docs: LSP LaTeX coverage framing revision 2, on a branch at last
Revision 1 was untracked, on main, in a single checkout. By the handoff own rule --- work is portable only after it is committed and pushed --- it did not travel. Committing it here is the first fix. Three factual corrections, all from checking rather than reading. haskell-language-server IS installed on this machine, along with its wrapper. Revision 1 said it was not, and that claim was the entire basis of its Slice 1 / Slice 2 split. Only OCaml still lacks a server. The argument for leaving Haskell out survives, but on use evidence --- the .hs files are a rarely-edited Hakyll generator --- not on dependency cost. Slice 1 is smaller than framed. Revision 1 proposed filetype mappings for .tex/.latex/.sty/.cls "so highlighting and LSP agree on what a LaTeX file is". They already agree, by construction: the grammar carries exactly those extensions at src/syntax.rs:1111, grammar-extension detection sits AHEAD of the LSP filetype map in the precedence chain per the merged grammar framing at :166-171, and lsp.lua:267-270 calls the filetype map "mainly the LSP-only fallback". The real missing piece is one config entry. Q#LX3 deferral argument read a stale line. COHERENCE.md:124 and :867 both record multi-root LSP affinity as merged in #161; only :1669 still says "first slice in flight", contradicting the same document twice. The one item revision 1 said could justify deferring therefore dissolves. The COHERENCE.md inconsistency is real and is left for whoever next touches section 20 rather than smuggled in here. Q#LX2, which revision 1 called the question most likely to make the entry wrong in practice, is now answered rather than shrugged at. An upward marker walk through config.latex.root, which already accepts a resolver function. .git is deliberately excluded: a repository root is the wrong answer for LaTeX, since texlab wants the document root, and this is the one place where copying the other fourteen entries instinct would be actively wrong. The .texlabroot marker is marked UNVERIFIED and blocking. texlab 5.25.1 is installed and its version and CLI were checked directly, but the CLI exposes only run and inverse-search, so its LSP-level behaviour was not established. Confirm against a live session before implementing. Same discipline the gate-protocol-build lane applies to its own precondition: the thing the design rests on gets observed, not reasoned about. Also renumbered Q#HS1 to Q#LX4, because revision 1 Q#LX2 collided with a live question ID in the merged grammar framing for the same language. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016bqGA6s9tTUFzYpbeW3tai
This commit is contained in:
parent
7cf4653417
commit
7992054153
|
|
@ -265,10 +265,61 @@ also removed: this branch's "R8 NEEDS A LANE" investigation block, and
|
||||||
durable facts are in the retired registry row and the handoff §6
|
durable facts are in the retired registry row and the handoff §6
|
||||||
census.
|
census.
|
||||||
|
|
||||||
## `scripts/gate --protocol` build step — IMPLEMENTED at `49bc141`, RE-OPENED by review, witness CLOSED at `677fd25`. No PR yet
|
## LSP LaTeX coverage — BRANCHED, framing in review
|
||||||
|
|
||||||
**PR #229 OPEN** — https://github.com/levineuwirth/pmacs/pull/229,
|
**Written with the lane's first commit**, per the standing correction
|
||||||
opened at `93d557a`. **Held, not merged.** Its first CI run went red on
|
from #171 and #215.
|
||||||
|
|
||||||
|
**Branch `lsp-latex-coverage`**, base `githubsucks/main` @ `4bc55e8`
|
||||||
|
(the #225 merge). **`githubsucks/lsp-latex-coverage` is the
|
||||||
|
authoritative tip** — the ref, not a SHA. Recover with
|
||||||
|
`git fetch githubsucks && git checkout lsp-latex-coverage`.
|
||||||
|
|
||||||
|
- **Framing `docs/lsp-language-coverage-framing.md`, revision 2**, in
|
||||||
|
review. **Revision 1 was UNTRACKED on `main` in one checkout** and
|
||||||
|
therefore did not travel; committing it here is the fix.
|
||||||
|
- **Scope: one `pmacs.lsp.config.latex` entry plus its root resolver.**
|
||||||
|
`texlab` 5.25.1 is installed and unused; a `.tex` buffer highlights
|
||||||
|
correctly and offers no completion, diagnostics, or go-to-definition.
|
||||||
|
- **Revision 2 found Slice 1 is SMALLER than revision 1 framed.** The
|
||||||
|
proposed `.tex`/`.latex`/`.sty`/`.cls` filetype mappings are
|
||||||
|
redundant: the grammar already carries exactly those extensions
|
||||||
|
(`src/syntax.rs:1111`), grammar-extension detection sits **ahead** of
|
||||||
|
the LSP filetype map in the precedence chain
|
||||||
|
(`docs/latex-grammar-math-substrate-framing.md:166-171`), and
|
||||||
|
`lsp.lua:267-270` calls that map "mainly the LSP-only fallback". The
|
||||||
|
two systems cannot disagree, because the grammar's extension list is
|
||||||
|
what drives detection.
|
||||||
|
- **Two other corrections.** `haskell-language-server` **is** installed
|
||||||
|
on this machine — revision 1 said it was not, which was the whole
|
||||||
|
basis of its Slice 1 / Slice 2 split. And Q#LX3's deferral argument
|
||||||
|
read `COHERENCE.md:1669` ("first slice in flight") when `:124` and
|
||||||
|
`:867` both record multi-root affinity as **merged (#161)**; that
|
||||||
|
line contradicts the same document twice and wants a separate fix.
|
||||||
|
- **Q#LX2 (the LaTeX root) is answered, with a caveat that must be
|
||||||
|
discharged first.** An upward marker walk — `.texlabroot`,
|
||||||
|
`latexmkrc`/`.latexmkrc`, `Tectonic.toml`, then the file's own
|
||||||
|
directory — through `config.latex.root`, which already accepts a
|
||||||
|
resolver function (`lsp.lua:543`). **`.git` is deliberately excluded**:
|
||||||
|
a repo root is the wrong answer for LaTeX, and it is the one place
|
||||||
|
copying the other fourteen entries' instinct is actively wrong.
|
||||||
|
**Whether texlab honours `.texlabroot` is UNVERIFIED** — only its
|
||||||
|
version and CLI were checked, and the CLI exposes no such surface.
|
||||||
|
Confirm against a live session before implementing; if it is not a
|
||||||
|
real marker, the walk starts at `latexmkrc`.
|
||||||
|
- **Gates:** `scripts/gate --acceptance <the new suite>`. No
|
||||||
|
`--protocol` — a config entry, no wire.
|
||||||
|
|
||||||
|
## `scripts/gate --protocol` build step — **MERGED as #229** (`7cf4653`)
|
||||||
|
|
||||||
|
**MERGED as PR #229** — https://github.com/levineuwirth/pmacs/pull/229,
|
||||||
|
at `3b10f9d`, 14/14 CI green including both macOS legs. `main` is now
|
||||||
|
`7cf4653`. *(This lane still awaits Rule 4 retirement — its durable
|
||||||
|
facts belong in the handoff before the entry is removed. Corrected here
|
||||||
|
only because the previous text said "Held, not merged", which the merge
|
||||||
|
falsified; the retirement itself is not this lane's work.)*
|
||||||
|
|
||||||
|
**History, retained:** opened at `93d557a`. Its first CI run went red on
|
||||||
`Test (macos-latest / lua54)`; the rerun turned that selector green and
|
`Test (macos-latest / lua54)`; the rerun turned that selector green and
|
||||||
went red on a **different** one. Both are recorded as **U4** and **U5**
|
went red on a **different** one. Both are recorded as **U4** and **U5**
|
||||||
in `docs/ci-red-signatures.md`, as separate incidents per the matching
|
in `docs/ci-red-signatures.md`, as separate incidents per the matching
|
||||||
|
|
@ -466,6 +517,7 @@ authoritative tip** — the ref, not a SHA. Recover with
|
||||||
emission, an aborting runner, the build folded into `sweep-crdt`, and
|
emission, an aborting runner, the build folded into `sweep-crdt`, and
|
||||||
— added in the second round — a **rename of either** the build or the
|
— added in the second round — a **rename of either** the build or the
|
||||||
sweep step each fail the suite.
|
sweep step each fail the suite.
|
||||||
|
||||||| parent of 72bbb96 (docs: LSP LaTeX coverage framing revision 2, on a branch at last)
|
||||||
|
|
||||||
## QoL arc retirement — PR #224 OPEN (docs only)
|
## QoL arc retirement — PR #224 OPEN (docs only)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,238 @@
|
||||||
|
# LSP language coverage: LaTeX (and the Haskell/OCaml question)
|
||||||
|
|
||||||
|
**Status: framing pass, revision 2. Pre-implementation. Awaiting
|
||||||
|
approval.**
|
||||||
|
|
||||||
|
**Revision 2 corrects three facts revision 1 got wrong or stale, and
|
||||||
|
answers the question revision 1 named as most likely to make the entry
|
||||||
|
wrong in practice.** Haskell's server *is* installed; Slice 1 is
|
||||||
|
**smaller** than framed because the extension wiring already exists;
|
||||||
|
Q#LX3's deferral argument rests on a `COHERENCE.md` line the same
|
||||||
|
document contradicts twice; and Q#LX2 (the LaTeX root) now has a
|
||||||
|
proposal rather than a shrug.
|
||||||
|
|
||||||
|
**Revision 1 was untracked, on `main`, in one checkout.** Per the
|
||||||
|
handoff's own rule — work is portable only after it is committed and
|
||||||
|
pushed — it did not travel. That is fixed by this branch.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 0. What prompted this
|
||||||
|
|
||||||
|
An audit of the host machine against `builtin/runtime/lsp.lua`. pmacs
|
||||||
|
configures LSP for fourteen languages — verified exactly, by extracting
|
||||||
|
the `pmacs.lsp.config.*` keys:
|
||||||
|
|
||||||
|
bash c cmake cpp cuda dockerfile go json lua
|
||||||
|
python rust toml yaml zig
|
||||||
|
|
||||||
|
**Lean is NOT among the gaps, and revision 1's first draft wrongly said
|
||||||
|
it was.** Lean 4 has `builtin/runtime/lean.lua`, `lean_abbrev.lua` and
|
||||||
|
`lean_input.lua` (all three present), an `arborium-lean` grammar, and
|
||||||
|
comment/typed-edit integration — Arc 8 Stages 1–4b, merged. The error
|
||||||
|
came from grepping `lsp.lua` alone, which is the wrong place to look
|
||||||
|
for a language that earned its own module.
|
||||||
|
|
||||||
|
## 1. The gap, re-measured
|
||||||
|
|
||||||
|
| Language | tree-sitter | LSP config | Server on this machine |
|
||||||
|
|---|---|---|---|
|
||||||
|
| LaTeX | ✅ grammar + `builtin/queries/latex/highlights.scm` | ❌ | **`texlab` 5.25.1 — installed** |
|
||||||
|
| Haskell | ❌ | ❌ | **`haskell-language-server` — INSTALLED** |
|
||||||
|
| OCaml | ❌ | ❌ | `ocaml`/`opam`/`dune` yes, `ocaml-lsp-server` **absent** |
|
||||||
|
|
||||||
|
**Correction: revision 1 said Haskell's server was missing.** Both
|
||||||
|
`haskell-language-server` and `haskell-language-server-wrapper` are on
|
||||||
|
this machine. That collapses revision 1's Slice 1 / Slice 2 split,
|
||||||
|
which rested on "Slice 2 needs servers installed first" — only OCaml
|
||||||
|
does now.
|
||||||
|
|
||||||
|
LaTeX remains the sharp case: the grammar work landed, so a `.tex`
|
||||||
|
buffer highlights correctly **and** offers no completion, no
|
||||||
|
diagnostics, no go-to-definition, while `texlab` sits on disk unused.
|
||||||
|
|
||||||
|
## 2. Ground truth — Slice 1 is smaller than revision 1 claimed
|
||||||
|
|
||||||
|
Revision 1 proposed "one `pmacs.lsp.config.latex` entry, **plus**
|
||||||
|
filetype mappings for `.tex`/`.latex`/`.sty`/`.cls`, matching the
|
||||||
|
grammar's existing extension set so highlighting and LSP agree on what
|
||||||
|
a LaTeX file is."
|
||||||
|
|
||||||
|
**The filetype mappings are redundant, and the rationale describes a
|
||||||
|
problem that cannot occur.** Three facts, read rather than assumed:
|
||||||
|
|
||||||
|
- **The grammar already carries exactly those extensions.**
|
||||||
|
`src/syntax.rs:1110-1112` — `name: "latex"`,
|
||||||
|
`extensions: &["tex", "latex", "sty", "cls"]`.
|
||||||
|
- **Grammar-extension detection sits AHEAD of the LSP filetype map.**
|
||||||
|
The merged `docs/latex-grammar-math-substrate-framing.md:166-171`
|
||||||
|
states the chain — *modeline → grammar extension → LSP filetype map →
|
||||||
|
filename map → shebang* — and concludes that adding those extensions
|
||||||
|
"**wires the whole chain with no Lua edit**".
|
||||||
|
- **The filetype map is explicitly a fallback.** `lsp.lua:267-270`:
|
||||||
|
"Every language with an LSP config now also ships a grammar, so this
|
||||||
|
is mainly the **LSP-only fallback** that keeps a language id stable if
|
||||||
|
a grammar is ever dropped, plus the seam for user-added mappings."
|
||||||
|
|
||||||
|
So a `.tex` buffer **already** resolves to language `latex`. They
|
||||||
|
cannot disagree, because the grammar's extension list *is* what drives
|
||||||
|
detection.
|
||||||
|
|
||||||
|
**Slice 1 is therefore one thing: the `pmacs.lsp.config.latex` entry**
|
||||||
|
(plus its root resolver, §3). Filetype-map entries may still be added
|
||||||
|
as the documented drop-a-grammar fallback, but that is belt-and-braces
|
||||||
|
and should be labelled as such rather than sold as making two systems
|
||||||
|
agree.
|
||||||
|
|
||||||
|
## 3. Q#LX2 — the LaTeX project root **(answered in rev 2)**
|
||||||
|
|
||||||
|
Revision 1 called this "the question most likely to make the entry
|
||||||
|
wrong in practice" and left it open. It is the difference between
|
||||||
|
texlab serving a multi-file thesis and serving isolated files, so it is
|
||||||
|
the whole value of the lane for the stated use case.
|
||||||
|
|
||||||
|
**The mechanism exists.** `pmacs.lsp.config.<lang>.root` accepts a
|
||||||
|
string **or a resolver function**, resolved through `resolve_root_fn`
|
||||||
|
(`lsp.lua:543`) with per-resolver memoization, and on the *reuse* path
|
||||||
|
as well as the spawn path (`:535`). A configured root "MUST be a
|
||||||
|
canonical absolute path" (`:525`). So this is a config entry, not new
|
||||||
|
machinery.
|
||||||
|
|
||||||
|
*My vote: **an upward marker walk with an explicit precedence, falling
|
||||||
|
back to the file's own directory.*** In order:
|
||||||
|
|
||||||
|
1. **`.texlabroot`** — if texlab honours it (see the verification
|
||||||
|
caveat below), an explicit user-placed marker should win over
|
||||||
|
everything inferred.
|
||||||
|
2. **`latexmkrc` / `.latexmkrc`** — a build config is a strong,
|
||||||
|
deliberate signal of a document root.
|
||||||
|
3. **`Tectonic.toml`** — the same for tectonic projects.
|
||||||
|
4. **The file's own directory**, as the fallback.
|
||||||
|
|
||||||
|
**Deliberately NOT in the walk: `.git`.** A repository root is the
|
||||||
|
wrong answer for LaTeX — texlab wants the *document* root, and a thesis
|
||||||
|
inside a monorepo would otherwise get the monorepo. This is the one
|
||||||
|
place where copying the other fourteen entries' instinct would be
|
||||||
|
actively wrong.
|
||||||
|
|
||||||
|
**Deliberately NOT proposed: scanning for `\documentclass`.** That is
|
||||||
|
the semantically correct notion of a root document, and it is a
|
||||||
|
directory scan on every resolve, with its own caching and invalidation
|
||||||
|
questions. If the marker walk proves insufficient in use, that is the
|
||||||
|
next increment — with evidence.
|
||||||
|
|
||||||
|
**VERIFICATION CAVEAT, stated rather than buried.** `texlab 5.25.1` is
|
||||||
|
installed and its version and CLI surface were checked directly. Its
|
||||||
|
**LSP-level** behaviour — whether it honours `.texlabroot`, and how it
|
||||||
|
resolves multi-file projects from a root URI — was **not** verified
|
||||||
|
here; the CLI exposes only `run` / `inverse-search`, so this needs a
|
||||||
|
live session. **Marker 1 is provisional and must be confirmed against a
|
||||||
|
running texlab before implementation**, exactly as the sibling
|
||||||
|
`gate-protocol-build` lane requires its precondition to be observed
|
||||||
|
rather than reasoned about. If `.texlabroot` is not a real marker, it
|
||||||
|
drops and the walk starts at `latexmkrc`.
|
||||||
|
|
||||||
|
## 4. Open questions
|
||||||
|
|
||||||
|
### Q#LX1 — does `texlab` need `settings` or `init_options`?
|
||||||
|
|
||||||
|
It pulls configuration via `workspace/configuration` under a `texlab`
|
||||||
|
section, which pmacs answers (#13). An empty section takes defaults, as
|
||||||
|
the Go entry does for gopls.
|
||||||
|
|
||||||
|
*My vote: **ship nothing.*** Build-on-save and forward-search are the
|
||||||
|
two candidates and both are opinionated; forward-search additionally
|
||||||
|
needs a configured viewer, so a default would be wrong for most
|
||||||
|
machines. Users override through the same `init.lua` seam as the other
|
||||||
|
fourteen.
|
||||||
|
|
||||||
|
### Q#LX4 — do Haskell and OCaml belong in this lane at all? *(renumbered — see below)*
|
||||||
|
|
||||||
|
With HLS installed, Haskell is now the same shape as LaTeX: one entry,
|
||||||
|
no new dependency. **But the argument against it never rested on the
|
||||||
|
dependency.** The `.hs` files here are `levineuwirth.org`'s Hakyll
|
||||||
|
generator, edited rarely; HLS is version-coupled to GHC and is a large
|
||||||
|
resident process for a language touched a few times a year.
|
||||||
|
|
||||||
|
*My vote: **LaTeX only in this lane.*** Add Haskell when there is use
|
||||||
|
evidence, which is a one-line change at that point. OCaml needs
|
||||||
|
`ocaml-lsp-server` via opam (not packaged for Arch) and is not close.
|
||||||
|
|
||||||
|
**Renumbered from Q#HS1 deliberately.** The merged
|
||||||
|
`docs/latex-grammar-math-substrate-framing.md` already uses **Q#LX2**
|
||||||
|
for a different question — its grammar vendoring source (`:83`) — so
|
||||||
|
revision 1's Q#LX2 collided with a live ID in the same language area.
|
||||||
|
This document's LaTeX questions are Q#LX1 and the root question in §3;
|
||||||
|
the language-scope question takes Q#LX4 to avoid a second collision.
|
||||||
|
|
||||||
|
### Q#LX3 — does this touch multi-root LSP affinity? — **RESOLVED, and revision 1 read a stale line**
|
||||||
|
|
||||||
|
Revision 1 called this "the one item that could argue for deferring
|
||||||
|
Slice 1", on the basis that multi-root affinity was in flight.
|
||||||
|
|
||||||
|
**It merged as PR #161.** `COHERENCE.md:124` lists it among landed
|
||||||
|
coherence work, and `:867` says "First slice landed (PR #161)". Only
|
||||||
|
`:1669` still says "first slice in flight" — and that line contradicts
|
||||||
|
the other two **within the same document**.
|
||||||
|
|
||||||
|
So the deferral argument dissolves: a LaTeX entry keyed like the
|
||||||
|
existing servers rides the convention that already landed. **The
|
||||||
|
`COHERENCE.md:1669` inconsistency is real and should be fixed**, but by
|
||||||
|
whoever next touches §20 — not smuggled into this lane.
|
||||||
|
|
||||||
|
## 5. Coherence impact (§20)
|
||||||
|
|
||||||
|
- **Journey steps touched: none.** This adds a row to an existing
|
||||||
|
registry; no new surface, keybinding, or panel.
|
||||||
|
- **Interaction islands: none added.**
|
||||||
|
- **Config registry adoption: yes, and only that.** One entry in the
|
||||||
|
existing `pmacs.lsp.config` table, overridable from `init.lua` by the
|
||||||
|
same mechanism as the fourteen already there.
|
||||||
|
- **Background-work attribution (§9): unchanged, and NOT improved.**
|
||||||
|
texlab spawns under the existing LSP supervision path with no new
|
||||||
|
lifecycle — but it is another process that appears in `*lsp*` and
|
||||||
|
whose requests appear in `*workers*` with nothing joining them. The
|
||||||
|
worker-identity lane owns that; this lane neither helps nor worsens
|
||||||
|
it.
|
||||||
|
- **§20 classification: WIRING, not model.** It surfaces machinery that
|
||||||
|
already exists rather than adding a runtime entity — and §2 shows it
|
||||||
|
is *more* purely wiring than revision 1 thought.
|
||||||
|
|
||||||
|
## 6. Verification
|
||||||
|
|
||||||
|
- **A `.tex` buffer attaches texlab**, witnessed end to end rather than
|
||||||
|
by asserting the config table's contents.
|
||||||
|
- **Detection is unchanged**: `.tex`/`.latex`/`.sty`/`.cls` still
|
||||||
|
resolve to `latex` via the grammar path (§2), asserted so that a
|
||||||
|
later "helpful" filetype-map addition cannot be mistaken for the
|
||||||
|
thing that made it work.
|
||||||
|
- **The root resolver returns the marker directory**, witnessed on a
|
||||||
|
fixture with a `latexmkrc` above a `chapters/` subdirectory — the
|
||||||
|
thesis shape, which is the case a file-directory root gets wrong.
|
||||||
|
- **It falls back to the file's own directory** with no marker present.
|
||||||
|
- **`.git` does NOT become the root** (§3) — a fixture with a
|
||||||
|
repository above a document directory, asserting the document
|
||||||
|
directory wins. This is the case where copying the other entries'
|
||||||
|
instinct is wrong, so it is pinned.
|
||||||
|
- **A missing `texlab` surfaces guidance**, through the existing
|
||||||
|
spawn-failure path (#204) — asserted, not assumed, since that path is
|
||||||
|
what makes the failure honest.
|
||||||
|
- **Fixtures bound project detection** with
|
||||||
|
`pmacs.project.set_search_boundary`. R8 was a fixture letting
|
||||||
|
detection escape into the developer's environment; a LaTeX root
|
||||||
|
fixture is exactly that hazard's shape.
|
||||||
|
|
||||||
|
**What this will NOT prove:** that texlab resolves multi-file `\input`
|
||||||
|
graphs correctly (that is texlab's job, not pmacs's), or that Haskell
|
||||||
|
and OCaml work (Q#LX4).
|
||||||
|
|
||||||
|
## 7. Not in scope
|
||||||
|
|
||||||
|
New tree-sitter grammars — Haskell and OCaml would have LSP without
|
||||||
|
highlighting, a real asymmetry that must be stated in the PR rather
|
||||||
|
than discovered by a user. Any change to Lean, which needs none.
|
||||||
|
Math/typesetting work (`#172` owns it). Any change to the LSP
|
||||||
|
spawn-failure surface (#204). Scanning for `\documentclass` to find a
|
||||||
|
root document (§3). Fixing `COHERENCE.md:1669`'s stale multi-root line
|
||||||
|
(Q#LX3) — real, but another lane's edit. Haskell and OCaml entries
|
||||||
|
(Q#LX4).
|
||||||
Loading…
Reference in New Issue