Skip to content

Commit 905407d

Browse files
committed
fix(highlight): render link/image brackets uniformly (closing ] was uncoloured)
Only the opening [ and closing ) of a link/image are queryable; the closing ] and opening ( are fused into the anonymous ]( token in target, so colouring just [/) left the closing ] a different colour. Drop the bracket captures so all link/image bracket punctuation uses the default foreground. qmd.punctuation.bracket stays a reserved legend/theme entry.
1 parent 279a6f6 commit 905407d

4 files changed

Lines changed: 30 additions & 18 deletions

File tree

claude-notes/plans/2026-06-10-monaco-tree-sitter-highlighting.md

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -109,11 +109,21 @@ Braid epic: **bd-t4ezufyg**. Sub-strands: Phase 0 `bd-mawltv3x`, Phase 1
109109
to gain the same innermost-wins flatten as the native path, or browser and
110110
native render user-grammar code blocks differently — now true parity (bd-98k6
111111
fixed on the browser render path too).
112-
- **Not verified headlessly (flagged):** the Phase-8 *manual browser check*
113-
(open a `.qmd`, eyeball the three zones, code-cell↔preview colour parity, no
114-
flash/flicker, `.ts` colours unchanged) needs a running hub + browser. The
115-
Monarch base's runtime tokenization and the theme's visual colours are only
116-
validated by that check; everything mechanically testable is green.
112+
- **Manual browser check — PASSED (2026-06-16).** Confirmed in a real
113+
hub-client + local hub server session: `.qmd` editor shows the tree-sitter
114+
semantic highlighting, "definitely an improvement" over the old markdown
115+
mapping. (Gotcha hit en route: the **browser** was serving a cached old WASM
116+
— a hard refresh / cache clear after `npm run build:wasm` was needed, on top
117+
of `npm run dev:fresh`.) Minor visual **tweaks** noted by the user as
118+
follow-up (palette / specific scopes), not blockers.
119+
- **Tweak (2026-06-16): link/image brackets uniform.** The opening `[` was
120+
coloured grey (`punctuation.bracket`) but the closing `]` was not (it is
121+
fused into the anonymous `](` token inside `target`, unreachable by the
122+
query), so the brackets clashed. Dropped the `[`/`)` bracket captures from
123+
`highlights.scm`; all link/image bracket punctuation now renders in the
124+
uniform default foreground. (`qmd.punctuation.bracket` stays a reserved
125+
legend entry / theme rule for when the grammar can split `](`.) Requires a
126+
WASM rebuild + browser hard-refresh.
117127
- **Pre-existing, unrelated failure:** `@quarto/hub-mcp`'s `hub-mcp.test.ts`
118128
(19/22) fails in this sandbox — `live:` tests needing an automerge server +
119129
MCP child-process spawn. Untouched package; orthogonal to this work.

crates/quarto-lsp-core/src/snapshots/quarto_lsp_core__tokens__tests__structural_corpus.snap

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,17 +26,13 @@ expression: rendered
2626
9:55-57 qmd.punctuation.special
2727
9:57-68 qmd.markup.raw.inline
2828
9:68-69 qmd.punctuation.special
29-
11:2-3 qmd.punctuation.bracket
3029
11:3-7 qmd.markup.link.label
3130
11:9-28 qmd.markup.link.url
3231
11:29-36 qmd.markup.link.title
33-
11:36-37 qmd.punctuation.bracket
3432
11:45-47 qmd.punctuation.special.image
3533
11:47-52 qmd.markup.image.label
3634
11:54-62 qmd.markup.image.url
37-
11:62-63 qmd.punctuation.bracket
3835
11:63-81 qmd.attribute.specifier
39-
13:2-3 qmd.punctuation.bracket
4036
13:15-22 qmd.attribute.specifier
4137
13:28-51 qmd.markup.shortcode
4238
15:12-19 qmd.markup.math

crates/quarto-lsp-core/src/tokens.rs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -470,7 +470,10 @@ mod tests {
470470
let toks = tokens("[label](https://example.com)");
471471
assert!(has_type(&toks, "qmd.markup.link.label"), "got {toks:?}");
472472
assert!(has_type(&toks, "qmd.markup.link.url"), "got {toks:?}");
473-
assert!(has_type(&toks, "qmd.punctuation.bracket"), "got {toks:?}");
473+
// Bracket punctuation is intentionally uncoloured (uniform default):
474+
// the closing `]` is unreachable by the query, so colouring only `[`
475+
// looked mismatched. See highlights.scm.
476+
assert!(!has_type(&toks, "qmd.punctuation.bracket"), "got {toks:?}");
474477
}
475478

476479
#[test]
@@ -581,12 +584,13 @@ mod tests {
581584
// A 4-byte emoji before a link: the link label must start at the
582585
// correct UTF-16 column (emoji is 2 UTF-16 code units), not byte col.
583586
let toks = tokens("😀 [x](y)");
584-
// "😀 " is 2 (emoji, surrogate pair) + 1 (space) = 3 UTF-16 units, so
585-
// the `[` bracket sits at character 3.
587+
// "😀 [" is 2 (emoji surrogate pair) + 1 (space) + 1 (`[`) = 4 UTF-16
588+
// units, so the link label `x` sits at character 4 (byte offset would
589+
// be 6 — emoji is 4 bytes).
586590
assert!(
587591
toks.iter()
588-
.any(|t| type_name(t) == "qmd.punctuation.bracket" && t.character == 3),
589-
"expected a bracket at UTF-16 char 3, got {toks:?}"
592+
.any(|t| type_name(t) == "qmd.markup.link.label" && t.character == 4),
593+
"expected a link label at UTF-16 char 4, got {toks:?}"
590594
);
591595
}
592596

crates/tree-sitter-qmd/tree-sitter-markdown/queries/highlights.scm

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,19 +47,21 @@
4747
(code_span_delimiter) @punctuation.special
4848

4949
; --- Links (a pandoc_span is a link only when it has a `target` child) --------
50+
; Bracket punctuation is left uncoloured (default foreground): of `[ ] ( )`
51+
; only `[` and `)` are queryable — the `](` between label and url is one fused
52+
; anonymous token inside `target`, so `]` and `(` cannot be reached by the
53+
; query. Colouring only `[`/`)` made the closing `]` a different colour from
54+
; the opening `[`; uniform default avoids that mismatch (splitting `](` in the
55+
; grammar is out of scope).
5056
(pandoc_span (content) @markup.link.label (target))
5157
(pandoc_span (target (url) @markup.link.url))
5258
(pandoc_span (target (title) @markup.link.title))
53-
(pandoc_span "[" @punctuation.bracket)
5459

5560
; --- Images (reuse `target`; the `![` opener is one fused token) --------------
5661
(pandoc_image "![" @punctuation.special.image)
5762
(pandoc_image (content) @markup.image.label)
5863
(pandoc_image (target (url) @markup.image.url))
5964

60-
; The queryable closing bracket of a link/image target.
61-
(target ")" @punctuation.bracket)
62-
6365
; --- Attribute specifiers ({#id .cls key="v"}, and code-cell {r}) -------------
6466
(attribute_specifier) @attribute.specifier
6567

0 commit comments

Comments
 (0)