docs+test(web): name and pin the @attribute retro-paint (review round 3)
Review found that adding ("attribute", fg(3)) for HTML/CSS also colours the
@attribute capture three already-bundled grammars emit — rust (attribute_item),
lua (<const>), yaml (directives) — which were previously unpainted. Verified on
a Rust buffer: #[derive(Debug)] now paints uniformly yellow (fg 3), an
improvement over unpainted and the distinct-attribute convention most editors
follow.
Name this retro-paint as intended in the framing (Q#WEB4, rev 4) and pin it with
rust_attribute_repaints_via_shared_attribute_capture so it is a chosen effect,
not incidental. @tag is unaffected (HTML/CSS only).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
394d39942c
commit
515c76f5ab
|
|
@ -1,11 +1,11 @@
|
||||||
# Web grammars (HTML + CSS) + HTML injections — framing
|
# Web grammars (HTML + CSS) + HTML injections — framing
|
||||||
|
|
||||||
**Revision 3 — pre-implementation. Ground truth: canonical `main` @
|
**Revision 4 — implemented on branch `web-grammars` (PR #146). Ground truth:
|
||||||
`4daa1b8` (after LaTeX #144 and inline-math-docs #145), 2026-07-23. Status:
|
canonical `main` @ `4daa1b8` (after LaTeX #144 and inline-math-docs #145),
|
||||||
framing only; no implementation.** Rev 2 settled the capture set, injection
|
2026-07-23.** Rev 2 settled the capture set, injection scope, and LSP claim
|
||||||
scope, and LSP claim (round 1); rev 3 corrects the `#match?` predicate analysis
|
(round 1); rev 3 corrected the `#match?` predicate analysis (round 2); rev 4
|
||||||
(tree-sitter evaluates it natively) and refreshes the folding footprint to the
|
names the intended `@attribute` retro-paint on the already-bundled rust/lua/yaml
|
||||||
current branch (round 2). See §0.1.
|
grammars — verified on a Rust buffer and pinned by a test (round 3). See §0.1.
|
||||||
|
|
||||||
## 0.1 Revision history
|
## 0.1 Revision history
|
||||||
|
|
||||||
|
|
@ -44,6 +44,17 @@ current branch (round 2). See §0.1.
|
||||||
`overlay.rs`/`daemon.rs`/`syntax.rs`. §0 now lists the real set; the
|
`overlay.rs`/`daemon.rs`/`syntax.rs`. §0 now lists the real set; the
|
||||||
zero-overlap conclusion is unchanged (stronger, if anything).
|
zero-overlap conclusion is unchanged (stronger, if anything).
|
||||||
|
|
||||||
|
### Round 3 (rev 3 → rev 4)
|
||||||
|
|
||||||
|
- **R3-1 (medium).** Q#WEB4 verified which captures pmacs *lacks* but not the
|
||||||
|
reverse: which already-bundled grammars *use* `@attribute`. Three do — rust
|
||||||
|
(`attribute_item`), lua (`<const>`), yaml (directives) — so the new
|
||||||
|
`("attribute", fg(3))` entry retro-paints their previously-unpainted spans
|
||||||
|
yellow. Named in Q#WEB4 as intended (verified on a Rust buffer: uniform
|
||||||
|
yellow, an improvement over unpainted), and pinned by
|
||||||
|
`rust_attribute_repaints_via_shared_attribute_capture`. `tag` is unaffected
|
||||||
|
(HTML/CSS only).
|
||||||
|
|
||||||
Add tree-sitter **HTML** and **CSS** grammars so `.html`/`.htm` and `.css`
|
Add tree-sitter **HTML** and **CSS** grammars so `.html`/`.htm` and `.css`
|
||||||
buffers get lexical highlighting, and — the north-star payoff — light up
|
buffers get lexical highlighting, and — the north-star payoff — light up
|
||||||
HTML's embedded-language **injections**: `<script>` → JavaScript (already
|
HTML's embedded-language **injections**: `<script>` → JavaScript (already
|
||||||
|
|
@ -197,6 +208,19 @@ There is **no** `tag.delimiter` (rev-1 speculation, removed); HTML's `<`/`>`/
|
||||||
- **general** — `tag`/`attribute` are standard tree-sitter web captures, so it
|
- **general** — `tag`/`attribute` are standard tree-sitter web captures, so it
|
||||||
also serves future html-ish grammars (vue/svelte/astro).
|
also serves future html-ish grammars (vue/svelte/astro).
|
||||||
|
|
||||||
|
**Retro-paint on already-bundled languages (intended, added rev 4).** The
|
||||||
|
capture table is global, so adding `attribute` also colours the `@attribute`
|
||||||
|
capture that three bundled grammars already emit but which was previously
|
||||||
|
unrecognized (and so unpainted): **rust** (`attribute_item`/`inner_attribute_item`
|
||||||
|
— every `#[derive(…)]` / `#![…]`), **lua** (the `<const>`/`<close>` variable
|
||||||
|
attribute), and **yaml** (`%YAML`/`%TAG` directives). On merge these begin
|
||||||
|
painting `attribute` yellow (`fg 3`). Verified on a Rust buffer: `#[derive(Debug)]`
|
||||||
|
paints uniformly yellow (the `attribute_item` span carries no narrower overriding
|
||||||
|
captures) — a distinct-attribute convention most editors follow, and an
|
||||||
|
improvement over unpainted. This is **chosen, not incidental**: it is pinned by
|
||||||
|
`rust_attribute_repaints_via_shared_attribute_capture` (`src/highlight.rs`).
|
||||||
|
`tag` is clean — only HTML/CSS use it, so it has no retro-effect.
|
||||||
|
|
||||||
**On CSS custom properties (corrected in rev 3):** pmacs passes the buffer text
|
**On CSS custom properties (corrected in rev 3):** pmacs passes the buffer text
|
||||||
to `QueryCursor::captures` (`src/syntax.rs:1701`), so tree-sitter evaluates the
|
to `QueryCursor::captures` (`src/syntax.rs:1701`), so tree-sitter evaluates the
|
||||||
standard `#match?`/`#eq?`/`#any-of?` predicates natively — pmacs special-cases
|
standard `#match?`/`#eq?`/`#any-of?` predicates natively — pmacs special-cases
|
||||||
|
|
|
||||||
|
|
@ -1416,6 +1416,61 @@ mod tests {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn rust_attribute_repaints_via_shared_attribute_capture() {
|
||||||
|
// Intended side effect, named in the framing (Q#WEB4): the
|
||||||
|
// `("attribute", fg(3))` entry added for HTML/CSS also colours the
|
||||||
|
// `@attribute` capture that tree-sitter-rust (attribute_item), -lua
|
||||||
|
// (`<const>`), and -yaml (directives) already emit. A Rust
|
||||||
|
// `#[derive(Debug)]` — previously unpainted, since `@attribute` was
|
||||||
|
// unrecognized — now paints the attribute style throughout. Pinned so
|
||||||
|
// the retro-paint on this repo's primary language is a chosen effect,
|
||||||
|
// not an incidental one.
|
||||||
|
use crate::buffer::{Buffer, BufferId, EditOp};
|
||||||
|
use crate::cell::{Cell, CellSize};
|
||||||
|
use crate::syntax::{ParseView, SyntaxRegistry};
|
||||||
|
|
||||||
|
let reg = SyntaxRegistry::new();
|
||||||
|
let language = reg.language("rust").expect("rust grammar");
|
||||||
|
let src = b"#[derive(Debug)]\nstruct S;\n";
|
||||||
|
let mut buf = Buffer::new(BufferId::next(), "a.rs");
|
||||||
|
buf.apply_edit(EditOp::Insert { pos: 0, bytes: src })
|
||||||
|
.unwrap();
|
||||||
|
let view = ParseView::new(&buf, language, "rust".to_owned());
|
||||||
|
let handle = view.handle();
|
||||||
|
let _vid = buf.attach_view(Box::new(view));
|
||||||
|
let mut req = handle.make_request();
|
||||||
|
req.injection_aliases = reg.injection_alias_snapshot();
|
||||||
|
let bundle = crate::syntax::run_parse(req).expect("rust parse");
|
||||||
|
handle.install(reg.resolve_layer_queries(&bundle));
|
||||||
|
|
||||||
|
let mut hv = SyntaxHighlightView::new(handle, reg.theme());
|
||||||
|
let (rows, cols) = (1usize, 20usize);
|
||||||
|
let mut backing: Vec<Cell> = vec![Cell::default(); rows * cols];
|
||||||
|
let mut grid = CellGrid {
|
||||||
|
cells: &mut backing,
|
||||||
|
stride: cols as u32,
|
||||||
|
size: CellSize::new(rows as u32, cols as u32),
|
||||||
|
};
|
||||||
|
let viewport = Viewport {
|
||||||
|
buffer_start: 0,
|
||||||
|
buffer_end: u64::MAX,
|
||||||
|
cell_origin: CellCoord::new(0, 0),
|
||||||
|
cell_size: CellSize::new(rows as u32, cols as u32),
|
||||||
|
gutter_w: 0,
|
||||||
|
};
|
||||||
|
let registry = buf;
|
||||||
|
hv.render(®istry, viewport, &mut grid);
|
||||||
|
|
||||||
|
// `derive` (col 2) sits inside the `attribute_item` and paints the
|
||||||
|
// shared @attribute style (fg 3) — the intended retro-paint.
|
||||||
|
assert_eq!(
|
||||||
|
grid.get(CellCoord::new(0, 2)).style.fg,
|
||||||
|
pmacs_protocol::cell::Color::Indexed(3),
|
||||||
|
"a Rust #[derive] attribute paints the shared @attribute style (fg 3)"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn web_grid_paints_html_tag_and_attribute() {
|
fn web_grid_paints_html_tag_and_attribute() {
|
||||||
// Q#WEB4 acceptance: the two capture entries this lane adds (`tag`,
|
// Q#WEB4 acceptance: the two capture entries this lane adds (`tag`,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue