summaryrefslogtreecommitdiff
path: root/docs/helix-keys.md
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-08-12 13:32:43 -0300
committerGabriel Schneider <[email protected]>2026-08-12 16:07:33 -0300
commitbc89f57cb576e23a58572ec35f96db068367f1b4 (patch)
tree06f1ea2b7e95f229c10b316214ae904b9d43e343 /docs/helix-keys.md
parentb424164922842796619cb6894ec46d729a8a6826 (diff)
downloadpardes-bc89f57cb576e23a58572ec35f96db068367f1b4.tar.gz
pardes-bc89f57cb576e23a58572ec35f96db068367f1b4.zip
docs: the tutor taught three keystrokes wrong, and the rest had drifted
The documentation had gone stale in the ordinary way -- claims that were true when they were written and that nothing since had been obliged to re-read. Some of them were load-bearing. THE TUTOR. It still said there is no multi-cursor, that NextColor cycles three themes, and that its practice blocks "are also run as unit tests (generated from this file by tutor_gen)" -- a tool that appears nowhere in the tree, and nothing anywhere parses a `# keys:` block. Left alone, that claim is what makes the next wrong block survive. Three of those blocks WERE wrong, and all three for one reason: since the helix motion model landed, w/e/f/t SELECT the range they cross, so `i` after one inserts at the SELECTION'S START. `w i Z esc` on "foo bar" gives "Zfoo bar", not the "foo Zbar" the file promised. They were written against a vim reading of the same keys. Every block in the file has now been run through `zig build hxdiff` against the real core and matches byte for byte, and the trap itself is written down in 3.3 rather than left to be rediscovered. The tutor gains a PART 4 for everything added since it was written -- PDF panes, the in-process ZLS backend, themes and fonts, the startup file -- and PART 3 gains counts (and which keys ignore one), f/F/t/T, the whole g table (bare `G` is a no-op; `ge` is the START of the last line), multiple cursors and the s/S regex pair, `m`, `]`/`[`, `|`, insert mode, and all fifty leader paths. THE REST. design.typ's line table claimed 7,626 lines against a real 38,048, and its rows did not sum to its own total; its Event/Effect boundary contract -- the part a shell author writes against -- named four variants that do not exist and omitted fourteen that do. lsp.md's probe count. config.md's theme-name rules, which as written could not reach a zed theme at all. helix-keys.md's Skipped section, holding five families that have since landed. macos.md's menu bar, undocumented, along with sixteen other claims. web.md on what the browser build can actually do. SOURCE COMMENTS that had rotted alongside them: `tag_normal` is a space, not the `•` its own comment describes; Wrap is ON by default, not off; a FontSel row is SELECTED by n and RUN by Tab, not run by n; the SPC paths in lsp.zig lost their `l` group prefix when the language group moved; and the differential suites are 481 and 561 cases, not 360 and 440. TWO THINGS FOUND BY DOCUMENTING THEM, both left standing and written down rather than papered over. Typing `[^\n]` at an s/S prompt panics: the live preview compiles every prefix, and `[^\` indexes an empty slice in mvzr's parseCharSet. Both the tutor and a waiver recommended that pattern as the workaround for `.` matching a newline; they now say what it costs and what would make it sayable. And `Exec` is a builtin, so an `Exec` line in the startup config types that command into a shell before the first frame -- the tutor said nothing in that file is ever sent to one. Nine adversarial reviews over two rounds, each with the hxdiff harness to execute what it doubted. The second round exists because the first round's fixes needed checking too, and it caught three regressions of my own -- one of them a probe count I had "corrected" away from the truth. Verified: unit-test, snap 87/87, hxdiff 481/0, hxparity 561/0, mupdf-check. docs/design.pdf regenerated. The tutor's first seventeen lines are byte- identical, which is what tutor.golden pins.
Diffstat (limited to 'docs/helix-keys.md')
-rw-r--r--docs/helix-keys.md21
1 files changed, 13 insertions, 8 deletions
diff --git a/docs/helix-keys.md b/docs/helix-keys.md
index 214a1280..eafe9a9c 100644
--- a/docs/helix-keys.md
+++ b/docs/helix-keys.md
@@ -57,8 +57,8 @@ Parity column (phase 5): **helix-verified** = matched field-by-field
binding) — cannot mismatch a golden; **waived** = corpus-covered divergence
with a reason in `test/hxcases/waivers.jsonl`; **out of corpus** = helix's
own key and meaning, but the work leaves the core as an EFFECT the headless
-differential has no shell to perform — the clipboard commands, and nothing
-else.
+differential has no shell to perform — the clipboard commands, the
+language-backend queries, and the shell pipe.
| Key | Behavior (pardes today) | Notes / quirks vs helix | Parity |
| --- | --- | --- | --- |
@@ -66,7 +66,7 @@ else.
| `w` `b` `e` | select to next word start / prev word start / next word end | full helix model incl. landing conventions (block cursor one before the next word after `w`) and newline/punct/EOF edges | helix-verified |
| `W` `B` `E` | long-word (WORD) variants | same | helix-verified |
| `Home` / `End` | line start / line end | matches `goto_line_start` / `goto_line_end` | helix-verified |
-| `0` / `$` / `^` | line start / line end / first non-ws | pardes extras — helix leaves these unbound (spells them `gh`/`gl`/`gs`); `0` is a count digit while a count is pending | pardes-specific |
+| `0` / `$` / `^` | line start / line end / first non-ws | `0` and `^` are pardes extras — helix leaves those two unbound (it spells them `gh`/`gs`). `$` is NOT unbound in helix: it is `shell_keep_pipe` (`keymap/default.rs`), and taking it for line-end is a deliberate divergence — see the `$` row in C. `0` is a count digit while a count is pending | pardes-specific (`$`: deliberate) |
| `G` | bare `G` is a **no-op**; `<n>G` = goto line n | vim-ism removed (phase 5): helix `goto_line` only acts with a count; `ge` is goto-last-line | helix-verified |
| `gg` / `<n>gg` | goto first line / line n | | helix-verified |
| `ge` | goto last content line | matches `goto_last_line` (ignores the trailing empty line) | helix-verified |
@@ -104,6 +104,11 @@ else.
| insert: `Enter` | newline; keeps the current full indent levels and adds one 4-space logical tab when the text before the cursor ends in `(`, `[`, `{`, or `)` (including `})`) | plain lines match `insert_newline`; delimiter heuristic is pardes-specific | helix-verified (plain) / pardes-specific (delimiter) |
| insert: `Backspace` (+ `Shift-Backspace`) | delete prev char, joins lines at col 0 | matches `delete_char_backward`; `Ctrl-h` alias in B | helix-verified |
| insert: `Up` `Down` `Left` `Right` | move cursor | matches helix's "not recommended" insert arrows | helix-verified |
+| `gd` `gD` `gy` `gi` `gr` | LSP definition / declaration / type-definition / implementation / references. ONE answer jumps straight there; several fill `+Search`, where n/N walk and Enter opens | in-process ZLS (`src/lsp/lsp_zls.zig`), `.zig` only — on a file the backend does not speak these do nothing at all, with no error row. Ctrl+left-click is the mouse spelling of `gd` | out of corpus |
+| `]d` `[d` / `]D` `[D` | step the diagnostics list / go to its last or first; if no list is up, asking the backend for one is part of the press | | out of corpus |
+| `=` | `format_selections` — writes a `- old` / `+ new` diff into `+Lsp` | deliberate divergence: the seam returns ROWS, not edits, so this SHOWS the formatting instead of applying it. Not in the corpus, so there is no waiver to name — the query leaves the core as an effect the headless harness has no shell to perform | out of corpus |
+| `Ctrl-o` / `Ctrl-i` | jumplist back / forward — the `Back` / `Forward` builtins, also on `SPC j o` / `SPC j i`, with `SPC j l` rendering the stack as a buffer | helix binds both keys (`jump_backward` / `jump_forward`) but to a POSITION jumplist; pardes' stack is over panes and focus, so the keys agree and the semantics do not. `Ctrl-i` and Tab are the same byte under the legacy encoding; there Tab keeps meaning execute, and the pair only separates where the host speaks the kitty keyboard protocol | pardes-specific |
+| `\|` | pipe every selection through `/bin/sh -c`: its bytes in on stdin, its stdout replacing them, one undo across all cursors | helix's own key and meaning; the command is typed into the pane's tag after a bare `\|` marker rather than into a popup | out of corpus |
## B. To implement
@@ -275,14 +280,14 @@ text.
| `Ctrl-j` | insert newline (Enter alias) | | helix-verified (phase 5) |
| `Home` / `End` | line start / line end past-the-last-char (`goto_line_end_newline`) | file panes (terminal insert cursor rides its run, as before) | helix-verified (phase 5) |
| `PageUp` / `PageDown` | cursor page up / down, col kept (clamped to line) | file panes | helix-verified (phase 5) |
-| `Tab` | insert a literal tab (`Key.tab` case + the text path both land `\t`) | file content is correct; NOTE: file-pane RENDERING of a literal tab has no tab-stop expansion (pre-existing — any tab-containing file shows the same); helix smart-tab skipped | helix-verified (phase 5) |
+| `Tab` | indent to the next 4-column stop with SPACES (`insertTab`, `pardes.zig`: `pad = INDENT_W - col % INDENT_W`) — no `\t` byte ever reaches the file | helix's Spaces indent style; helix smart-tab skipped. After a `.` in a file the backend speaks, Tab instead asks for completion and only indents if the answer is empty (section A) | helix-verified (phase 5) |
## C. Skipped
| Key(s) | Helix behavior | Reason |
| --- | --- | --- |
| `?`, `*`, `Alt-*` | rsearch / selection-as-pattern | search — pardes has its own `/` (plain substring into an output buffer, kept as-is) and an `n`/`N` that SELECTS the next look-able text instead of walking match hits; helix regex search machinery not wanted |
-| `Space` mode, all rows but the clipboard menu (`f F e . b j g G k s S d D r a h ' w c C Alt-c / ?`) | pickers, LSP actions, global search, palette | helix's space mode is pickers + LSP, neither of which exists here — but the KEY is taken: pardes' own leader runs the acme builtins (section A). The clipboard menu is the half that DOES exist now: `<space>y Y p P R`, helix's letters on helix's leader, in section A |
+| `Space` mode: `f F e . b j g G ' w c C Alt-c / ?` | pickers, global search, palette | pickers and the command palette do not exist here — but the KEY is taken: pardes' own leader runs the acme builtins (section A). Two halves of helix's space mode DO exist and are in section A: the clipboard menu (`<space>y Y p P R`, helix's letters on helix's leader) and the LSP menu, moved one prefix deeper to `SPC l k/r/a/h/s/S/d/D` because `d`, `k`, `s` and `h` were already pardes' most-pressed keys |
| Popup `Ctrl-u`/`Ctrl-d`, Completion menu, Signature help tables | LSP popups | LSP |
| Picker table (all rows), Prompt table (all rows) | picker / prompt internals | pickers — pardes' tag line is its own one-line editor |
| `gn` `gp` `ga` `gm` | next/prev/alternate buffer | buffer nav — pardes panes aren't a buffer list |
@@ -292,15 +297,15 @@ text.
| `Alt-o`/`Alt-up`, `Alt-i`/`Alt-down`, `Alt-p`/`Alt-left`, `Alt-n`/`Alt-right`, `Alt-a`, `Alt-I`, `Alt-e`, `Alt-b` | syntax-node selection | tree-sitter |
| `]f [f ]t [t ]a [a ]c [c ]e [e ]T [T ]x [x` | TS unimpaired jumps | tree-sitter |
| `]g [g ]G [G` | git change jumps | needs VCS diff state |
-| `gd gD gy gr gi`, `=`, `]d [d ]D [D`, insert `Ctrl-x` | definition/refs/format/diagnostics/completion | LSP |
+| insert `Ctrl-x` | completion menu | completion exists, but not as a popup: insert-mode Tab straight after a `.` opens a buffer of candidate DECLARATIONS (section A). helix's menu itself is skipped |
| `"` `<reg>`, insert `Ctrl-r` | register select / insert | registers — one yank register and no way to name a second; the system clipboard is not spelled as a register here either, it is the five `SPC` commands in A |
| `Q` / `q` | record / replay macro | macros — needs replayable input log |
-| `Ctrl-i` `Ctrl-o` `Ctrl-s` (normal) | jumplist forward/back/save | jumplist |
+| `Ctrl-s` (normal) | save jumplist position | jumplist itself is implemented (`Ctrl-o`/`Ctrl-i`, section A); only the explicit save point is skipped |
| `Alt-u` / `Alt-U` | undo-history earlier/later | history timeline — linear snapshot u/U covers pardes |
| `K Alt-K`, `Alt-:` | regex keep/remove, ensure-forward | `K`/`Alt-K` are the same prompt `s`/`S` now have, filtering instead of splitting (`s S` moved to "Regex selection" in A, the rest of the family to "Multiple cursors") |
| `&`, `Alt-(` / `Alt-)` | align selections, rotate selection CONTENTS | see the multiple-cursors table for why |
| `Alt-J` | join + select the inserted space | marginal over `J` |
-| `\|` `Alt-\|` `!` `Alt-!` `$` | shell pipe/insert/append/keep | shell — pardes executes via Tab / middle-click chords instead |
+| `Alt-\|` `!` `Alt-!` `$` | shell pipe-to (output discarded), insert output, append output, keep-by-exit-status | shell — `\|` (`shell_pipe`, output replaces the selection) is implemented in section A; these four are the other members of helix's shell family. `$` is additionally taken for line-end here (section A) |
| `:` | command mode | side-effects/file-ops — pardes builtins live in the tag, and `:` is bound to focusing it (section A) |
| `gf` | goto file under selection | covered by pardes Enter-look |
| `Ctrl-z` | suspend | pardes IS the terminal multiplexer |