Add lint diagnostics API to CodeMirror#5985
Draft
Jepson2k wants to merge 2 commits intozauberzeug:mainfrom
Draft
Add lint diagnostics API to CodeMirror#5985Jepson2k wants to merge 2 commits intozauberzeug:mainfrom
Jepson2k wants to merge 2 commits intozauberzeug:mainfrom
Conversation
`set_diagnostics(list[Diagnostic])` and `clear_diagnostics()` render inline error/warning marks with hover tooltips on user-supplied lines, backed by CodeMirror's built-in lint system. Each `Diagnostic` is a small TypedDict with required `line` (1-indexed) and `message`, plus optional `severity` (`'error'` | `'warning'` | `'info'` | `'hint'`, default `'error'`) and `source` (label shown next to the message). The editor installs `CM.linter(() => [])` so that `setDiagnostics()` works and inline error marks render. **Important:** we deliberately do NOT use `CM.lintGutter()` — it pulls in `lintGutterTooltip`, a StateField that registers itself via `showTooltip.from(field)` and returns null on most transactions. That null provider sits in the `showTooltip` facet and silently suppresses the autocomplete popup outside of paren contexts. `CM.linter()`'s only tooltip is a `hoverTooltip` that fires on mouseover, not on every keystroke. Adds `@codemirror/lint` to the dist bundle (already a transitive dependency of `codemirror`, just needs to be re-exported from `src/index.mjs` so it ends up in `dist/`). Bundle rebuilt. Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
- Diagnostic TypedDict: make `line`/`message` required and use `NotRequired` for `severity`/`source`, matching the docstring. - `set_diagnostics` docstring: drop the inaccurate gutter-underline claim; we deliberately don't install `lintGutter()`. - JS: drop the dead empty-string fallback for `message` (now required), and `console.warn` + skip non-integer or out-of-range line numbers instead of silently clamping them onto the wrong line. - Test: drop the slack `screen.wait(0.3)`; assert that severity-suffixed classes (`.cm-lintRange-error`, `.cm-lintRange-info`) appear; add a case exercising the default-`error` severity branch. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation
Embedding
ui.codemirroras an in-app code editor often needs to surface programmatically computed diagnostics — type-check results, lint output, runtime errors mapped back to source — onto specific lines, with hover tooltips so the user can read the message without leaving the editor. CodeMirror 6's@codemirror/lintpackage provides exactly this, but it isn't bundled in the current dist and there's no Python API for it. This PR adds both.This is one of several small slices being carved out of #5965 per the splitting discussion on that thread.
Implementation
Python (
nicegui/elements/codemirror/codemirror.py):DiagnosticTypedDict(total=False)with requiredline(1-indexed) andmessage, optionalseverity('error'|'warning'|'info'|'hint', default'error') andsource(label shown next to the message).set_diagnostics(list[Diagnostic])andclear_diagnostics()methods. Both run a JSsetDiagnosticsmethod viarun_method.JavaScript (
nicegui/elements/codemirror/codemirror.js):setDiagnosticsmethod maps eachDiagnosticto a CM6 diagnostic spanning the affected line, then dispatchesCM.setDiagnostics(state, ...).CM.linter(() => []). The empty source disables auto-linting; thelinter()extension just installslintStatesosetDiagnostics()works and inline error marks render. We do NOT useCM.lintGutter(): it pulls inlintGutterTooltip, aStateFieldthat registers itself viashowTooltip.from(field)and returns null on most transactions. That null provider sits in theshowTooltipfacet and silently suppresses the autocomplete popup outside of paren contexts.CM.linter()'s only tooltip is ahoverTooltipthat fires on mouseover, not on every keystroke.Bundle (
nicegui/elements/codemirror/src/index.mjs,nicegui/elements/codemirror/dist/):@codemirror/lintfromsrc/index.mjssolinter,setDiagnostics, andlintStateend up in the dist bundle.@codemirror/lintwas already a transitive dep of thecodemirrormeta-package, sopackage.jsondoesn't change.npm run clean && npm run build.Tests (
tests/test_codemirror.py):test_set_and_clear_diagnosticscallsset_diagnosticswith two entries (different severities, different lines) and asserts two.cm-lintRangeelements appear in the DOM, then callsclear_diagnosticsand asserts they're gone.Documentation (
website/documentation/content/codemirror_documentation.py):Progress