diff options
Diffstat (limited to 'docs/lsp.md')
| -rw-r--r-- | docs/lsp.md | 65 |
1 files changed, 44 insertions, 21 deletions
diff --git a/docs/lsp.md b/docs/lsp.md index 987e901c..2a4c8784 100644 --- a/docs/lsp.md +++ b/docs/lsp.md @@ -77,29 +77,49 @@ Verified against `helix-term/src/keymap/default.rs`, not from memory. | `gy` | type definition | | | `gi` | implementation | | | `gr` | references | | -| `SPC k` | hover | opens `+Hover` | -| `SPC r` | rename | tag input, like Find/Grep | -| `SPC a` | code action | | -| `SPC h` | select references | | -| `SPC s` / `SPC S` | document / workspace symbols | `S` takes a query | -| `SPC d` / `SPC D` | document / workspace diagnostics | | +| `SPC l k` | hover | opens `+Hover` | +| `SPC l r` | rename | tag input, like Find/Grep | +| `SPC l a` | code action | | +| `SPC l h` | select references | | +| `SPC l s` / `SPC l S` | document / workspace symbols | `S` takes a query | +| `SPC l d` / `SPC l D` | document / workspace diagnostics | | | `]d` / `[d` | next / prev diagnostic | steps the list, asks for one if absent | | `]D` / `[D` | last / first diagnostic | | | `=` | format | | +| `Ctrl`+left-click | definition | the mouse spelling of `gd` | -`g` and `[`/`]` had **no conflicts** — `gd/gD/gy/gi/gr` and `]d/[d` were all -free. The `SPC` letters were not, so pardes's own builtins moved out of helix's -way rather than the reverse: +Ctrl-click rides the ordinary left-click drag rather than firing on the press: +a click does not place the modal cursor until RELEASE, so a query asked at +press time would answer about wherever the cursor previously sat. A ctrl-DRAG +still selects, and still asks about where it started. -| builtin | was | now | why | -|---|---|---|---| -| Kill | `SPC k` | `SPC q` | `k` is hover; `q` is quit everywhere else | -| Del | `SPC d` | `SPC w c` | `d` is diagnostics; closing a pane IS a window op, and `c` is helix's own spelling for close in its window mode | -| Dump | `SPC s d` | `SPC f d` | `s` is symbols; writing a session file is a file operation | -| Restore | `SPC s r` | `SPC f r` | same | -| Tutor | `SPC h t` | `SPC T` | frees `h` for select-references | +**The gotos are helix's exactly; the leader commands are helix's letters under +an `l` prefix.** `g` and `[`/`]` had no conflicts — `gd/gD/gy/gi/gr` and +`]d/[d` were all free, so they stay where helix puts them. The bare `<space>` +letters were NOT free, and an earlier pass took them anyway, displacing `SPC d` +(Del), `SPC k` (Kill), `SPC s?` (Dump/Restore) and `SPC h t` (Tutor). That is +the wrong trade: those are pardes's most-pressed keys and predate the language +work, whereas an LSP command is something you reach for deliberately and can +afford one keystroke more. So every one of them keeps helix's own letter and +gains the prefix — `<space>k` becomes `SPC l k`, `<space>d` becomes `SPC l d` +— and nothing pardes had moved at all. -A three-exception muscle-memory map is not a map. That is the whole argument. +Two more live in the same group because they belong to it, not to helix: + +| keys | builtin | what it shows | +|---|---|---| +| `SPC l i` | `Lspinfo` | which ZLS, which stdlib (and whether it opens), what the backend answers and refuses, plus the last 24 queries with timings, row counts and **the errors `query` swallowed** | +| `SPC l w` | `Lspwhy` | why the definition query at the cursor answers what it does | + +These exist because of the seam's own contract: a backend never fails loudly, +which is right for an editor — a thrown analyser must not take the process with +it — but it makes a broken backend and a correct one that found nothing look +identical. `Lspwhy` narrates the REAL resolution path (the position context is +the analyser's own answer, threaded out through a trace) rather than +re-deriving it beside the code, because a debug view that reimplements the +logic is one that can disagree with it. `Lspinfo` answers from ANY pane, +including one with no file, since it is about the backend rather than a +document — which matters precisely when the pane you are in is the problem. `K` is **not** hover — in helix it is `keep_selections`. It was checked; do not "fix" it. @@ -110,16 +130,19 @@ A three-exception muscle-memory map is not a map. That is the whole argument. nothing else: ```zig -pub fn query(gpa, arena, req: Req, out: *std.ArrayList(u8)) void +pub fn query(gpa, arena, req: Req, out: *std.Io.Writer) void pub const supports: std.EnumSet(Kind) pub const backend_name = "..." ``` `query` runs on a worker thread with no access to the core — everything it may read is in `req` (`path`, `source` (NUL-terminated), `offset`, `arg`, `root`). -`arena` is freed wholesale on return; `gpa` owns only what goes into `out`. -Use `lsp.row()` to emit a location and `lsp.lineCol()` to convert an offset, -so every backend's rows are byte-identical in shape. +`out` is a plain `std.Io.Writer`: the shell owns the buffer behind it (an +`Io.Writer.Allocating`), so a backend never allocates the result, never frees +it, and cannot get the allocator wrong. `arena` is freed wholesale on return; +`gpa` is for a backend's own scratch. Use `lsp.row()` to emit a location and +`lsp.lineCol()` to convert an offset, so every backend's rows are +byte-identical in shape. ## How the implementations are judged |
