summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--build.zig54
-rw-r--r--docs/lsp-evaluation.md23
-rw-r--r--docs/lsp.md65
-rw-r--r--src/gui.zig38
-rw-r--r--src/lsp.zig37
-rw-r--r--src/lsp_zls.zig458
-rw-r--r--src/pardes.zig124
-rw-r--r--src/tty.zig21
-rw-r--r--test/lspbench.zig22
-rw-r--r--test/snapshot.zig20
-rw-r--r--test/snapshots/argv.golden6
-rw-r--r--test/snapshots/badutf.golden4
-rw-r--r--test/snapshots/boot.golden4
-rw-r--r--test/snapshots/chordcut.golden26
-rw-r--r--test/snapshots/cursorline.golden8
-rw-r--r--test/snapshots/dump.golden2
-rw-r--r--test/snapshots/edit.golden4
-rw-r--r--test/snapshots/exec-bigdrag.golden2
-rw-r--r--test/snapshots/exec.golden8
-rw-r--r--test/snapshots/fileedit.golden6
-rw-r--r--test/snapshots/find.golden28
-rw-r--r--test/snapshots/fsearch.golden20
-rw-r--r--test/snapshots/ghostty-mid.golden2
-rw-r--r--test/snapshots/grep.golden16
-rw-r--r--test/snapshots/hscroll.golden10
-rw-r--r--test/snapshots/images.golden10
-rw-r--r--test/snapshots/layout-close.golden10
-rw-r--r--test/snapshots/layout-open.golden10
-rw-r--r--test/snapshots/leader.golden181
-rw-r--r--test/snapshots/leader.snap53
-rw-r--r--test/snapshots/load.golden4
-rw-r--r--test/snapshots/logquiet.golden2
-rw-r--r--test/snapshots/look-center.golden6
-rw-r--r--test/snapshots/look-dir.golden2
-rw-r--r--test/snapshots/look-file-1col.golden2
-rw-r--r--test/snapshots/look-file.golden4
-rw-r--r--test/snapshots/lookloaded.golden6
-rw-r--r--test/snapshots/lookpanes.golden12
-rw-r--r--test/snapshots/lsp.golden14
-rw-r--r--test/snapshots/lsp.snap6
-rw-r--r--test/snapshots/lspdebug.golden225
-rw-r--r--test/snapshots/lspdebug.snap52
-rw-r--r--test/snapshots/modal.golden24
-rw-r--r--test/snapshots/psearch.golden20
-rw-r--r--test/snapshots/reflow.golden2
-rw-r--r--test/snapshots/respawn.golden2
-rw-r--r--test/snapshots/restore.golden4
-rw-r--r--test/snapshots/rsearch.golden8
-rw-r--r--test/snapshots/scroll.golden12
-rw-r--r--test/snapshots/scrolloff.golden14
-rw-r--r--test/snapshots/selarg.golden6
-rw-r--r--test/snapshots/shrinktag.golden10
-rw-r--r--test/snapshots/splitparent.golden8
-rw-r--r--test/snapshots/syntax.golden8
-rw-r--r--test/snapshots/tag.golden10
-rw-r--r--test/snapshots/tagcmd.golden10
-rw-r--r--test/snapshots/tagnav.golden90
-rw-r--r--test/snapshots/tagpath.golden20
-rw-r--r--test/snapshots/theme.golden20
-rw-r--r--test/snapshots/tinywin.golden6
-rw-r--r--test/snapshots/tty.golden10
-rw-r--r--test/snapshots/ttyclick.golden8
-rw-r--r--test/snapshots/ttyedit.golden10
-rw-r--r--test/snapshots/ttyfollow.golden6
-rw-r--r--test/snapshots/ttyhelp.golden93
-rw-r--r--test/snapshots/ttyhelp.snap21
-rw-r--r--test/snapshots/ttylook.golden18
-rw-r--r--test/snapshots/ttyonly.golden4
-rw-r--r--test/snapshots/tutor.golden2
-rw-r--r--test/snapshots/winch.golden4
-rw-r--r--test/snapshots/windownav.golden20
-rw-r--r--test/snapshots/windowops.golden24
-rw-r--r--test/snapshots/yankpaste.golden8
73 files changed, 1527 insertions, 582 deletions
diff --git a/build.zig b/build.zig
index 3c3c65f2..87df6727 100644
--- a/build.zig
+++ b/build.zig
@@ -2,6 +2,12 @@ const std = @import("std");
const snap_build = @import("build/snap.zig");
pub const Platform = enum { tty, gui, web };
+
+/// The ZLS the language backend links, spelled once. It names the commit
+/// build.zig.zon pins (0.16.x branch) and is passed BOTH to ZLS's own
+/// `-Dversion-string` (its build.zig otherwise shells out to `git describe`,
+/// which fails on a fetched package that has no .git) and to `SPC l i`.
+const zls_version = "0.16.1-dev+3e0d0820";
pub const TreeSitterGrammars = enum { disabled, zig, minimal, full };
const GhosttyArtifact = enum { ghostty, lib };
@@ -131,14 +137,19 @@ pub fn build(b: *std.Build) void {
opts.addOption(bool, "syntax_full_grammars", tree_sitter_grammars == .full);
opts.addOption(bool, "enable_tracy", tracy != null);
opts.addOption(bool, "zls_backend", zls_backend);
+ // Which ZLS is compiled in, for `SPC l i`. Kept next to the dependency it
+ // names: the .zon pins a commit, and a status screen that cannot say WHICH
+ // analyser answered is not worth opening.
+ opts.addOption([]const u8, "zls_version", if (zls_backend) zls_version else "none");
// The stdlib this binary was compiled against, so `gd` on `std.mem.count`
// can open the same mem.zig the compiler used. ZLS resolves `@import("std")`
// through `zig_lib_dir` and nothing else; without it every std symbol is a
// silent miss, and asking the `zig` binary for it is the subprocess this
// whole backend exists to avoid. ZIG_LIB_DIR overrides it at runtime.
opts.addOption([]const u8, "zig_lib_dir", b.graph.zig_lib_directory.path orelse "");
- root_mod.addOptions("pardes_config", opts);
- hx_core_mod.addOptions("pardes_config", opts);
+ // NOTE: `opts` is attached to the modules at the BOTTOM of this function,
+ // after every addImport — the module-import table below is folded out of
+ // root_mod.import_table and would be empty if we attached it here.
if (zls_backend) {
// .target/.optimize are mandatory: createZLSModule bakes them into the
@@ -154,7 +165,7 @@ pub fn build(b: *std.Build) void {
const zls_dep = b.dependency("zls", .{
.target = target,
.optimize = optimize,
- .@"version-string" = @as([]const u8, "0.16.1-dev"),
+ .@"version-string" = @as([]const u8, zls_version),
});
root_mod.addImport("zls", zls_dep.module("zls"));
hx_core_mod.addImport("zls", zls_dep.module("zls"));
@@ -376,6 +387,43 @@ pub fn build(b: *std.Build) void {
root_mod.addImport("uucode", uucode_mod);
hx_core_mod.addImport("uucode", uucode_mod);
+ // --- the dependency module map, for `gd` on `@import("vaxis")` ---
+ //
+ // ZLS resolves an import string three ways: a relative `.zig` path, `std`
+ // (via zig_lib_dir), and everything else — which it can only answer by
+ // running `zig build --build-runner` to learn the module graph. This
+ // backend sets `zig_exe_path = null` on purpose, so that last branch
+ // returns nothing and every `@import("<dependency>")` is a silent miss
+ // while `std` works perfectly. That asymmetry is the whole bug report.
+ //
+ // We do not need the compiler to answer it: THIS FILE *is* the module
+ // graph. Fold the imports we just wired into a name->root-source table and
+ // hand it to the backend, which consults it exactly where ZLS gave up.
+ // Costs one build option and stays correct by construction — a dependency
+ // that is added or renamed above cannot forget to update it.
+ var mod_names: std.ArrayList([]const u8) = .empty;
+ var mod_roots: std.ArrayList([]const u8) = .empty;
+ {
+ var it = root_mod.import_table.iterator();
+ while (it.next()) |e| {
+ const lp = e.value_ptr.*.root_source_file orelse continue;
+ // `generated` is a build artifact (the options modules): it has no
+ // path until make() runs, and pointing an editor at one is useless
+ const abs = switch (lp) {
+ .src_path => |sp| sp.owner.pathFromRoot(sp.sub_path),
+ .cwd_relative => |cr| cr,
+ else => continue,
+ };
+ mod_names.append(b.allocator, e.key_ptr.*) catch @panic("OOM");
+ mod_roots.append(b.allocator, abs) catch @panic("OOM");
+ }
+ }
+ opts.addOption([]const []const u8, "module_names", mod_names.items);
+ opts.addOption([]const []const u8, "module_roots", mod_roots.items);
+
+ root_mod.addOptions("pardes_config", opts);
+ hx_core_mod.addOptions("pardes_config", opts);
+
// SDL3 shell wiring (-Dplatform=gui and web). The sdl package builds SDL3
// from source as a static lib + emits the SDL3/ headers; gui.zig @cImports
// those, plus a small stb_truetype C shim for the glyph atlas, and embeds
diff --git a/docs/lsp-evaluation.md b/docs/lsp-evaluation.md
index ae822213..5f660640 100644
--- a/docs/lsp-evaluation.md
+++ b/docs/lsp-evaluation.md
@@ -2,16 +2,16 @@
Same core, same seam (`src/lsp.zig`), same 17-probe harness (`zig build lspbench`)
over the same corpus. Three jj workspaces, three independent implementations,
-one function each.
+one function each. C landed; see **Decision** below.
| | **A · stdlib** | **B · client** | **C · in-process** |
|---|---|---|---|
-| workspace | `pardes-ws-ast` | `pardes-ws-proto` | `pardes-ws-inproc` |
+| change | `nvqpknzm` | `stuurqqt` | **landed** |
| what it is | `std.zig.Ast` + `AstGen`, hand-rolled scope walk | `zls` as a child process, JSON-RPC over a socketpair | ZLS linked as a Zig module, analyser called directly |
| **probes correct** | 12 / 17 | **17 / 17** | **17 / 17** |
| **false claims** | 0 | 0 | 0 |
| **implementation LOC** | 622 (+307 test) | 721 | **540** (+29 build) |
-| new dependency | **none** | a `zls` binary at runtime | ZLS source (path dep) |
+| new dependency | **none** | a `zls` binary at runtime | ZLS source (fetched into `zig-pkg/`) |
| binary size vs base | +6 MiB | +14 MiB | +35 MiB |
| memory | 3.7 MiB | 1.1 MiB **+ 37 MiB in the child** | 5.5 MiB |
| processes | **1** | 2 | **1** |
@@ -82,7 +82,22 @@ All three keep the 56 existing snapshot scripts green, add a 57th driving the
real binary through the helix keymap, and pass `hxdiff` (360) and `hxparity`
(440) with no new waivers.
-## Recommendation
+## Decision
+
+**C landed.** It is what `src/lsp_zls.zig` is, and ZLS is now a fetched
+dependency (`build.zig.zon`, pinned to commit `3e0d0820` on the 0.16.x branch)
+so it sits in `zig-pkg/` like everything else and the build is reproducible
+from the .zon alone — no path dependency on a local checkout.
+
+A and B were not deleted, only un-worktree'd. They remain whole commits:
+
+- **A · stdlib** — change `nvqpknzm`
+- **B · client** — change `stuurqqt`
+
+Both are one `jj new <change>` away if the multi-language argument below wins
+later, or if the ZLS coupling ever needs backing out.
+
+## Recommendation (as written before the decision)
**C (in-process), with B as the answer to a question pardes has not asked yet.**
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
diff --git a/src/gui.zig b/src/gui.zig
index e157ef28..25abe905 100644
--- a/src/gui.zig
+++ b/src/gui.zig
@@ -610,8 +610,9 @@ fn lspThread(gpa: std.mem.Allocator, job: *LspJob, q: *Queue) void {
defer job.free(gpa);
var arena: std.heap.ArenaAllocator = .init(gpa);
defer arena.deinit();
- var out: std.ArrayList(u8) = .empty;
- defer out.deinit(gpa);
+ // the shell owns the result buffer; the backend only ever writes to it
+ var out: std.Io.Writer.Allocating = .init(gpa);
+ defer out.deinit();
pardes.lsp.query(gpa, arena.allocator(), .{
.kind = job.kind,
.path = job.path,
@@ -619,8 +620,8 @@ fn lspThread(gpa: std.mem.Allocator, job: *LspJob, q: *Queue) void {
.offset = job.offset,
.arg = job.arg,
.root = job.root,
- }, &out);
- const rows = gpa.dupe(u8, out.items) catch return;
+ }, &out.writer);
+ const rows = gpa.dupe(u8, out.written()) catch return;
q.push(.{ .lsp = .{ .id = job.id, .rows = rows } });
}
@@ -629,17 +630,19 @@ fn lspThread(gpa: std.mem.Allocator, job: *LspJob, q: *Queue) void {
/// already tolerates a late push after close.
fn spawnLsp(core: *pardes.Pardes, gpa: std.mem.Allocator, q: *Queue, e: anytype) void {
const pane = core.panes[e.pane] orelse return;
- const f = pane.file orelse return;
+ // a pane with no file still asks `status` (it is about the backend, not
+ // the buffer): empty path and source, root from the pane's cwd
+ const f = pane.file;
const job = gpa.create(LspJob) catch return;
job.* = .{
.id = e.id,
.kind = e.kind,
.offset = e.offset,
- .path = gpa.dupe(u8, f.path) catch {
+ .path = gpa.dupe(u8, if (f) |ff| ff.path else "") catch {
gpa.destroy(job);
return;
},
- .source = gpa.dupeZ(u8, f.content) catch {
+ .source = gpa.dupeZ(u8, if (f) |ff| ff.content else "") catch {
gpa.free(job.path);
gpa.destroy(job);
return;
@@ -650,7 +653,7 @@ fn spawnLsp(core: *pardes.Pardes, gpa: std.mem.Allocator, q: *Queue, e: anytype)
gpa.destroy(job);
return;
},
- .root = gpa.dupe(u8, std.fs.path.dirname(f.path) orelse "/") catch {
+ .root = gpa.dupe(u8, if (f) |ff| (std.fs.path.dirname(ff.path) orelse "/") else pane.cwdSlice()) catch {
gpa.free(job.path);
gpa.free(job.source);
gpa.free(job.arg);
@@ -1572,6 +1575,7 @@ const StdinFeed = struct {
},
.col = @intCast(@max(m.col, 0)),
.row = @intCast(@max(m.row, 0)),
+ .ctrl = m.mods.ctrl,
} });
out.n_events += 1;
}
@@ -1714,12 +1718,18 @@ fn dispatch(g: *Gui, core: *pardes.Pardes, sev: *const c.SDL_Event) void {
else => return,
};
const mc = mouseCell(g, core, b.x, b.y);
- core.update(.{ .mouse = .{
- .button = button,
- .kind = if (b.down) .press else .release,
- .col = mc.col,
- .row = mc.row,
- } });
+ core.update(.{
+ .mouse = .{
+ .button = button,
+ .kind = if (b.down) .press else .release,
+ .col = mc.col,
+ .row = mc.row,
+ // asked of SDL directly rather than read off g.live_ctrl:
+ // that one is bookkeeping from KEY events, and a ctrl-click
+ // with no key pressed since startup would miss it
+ .ctrl = (c.SDL_GetModState() & c.SDL_KMOD_CTRL) != 0,
+ },
+ });
},
c.SDL_EVENT_MOUSE_MOTION => {
const m = sev.motion;
diff --git a/src/lsp.zig b/src/lsp.zig
index fe492c62..536047a3 100644
--- a/src/lsp.zig
+++ b/src/lsp.zig
@@ -50,6 +50,17 @@ pub const Kind = enum {
/// SPC h
select_refs,
+ // The two introspection kinds. A backend that answers nothing is
+ // indistinguishable from a backend that is broken, so these exist to tell
+ // those apart — they are the only Kinds whose answer is ABOUT the backend
+ // rather than about the code.
+ /// SPC l i — configuration, capabilities and the recent-query log
+ status,
+ /// SPC l w — why the query at the cursor answers what it does. Narrates
+ /// the REAL resolution path rather than re-deriving it, so it cannot drift
+ /// away from what `gd` actually did.
+ explain,
+
/// Whether an answer of exactly one row should JUMP rather than open a
/// results buffer. Helix: the five gotos jump on a single location and
/// show a picker on several; a symbol list is always a picker.
@@ -66,6 +77,8 @@ pub const Kind = enum {
return switch (k) {
.hover => "+Hover",
.code_action, .format, .rename => "+Lsp",
+ // prose about the backend, never a list of locations
+ .status, .explain => "+Lsp",
else => "+Search",
};
}
@@ -94,14 +107,13 @@ pub const Req = struct {
/// Emit one `path:LINE:COL text` row. Line and column are 1-based, the way
/// every other row in a `+Search` buffer is (and the way look.zig parses one).
pub fn row(
- gpa: std.mem.Allocator,
- out: *std.ArrayList(u8),
+ out: *std.Io.Writer,
path: []const u8,
line: usize,
col: usize,
text: []const u8,
) void {
- out.print(gpa, "{s}:{d}:{d} {s}\n", .{
+ out.print("{s}:{d}:{d} {s}\n", .{
path, line + 1, col + 1, std.mem.trim(u8, text, " \t\r\n"),
}) catch {};
}
@@ -115,14 +127,19 @@ pub fn lineCol(source: []const u8, offset: usize) struct { line: usize, col: usi
return .{ .line = line, .col = upto.len - bol };
}
-/// Answer `req`, appending rows to `out`. Runs on a worker thread with no
+/// Answer `req`, writing rows to `out`. Runs on a worker thread with no
/// access to the core: everything it may read is in `req`.
///
-/// `arena` is freed wholesale when the query returns; `gpa` owns only what
-/// goes into `out`. Errors are not reported — a backend that cannot answer
-/// appends nothing, and the core treats "no rows" as "no result", which is
-/// also what a language server that is still starting up looks like.
-pub fn query(gpa: std.mem.Allocator, arena: std.mem.Allocator, req: Req, out: *std.ArrayList(u8)) void {
+/// `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. Write failures are the
+/// writer's problem; a backend may ignore them.
+///
+/// `arena` is freed wholesale when the query returns; `gpa` is for a backend's
+/// own longer-lived scratch. Errors are not reported — a backend that cannot
+/// answer writes nothing, and the core treats "no rows" as "no result", which
+/// is also what a language server still starting up looks like.
+pub fn query(gpa: std.mem.Allocator, arena: std.mem.Allocator, req: Req, out: *std.Io.Writer) void {
backend.query(gpa, arena, req, out);
}
@@ -131,7 +148,7 @@ pub fn query(gpa: std.mem.Allocator, arena: std.mem.Allocator, req: Req, out: *s
/// effect, and cannot build ZLS anyway, so there it is the empty backend the
/// base tree shipped with.
const backend = if (@import("pardes_config").zls_backend) @import("lsp_zls.zig") else struct {
- pub fn query(_: std.mem.Allocator, _: std.mem.Allocator, _: Req, _: *std.ArrayList(u8)) void {}
+ pub fn query(_: std.mem.Allocator, _: std.mem.Allocator, _: Req, _: *std.Io.Writer) void {}
pub const supports: std.EnumSet(Kind) = .initEmpty();
};
diff --git a/src/lsp_zls.zig b/src/lsp_zls.zig
index 99d20a10..6f5bbcdd 100644
--- a/src/lsp_zls.zig
+++ b/src/lsp_zls.zig
@@ -23,9 +23,21 @@
//! - `zig_exe_path` is null on purpose: shelling out to the compiler is the
//! thing this backend exists to avoid. `zig_lib_dir` is the build's own
//! (`b.graph.zig_lib_directory`), which is what makes `std` resolvable —
-//! `gd` on `std.mem.count` lands in the real `mem.zig`. The price is that
-//! `@import("builtin")`, `@import("<pkg>")` and `@cImport` resolve to
-//! nothing, silently, because those need a build graph we refuse to run.
+//! `gd` on `std.mem.count` lands in the real `mem.zig`.
+//!
+//! The price is DEPENDENCIES, and it is worth being exact about how far it
+//! goes. ZLS resolves a non-`std`, non-relative import only through a
+//! `BuildFile` whose config came from running `zig build --build-runner`, so
+//! with no compiler it resolves none of them. We paper over ONE case of
+//! that: `gd` on the import string itself (`moduleRoot`, fed by build.zig).
+//! That is a fallback in OUR handler and ZLS cannot see it, so the analyser
+//! still cannot type `vaxis`, and `gd` on `vaxis.init` still finds nothing.
+//! Making member access work means giving ZLS a real build config — either
+//! by letting it run the build runner (a subprocess, and with no cross-query
+//! cache that is once PER KEYPRESS) or by synthesizing a BuildConfig and
+//! reaching into `BuildFile.impl`. Both are real work; neither is smuggled
+//! in here. `@import("builtin")` and `@cImport` are unresolved for the same
+//! reason.
const std = @import("std");
const zls = @import("zls");
const lsp = @import("lsp.zig");
@@ -64,17 +76,142 @@ pub const supports: std.EnumSet(lsp.Kind) = .initMany(&.{
.rename,
.format,
.code_action,
+ .status,
+ .explain,
});
+// ------------------------------------------------------------ introspection
+//
+// Everything below exists because of the contract two lines down: this backend
+// never fails loudly. That is right for an editor — a thrown analyser must not
+// take the process with it — but it means a broken backend and a correct one
+// that found nothing look identical from the outside. So every query leaves a
+// record, and `SPC l i` reads them back.
+
+/// One finished query. Fixed-size and inline: this array is process-global and
+/// lives forever, so it must not own heap.
+const LogEntry = struct {
+ used: bool = false,
+ kind: lsp.Kind = .definition,
+ us: u64 = 0,
+ rows: usize = 0,
+ offset: u32 = 0,
+ /// the error `run` returned, or empty when it returned normally. THIS is
+ /// the thing you cannot see any other way.
+ err: [40]u8 = @splat(0),
+ err_len: u8 = 0,
+ /// basename only — a full path would need most of this struct
+ file: [64]u8 = @splat(0),
+ file_len: u8 = 0,
+
+ fn errName(e: *const LogEntry) []const u8 {
+ return e.err[0..e.err_len];
+ }
+ fn fileName(e: *const LogEntry) []const u8 {
+ return e.file[0..e.file_len];
+ }
+};
+
+const log_cap = 24;
+var log_buf: [log_cap]LogEntry = @splat(.{});
+var log_next: usize = 0;
+var log_total: u64 = 0;
+/// 0.16 has no std.Thread.Mutex; the critical sections here are a memcpy, so
+/// spinning on the lock-free one is enough — the same call gui.zig's pty queue
+/// makes. Only WORKER threads touch this; the core never does.
+var log_mu: std.atomic.Mutex = .unlocked;
+
+fn logLock() void {
+ while (!log_mu.tryLock()) std.atomic.spinLoopHint();
+}
+
+fn record(req: lsp.Req, us: u64, rows: usize, err: []const u8) void {
+ logLock();
+ defer log_mu.unlock();
+ const e = &log_buf[log_next];
+ e.* = .{ .used = true, .kind = req.kind, .us = us, .rows = rows, .offset = req.offset };
+ const base = std.fs.path.basename(req.path);
+ e.file_len = @intCast(@min(base.len, e.file.len));
+ @memcpy(e.file[0..e.file_len], base[0..e.file_len]);
+ e.err_len = @intCast(@min(err.len, e.err.len));
+ @memcpy(e.err[0..e.err_len], err[0..e.err_len]);
+ log_next = (log_next + 1) % log_cap;
+ log_total += 1;
+}
+
+/// A duration cannot go in a snapshot golden — it differs every run. The
+/// snapshot harness sets PARDES_LSP_NOTIME so the two introspection views
+/// print `-` instead, the same way it pins PARDES_DUMP for the dump tests.
+/// Nothing else reads it, and unset (i.e. every real run) shows real numbers.
+fn hideTime() bool {
+ const v = std.c.getenv("PARDES_LSP_NOTIME") orelse return false;
+ return std.mem.span(v).len != 0;
+}
+
+fn nowUs() u64 {
+ var ts: std.c.timespec = undefined;
+ _ = std.c.clock_gettime(.MONOTONIC, &ts);
+ return @as(u64, @intCast(ts.sec)) *| 1_000_000 +| @as(u64, @intCast(ts.nsec)) / 1000;
+}
+
+/// The narration `SPC l w` prints. It is threaded through the REAL resolution
+/// path rather than re-derived beside it: a debug view that reimplements the
+/// logic is a debug view that can disagree with it, and the whole point is to
+/// find out what actually happened.
+const Trace = struct {
+ on: bool = false,
+ arena: std.mem.Allocator,
+ buf: std.ArrayList(u8) = .empty,
+
+ fn note(t: *Trace, comptime fmt: []const u8, args: anytype) void {
+ if (!t.on) return;
+ t.buf.print(t.arena, fmt ++ "\n", args) catch {};
+ }
+};
+
/// The seam's contract: never fail, never panic, no rows is a legal answer.
/// Every error path in here — OOM, a cancelled io, a file that vanished —
/// collapses to "appended nothing", which the core already treats as "no
/// result". There is deliberately no error rendering.
-pub fn query(gpa: std.mem.Allocator, arena: std.mem.Allocator, req: lsp.Req, out: *std.ArrayList(u8)) void {
- run(gpa, arena, req, out) catch {};
+pub fn query(gpa: std.mem.Allocator, arena: std.mem.Allocator, req: lsp.Req, out: *std.Io.Writer) void {
+ // status reads the log; recording it would push a real query out of a
+ // 24-entry ring every time you looked at it.
+ if (req.kind == .status) return status(arena, req, out) catch {};
+
+ // Rows land in a scratch buffer first, for two reasons a plain Writer
+ // cannot serve: the log wants an exact row count, and `explain` throws the
+ // rows away and prints the narration in their place — neither a count nor
+ // a rewind exists on a Writer you do not own.
+ var scratch: std.Io.Writer.Allocating = .init(gpa);
+ defer scratch.deinit();
+
+ var tr: Trace = .{ .arena = arena, .on = req.kind == .explain };
+ const t0 = nowUs();
+ var err_name: []const u8 = "";
+ run(gpa, arena, req, &scratch.writer, &tr) catch |e| {
+ err_name = @errorName(e);
+ tr.note("ERROR: {s} — the query threw; the editor shows this as 'no result'", .{err_name});
+ };
+ const us = nowUs() -| t0;
+ const rows = std.mem.count(u8, scratch.written(), "\n");
+ record(req, us, rows, err_name);
+
+ if (req.kind != .explain) {
+ out.writeAll(scratch.written()) catch {};
+ return;
+ }
+ // the question was never "where is it", it was "what did you do"
+ out.print("lsp explain — the definition query at byte {d} of {s}\n\n", .{
+ req.offset, if (req.path.len == 0) "(no file)" else std.fs.path.basename(req.path),
+ }) catch {};
+ out.writeAll(tr.buf.items) catch {};
+ if (hideTime())
+ out.print("\n{d} row(s)\n", .{rows}) catch {}
+ else
+ out.print("\n{d} row(s) in {d}us\n", .{ rows, us }) catch {};
}
-fn run(gpa: std.mem.Allocator, arena: std.mem.Allocator, req: lsp.Req, out: *std.ArrayList(u8)) !void {
+fn run(gpa: std.mem.Allocator, arena: std.mem.Allocator, req: lsp.Req, out: *std.Io.Writer, tr: *Trace) !void {
// The blocking, single-threaded std.Io — the same one look.zig walks
// directories with. ZLS wants an `Io` for every file read; a worker thread
// that is allowed to block wants the one that just does the syscall.
@@ -83,25 +220,35 @@ fn run(gpa: std.mem.Allocator, arena: std.mem.Allocator, req: lsp.Req, out: *std
// The two workspace kinds are about the PROJECT, not about this buffer, so
// they answer from any pane and never need the analyser, the store or the
// intern pool — a walk and a parse each.
- switch (req.kind) {
+ // `explain` narrates the definition query; everywhere below dispatches on
+ // the effective kind, so the trace follows the code `gd` really runs.
+ const kind: lsp.Kind = if (req.kind == .explain) .definition else req.kind;
+
+ switch (kind) {
.workspace_symbols => return workspaceSymbols(gpa, arena, io, req, out),
.workspace_diagnostics => return workspaceDiagnostics(gpa, arena, io, req, out),
// Everything else is about THIS file, and this backend speaks Zig. The
// core does not gate the keymap by file type (a pane is a pane), so
// the gate is here: `gd` in a README must find nothing rather than
// parse prose as Zig and confidently resolve a word out of it.
- else => if (!std.mem.endsWith(u8, req.path, ".zig")) return,
+ else => if (!std.mem.endsWith(u8, req.path, ".zig")) {
+ tr.note("STOP: not a .zig file ({s}) — this backend only reads Zig", .{
+ if (req.path.len == 0) "no path: this pane has no file behind it" else req.path,
+ });
+ return;
+ },
}
// Pure tree, no analyser.
- if (req.kind == .format) return formatQuery(gpa, arena, req, out);
+ if (kind == .format) return formatQuery(arena, req, out);
var env: std.process.Environ.Map = .init(arena);
var lib_dir: ?std.Build.Cache.Directory = null;
if (zigLibPath()) |p| {
if (std.Io.Dir.cwd().openDir(io, p, .{})) |h| {
lib_dir = .{ .handle = h, .path = p };
- } else |_| {}
- }
+ tr.note("zig lib dir: {s} (open) — `std` imports resolve", .{p});
+ } else |e| tr.note("zig lib dir: {s} FAILED to open ({s}) — nothing in `std` will resolve", .{ p, @errorName(e) });
+ } else tr.note("zig lib dir: NOT SET — nothing in `std` will resolve", .{});
defer if (lib_dir) |d| d.handle.close(io);
var ip: InternPool = try .init(io, gpa);
@@ -131,28 +278,158 @@ fn run(gpa: std.mem.Allocator, arena: std.mem.Allocator, req: lsp.Req, out: *std
// shell's snapshot, so unsaved edits are what gets analysed.
const uri: Uri = try .fromPath(arena, req.path);
try store.openLspSyncedDocument(uri, req.source);
- const handle = store.getHandle(uri) orelse return;
- if (handle.tree.mode == .zon) return;
+ const handle = store.getHandle(uri) orelse {
+ tr.note("STOP: the document store would not take this buffer", .{});
+ return;
+ };
+ if (handle.tree.mode == .zon) {
+ tr.note("STOP: parsed as .zon, not Zig code — there is nothing to resolve", .{});
+ return;
+ }
+ tr.note("parsed {d} bytes, {d} syntax error(s){s}", .{
+ req.source.len,
+ handle.tree.errors.len,
+ if (handle.tree.errors.len == 0) "" else " — a broken tree resolves badly or not at all",
+ });
var analyser: Analyser = .init(gpa, arena, &store, &ip, handle);
defer analyser.deinit();
const off: usize = @min(req.offset, req.source.len);
- switch (req.kind) {
- .definition, .implementation => try goto(gpa, arena, &analyser, handle, off, .definition, out),
- .declaration => try goto(gpa, arena, &analyser, handle, off, .declaration, out),
- .type_definition => try goto(gpa, arena, &analyser, handle, off, .type_definition, out),
- .hover => try hover(gpa, arena, &analyser, handle, off, out),
+ switch (kind) {
+ .definition, .implementation => try goto(arena, &analyser, handle, off, .definition, out, tr),
+ .declaration => try goto(arena, &analyser, handle, off, .declaration, out, tr),
+ .type_definition => try goto(arena, &analyser, handle, off, .type_definition, out, tr),
+ .hover => try hover(arena, &analyser, handle, off, out),
.document_symbols => try documentSymbols(gpa, arena, req.path, &handle.tree, out),
- .references, .select_refs => try references(gpa, arena, &analyser, handle, off, null, out),
- .rename => try references(gpa, arena, &analyser, handle, off, req.arg, out),
+ .references, .select_refs => try references(arena, &analyser, handle, off, null, out),
+ .rename => try references(arena, &analyser, handle, off, req.arg, out),
.diagnostics => try diagnostics(gpa, arena, req.path, &handle.tree, out),
.code_action => try codeActions(gpa, arena, &analyser, handle, off, out),
else => {},
}
}
+/// `SPC l i`. What the backend IS: which ZLS, which stdlib, what it will and
+/// will not answer, and the last two dozen queries with their timings and —
+/// the point of the whole exercise — the errors that `query` swallowed.
+fn status(arena: std.mem.Allocator, req: lsp.Req, out: *std.Io.Writer) !void {
+ const io = std.Io.Threaded.global_single_threaded.io();
+ try out.print("backend: {s}\nzls: {s} (compiled in — no server process, no JSON-RPC)\n", .{
+ lsp.backend_name, cfg.zls_version,
+ });
+
+ // The single most common cause of "gd does nothing in std": say whether it
+ // is actually openable, not just what it is set to.
+ if (zigLibPath()) |p| {
+ if (std.Io.Dir.cwd().openDir(io, p, .{})) |h| {
+ var d = h;
+ d.close(io);
+ try out.print("zig lib dir: {s} [OK]\n", .{p});
+ } else |e| try out.print("zig lib dir: {s} [CANNOT OPEN: {s}] — nothing in `std` will resolve\n", .{ p, @errorName(e) });
+ } else try out.print("zig lib dir: NOT SET — nothing in `std` will resolve\n", .{});
+ try out.print("offsets: {s} walk caps: {d} files, {d} rows\n", .{ @tagName(enc), max_files, max_rows });
+ // The dependency module map, which is the answer to "why does gd work on
+ // std and not on @import(\"vaxis\")" — if a name is not on this list, the
+ // build did not import it and nothing can resolve it.
+ try out.print("\ndependency imports gd can follow ({d}):\n", .{cfg.module_names.len});
+ for (cfg.module_names, cfg.module_roots) |n, r| {
+ try out.print(" {s:<14} {s}\n", .{ n, r });
+ }
+ try out.print("asked from: {s}\n", .{if (req.path.len == 0) "a pane with no file" else req.path});
+
+ try out.print("\nanswers:", .{});
+ var it = supports.iterator();
+ var n: usize = 0;
+ while (it.next()) |k| : (n += 1) {
+ if (k == .status or k == .explain) continue; // these two are the debugger, not a feature
+ try out.print("{s}{s}", .{ if (n == 0) " " else ", ", @tagName(k) });
+ }
+ try out.print("\nrefuses: ", .{});
+ n = 0;
+ for (std.enums.values(lsp.Kind)) |k| {
+ if (supports.contains(k)) continue;
+ try out.print("{s}{s}", .{ if (n == 0) "" else ", ", @tagName(k) });
+ n += 1;
+ }
+ if (n == 0) try out.print("(nothing)", .{});
+ try out.print("\n", .{});
+
+ // The log. Oldest first, so it reads like a transcript.
+ logLock();
+ defer log_mu.unlock();
+ try out.print("\nlast queries ({d} total, keeping {d}):\n", .{ log_total, log_cap });
+ var shown: usize = 0;
+ for (0..log_cap) |i| {
+ const e = &log_buf[(log_next + i) % log_cap];
+ if (!e.used) continue;
+ shown += 1;
+ if (hideTime()) {
+ try out.print(" {s:<22} {s:<20} @{d:<7} {d:>4} row(s){s}{s}\n", .{
+ @tagName(e.kind), e.fileName(), e.offset, e.rows,
+ if (e.err_len == 0) "" else " ERROR: ", e.errName(),
+ });
+ } else {
+ try out.print(" {s:<22} {s:<20} @{d:<7} {d:>7}us {d:>4} row(s){s}{s}\n", .{
+ @tagName(e.kind), e.fileName(), e.offset, e.us, e.rows,
+ if (e.err_len == 0) "" else " ERROR: ", e.errName(),
+ });
+ }
+ }
+ if (shown == 0) try out.print(" (none yet — press gd somewhere, then ask again)\n", .{});
+ _ = arena;
+}
+
+/// The root source file of a module this build imports, or null.
+///
+/// ZLS answers `@import("std")` from `zig_lib_dir` and a relative `.zig` path
+/// from the filesystem, but ANY OTHER name — every dependency in
+/// build.zig.zon — it can only resolve by running `zig build --build-runner`
+/// to discover the module graph. This backend sets `zig_exe_path = null` on
+/// purpose, so that branch always returned nothing: `gd` worked perfectly into
+/// `std` and silently did nothing on `@import("vaxis")`.
+///
+/// We never needed the compiler for this. build.zig IS the module graph, so it
+/// folds its own `root_mod.import_table` into these two parallel arrays at
+/// configure time. Correct by construction: a dependency added or renamed in
+/// build.zig cannot forget to appear here.
+///
+/// LIMITS, in the order you will hit them:
+/// 1. This resolves the IMPORT STRING only. It is consulted from our own
+/// `goto`, not from inside ZLS, so the analyser still cannot type the
+/// `vaxis` const — `gd` on `vaxis.init` finds nothing. Fixing that means
+/// giving ZLS a BuildConfig; see the note at the top of this file.
+/// 2. These are THIS build's imports. A file inside a dependency importing
+/// that dependency's own internal module name is a miss — that would mean
+/// running ITS build.zig.
+/// 3. A module whose root source is a GENERATED file is absent from the
+/// table: it has no path until make() runs.
+fn moduleRoot(name: []const u8) ?[]const u8 {
+ comptime std.debug.assert(cfg.module_names.len == cfg.module_roots.len);
+ for (cfg.module_names, cfg.module_roots) |n, r| {
+ if (std.mem.eql(u8, n, name)) return r;
+ }
+ return null;
+}
+
+/// Why a field access came back empty. Worth its own function because ONE of
+/// the reasons is a known, explainable hole rather than "no idea": if the left
+/// side starts with a dependency module name, the analyser could not type it
+/// because ZLS has no build config, and no amount of staring at the code will
+/// reveal that.
+fn explainFieldMiss(tr: *Trace, lhs: []const u8) void {
+ var head: usize = 0;
+ while (head < lhs.len and (std.ascii.isAlphanumeric(lhs[head]) or lhs[head] == '_')) head += 1;
+ if (head != 0 and moduleRoot(lhs[0..head]) != null) {
+ tr.note(" `{s}` IS a build.zig dependency, and this is the known hole: the module", .{lhs[0..head]});
+ tr.note(" map is consulted by our @import handler, not by ZLS, so the analyser cannot", .{});
+ tr.note(" type it. `gd` on the import string works; `gd` on a member does not.", .{});
+ return;
+ }
+ tr.note(" (a value whose type needs comptime, an unresolved @import, or genuinely absent)", .{});
+}
+
/// The zig lib directory, which is the one thing this backend cannot work out
/// for itself: it is baked in at build time from `b.graph.zig_lib_directory`,
/// i.e. the exact stdlib pardes was compiled against, and ZIG_LIB_DIR wins if
@@ -202,12 +479,12 @@ fn lineAt(src: []const u8, want: usize) []const u8 {
/// Emit one row for a token in whatever file it lives in — which for a goto
/// into `std` is not the file the cursor was in, so the path comes off the
/// handle's uri rather than off `req`.
-fn rowForToken(gpa: std.mem.Allocator, arena: std.mem.Allocator, th: Analyser.TokenWithHandle, out: *std.ArrayList(u8)) !void {
+fn rowForToken(arena: std.mem.Allocator, th: Analyser.TokenWithHandle, out: *std.Io.Writer) !void {
const tree = &th.handle.tree;
if (th.token >= tree.tokens.len) return;
const r = offsets.tokenToRange(tree, th.token, enc);
const path = th.handle.uri.toFsPath(arena) catch return;
- lsp.row(gpa, out, path, r.start.line, r.start.character, lineAt(tree.source, r.start.line));
+ lsp.row(out, path, r.start.line, r.start.character, lineAt(tree.source, r.start.line));
}
// ---------------------------------------------------------------- goto
@@ -220,32 +497,65 @@ const GotoKind = enum { declaration, definition, type_definition };
/// collapse onto three ZLS kinds (`gi` behaves as `gd`, which is what ZLS's
/// own implementation handler does too).
fn goto(
- gpa: std.mem.Allocator,
arena: std.mem.Allocator,
analyser: *Analyser,
handle: *DocumentStore.Handle,
off: usize,
kind: GotoKind,
- out: *std.ArrayList(u8),
+ out: *std.Io.Writer,
+ tr: *Trace,
) !void {
const tree = &handle.tree;
const ctx = try Analyser.getPositionContext(arena, tree, off, true);
+ tr.note("position context: .{s}", .{@tagName(ctx)});
var decls: std.ArrayList(Analyser.DeclWithHandle) = .empty;
switch (ctx) {
.var_access, .test_doctest_name => {
- const name_loc = offsets.identifierLocFromIndex(tree, off) orelse return;
+ const name_loc = offsets.identifierLocFromIndex(tree, off) orelse {
+ tr.note("STOP: no identifier under the cursor", .{});
+ return;
+ };
const name = offsets.locToSlice(tree.source, name_loc);
- if (std.mem.eql(u8, name, "_")) return;
- if (std.zig.isPrimitive(name)) return;
- const d = try analyser.lookupSymbolGlobal(handle, name, off) orelse return;
+ tr.note("identifier: `{s}` — a plain name, so: innermost scope outward", .{name});
+ if (std.mem.eql(u8, name, "_")) {
+ tr.note("STOP: `_` is the discard, it declares nothing", .{});
+ return;
+ }
+ if (std.zig.isPrimitive(name)) {
+ tr.note("STOP: `{s}` is a builtin primitive — it has no declaration in any file", .{name});
+ return;
+ }
+ const d = try analyser.lookupSymbolGlobal(handle, name, off) orelse {
+ tr.note("STOP: lookupSymbolGlobal found no `{s}` in scope here", .{name});
+ return;
+ };
try decls.append(arena, d);
},
.field_access => |loc| {
- const name_loc = offsets.identifierLocFromIndex(tree, off) orelse return;
+ const name_loc = offsets.identifierLocFromIndex(tree, off) orelse {
+ tr.note("STOP: no identifier under the cursor", .{});
+ return;
+ };
const name = offsets.locToSlice(tree.source, name_loc);
const held = offsets.locMerge(loc, name_loc);
- const found = try analyser.getSymbolFieldAccesses(arena, handle, off, held, name) orelse return;
+ tr.note("field access: `{s}` on `{s}` — needs the TYPE of the left side", .{
+ name, offsets.locToSlice(tree.source, loc),
+ });
+ // NOTE both misses: a null result AND an empty one. ZLS returns an
+ // empty slice when it typed the left side but found no such member,
+ // and null when it could not type it at all — from the outside both
+ // are "gd did nothing", so both have to be explained.
+ const found = try analyser.getSymbolFieldAccesses(arena, handle, off, held, name) orelse {
+ tr.note("STOP: could not resolve the left side to a type at all", .{});
+ explainFieldMiss(tr, offsets.locToSlice(tree.source, loc));
+ return;
+ };
+ if (found.len == 0) {
+ tr.note("STOP: the left side resolved, but nothing named `{s}` was found on it", .{name});
+ explainFieldMiss(tr, offsets.locToSlice(tree.source, loc));
+ return;
+ }
try decls.appendSlice(arena, found);
},
.label_access, .label_decl => {
@@ -266,23 +576,43 @@ fn goto(
const loc = ctx.stringLiteralContentLoc(tree.source);
if (loc.start == loc.end) return;
const str = offsets.locToSlice(tree.source, loc);
+ tr.note("import string: \"{s}\"", .{str});
const res = try analyser.store.uriFromImportStr(arena, handle, str);
switch (res) {
- .none => return,
- .one => |u| lsp.row(gpa, out, u.toFsPath(arena) catch return, 0, 0, str),
- .many => |us| for (us) |u| lsp.row(gpa, out, u.toFsPath(arena) catch continue, 0, 0, str),
+ .none => {
+ // ZLS gave up, which for a DEPENDENCY name is not a real
+ // dead end — it just means it wanted the module graph and
+ // we would not start a compiler to get one. Our build.zig
+ // knows the graph and baked it in; consult that.
+ if (moduleRoot(str)) |path| {
+ tr.note("`{s}` is a build.zig dependency; resolved from the compiled-in module map", .{str});
+ lsp.row(out, path, 0, 0, str);
+ return;
+ }
+ tr.note("STOP: `{s}` does not resolve to a file. Relative paths, `std` and this", .{str});
+ tr.note(" build's own dependencies work; `builtin`, `root` and a dependency's", .{});
+ tr.note(" OWN internal module names need the build graph we do not run.", .{});
+ return;
+ },
+ .one => |u| lsp.row(out, u.toFsPath(arena) catch return, 0, 0, str),
+ .many => |us| for (us) |u| lsp.row(out, u.toFsPath(arena) catch continue, 0, 0, str),
}
return;
},
- else => return,
+ else => {
+ tr.note("STOP: nothing to resolve in a .{s} context — `gd` only answers on", .{@tagName(ctx)});
+ tr.note(" an identifier, a field access, a label, an enum literal or an @import string.", .{});
+ return;
+ },
}
+ tr.note("resolved to {d} declaration(s); asking each for its {s} token", .{ decls.items.len, @tagName(kind) });
// One decl that fails to resolve must not swallow the others: a field
// access can name several and a partial answer beats none.
for (decls.items) |d| {
switch (kind) {
- .declaration => try rowForToken(gpa, arena, d.definitionToken(analyser, false) catch continue, out),
- .definition => try rowForToken(gpa, arena, d.definitionToken(analyser, true) catch continue, out),
+ .declaration => try rowForToken(arena, d.definitionToken(analyser, false) catch continue, out),
+ .definition => try rowForToken(arena, d.definitionToken(analyser, true) catch continue, out),
.type_definition => {
// peel error unions / pointers / optionals the way ZLS does,
// then take the container's own name token
@@ -294,7 +624,7 @@ fn goto(
try analyser.resolveOptionalUnwrap(r) orelse break;
}
if (r.typeDefinitionToken()) |th| {
- try rowForToken(gpa, arena, th, out);
+ try rowForToken(arena, th, out);
continue;
}
}
@@ -302,7 +632,7 @@ fn goto(
const t2 = &nd.handle.tree;
const rr = offsets.nodeToRange(t2, nd.node, enc);
const path = nd.handle.uri.toFsPath(arena) catch continue;
- lsp.row(gpa, out, path, rr.start.line, rr.start.character, lineAt(t2.source, rr.start.line));
+ lsp.row(out, path, rr.start.line, rr.start.character, lineAt(t2.source, rr.start.line));
},
}
}
@@ -315,12 +645,11 @@ fn goto(
/// as lines and nothing arms the n/N stepper. Fenced-code markers are dropped
/// because a plain-text pane has nothing to do with them.
fn hover(
- gpa: std.mem.Allocator,
arena: std.mem.Allocator,
analyser: *Analyser,
handle: *DocumentStore.Handle,
off: usize,
- out: *std.ArrayList(u8),
+ out: *std.Io.Writer,
) !void {
const h = try zls.hover.hover(analyser, arena, handle, off, .markdown, enc) orelse return;
const text = switch (h.contents) {
@@ -330,7 +659,7 @@ fn hover(
var it = std.mem.splitScalar(u8, text, '\n');
while (it.next()) |ln| {
if (std.mem.startsWith(u8, ln, "```")) continue;
- out.print(gpa, "{s}\n", .{std.mem.trimEnd(u8, ln, " \t\r")}) catch return;
+ out.print("{s}\n", .{std.mem.trimEnd(u8, ln, " \t\r")}) catch return;
}
}
@@ -344,7 +673,7 @@ fn documentSymbols(
arena: std.mem.Allocator,
path: []const u8,
tree: *const Ast,
- out: *std.ArrayList(u8),
+ out: *std.Io.Writer,
) !void {
const syms = try zls.document_symbol.getDocumentSymbols(arena, tree, enc);
var n: usize = 0;
@@ -361,7 +690,7 @@ fn emitSymbols(
syms: []const types.DocumentSymbol,
prefix: []const u8,
n: *usize,
- out: *std.ArrayList(u8),
+ out: *std.Io.Writer,
) !void {
for (syms) |s| {
if (n.* >= max_rows) return;
@@ -374,7 +703,7 @@ fn emitSymbols(
try std.fmt.allocPrint(arena, "{s} {s}", .{ name, d })
else
name;
- lsp.row(gpa, out, path, s.selectionRange.start.line, s.selectionRange.start.character, text);
+ lsp.row(out, path, s.selectionRange.start.line, s.selectionRange.start.character, text);
if (s.children) |kids| try emitSymbols(gpa, arena, path, kids, name, n, out);
}
}
@@ -389,7 +718,7 @@ fn workspaceSymbols(
arena: std.mem.Allocator,
io: std.Io,
req: lsp.Req,
- out: *std.ArrayList(u8),
+ out: *std.Io.Writer,
) !void {
if (req.arg.len == 0) return;
var files: std.ArrayList([]const u8) = .empty;
@@ -413,7 +742,7 @@ fn filterSymbols(
prefix: []const u8,
needle: []const u8,
n: *usize,
- out: *std.ArrayList(u8),
+ out: *std.Io.Writer,
) !void {
for (syms) |s| {
if (n.* >= max_rows) return;
@@ -423,7 +752,7 @@ fn filterSymbols(
try std.fmt.allocPrint(arena, "{s}.{s}", .{ prefix, s.name });
if (containsIgnoreCase(s.name, needle)) {
n.* += 1;
- lsp.row(gpa, out, path, s.selectionRange.start.line, s.selectionRange.start.character, name);
+ lsp.row(out, path, s.selectionRange.start.line, s.selectionRange.start.character, name);
}
if (s.children) |kids| try filterSymbols(gpa, arena, path, kids, name, needle, n, out);
}
@@ -459,13 +788,12 @@ fn containsIgnoreCase(hay: []const u8, needle: []const u8) bool {
/// with the replacement. The seam returns rows, not edits, so `SPC r` shows
/// what would change and changes nothing — an honest half of rename.
fn references(
- gpa: std.mem.Allocator,
arena: std.mem.Allocator,
analyser: *Analyser,
handle: *DocumentStore.Handle,
off: usize,
new_name: ?[]const u8,
- out: *std.ArrayList(u8),
+ out: *std.Io.Writer,
) !void {
const tree = &handle.tree;
const target = try declAt(arena, analyser, handle, off) orelse return;
@@ -496,7 +824,7 @@ fn references(
try std.fmt.allocPrint(arena, "{s} -> {s} {s}", .{ want, nn, std.mem.trim(u8, lines.line(r.start.line), " \t") })
else
lines.line(r.start.line);
- lsp.row(gpa, out, handle.uri.toFsPath(arena) catch return, r.start.line, r.start.character, text);
+ lsp.row(out, handle.uri.toFsPath(arena) catch return, r.start.line, r.start.character, text);
}
}
@@ -541,10 +869,10 @@ fn diagnostics(
arena: std.mem.Allocator,
path: []const u8,
tree: *const Ast,
- out: *std.ArrayList(u8),
+ out: *std.Io.Writer,
) !void {
const n = try treeDiagnostics(gpa, arena, path, tree, out);
- if (n == 0) lsp.row(gpa, out, path, 0, 0, "no diagnostics");
+ if (n == 0) lsp.row(out, path, 0, 0, "no diagnostics");
}
/// `zig ast-check`, in this process. ZLS spawns the compiler for this when it
@@ -569,7 +897,7 @@ fn treeDiagnostics(
arena: std.mem.Allocator,
path: []const u8,
tree: *const Ast,
- out: *std.ArrayList(u8),
+ out: *std.Io.Writer,
) !usize {
var n: usize = 0;
if (tree.errors.len != 0) {
@@ -582,7 +910,7 @@ fn treeDiagnostics(
const at = tree.tokenStart(e.token);
const lc = lsp.lineCol(tree.source, at);
n += 1;
- lsp.row(gpa, out, path, lc.line, lc.col, try std.fmt.allocPrint(arena, "error: {s} {s}", .{
+ lsp.row(out, path, lc.line, lc.col, try std.fmt.allocPrint(arena, "error: {s} {s}", .{
w.written(), std.mem.trim(u8, lines.line(lc.line), " \t"),
}));
}
@@ -598,7 +926,7 @@ fn treeDiagnostics(
if (em.src_loc == .none) continue;
const sl = bundle.getSourceLocation(em.src_loc);
n += 1;
- lsp.row(gpa, out, path, sl.line, sl.column, try std.fmt.allocPrint(arena, "error: {s}", .{
+ lsp.row(out, path, sl.line, sl.column, try std.fmt.allocPrint(arena, "error: {s}", .{
bundle.nullTerminatedString(em.msg),
}));
}
@@ -614,7 +942,7 @@ fn workspaceDiagnostics(
arena: std.mem.Allocator,
io: std.Io,
req: lsp.Req,
- out: *std.ArrayList(u8),
+ out: *std.Io.Writer,
) !void {
var files: std.ArrayList([]const u8) = .empty;
try collectZigFiles(arena, io, req.root, &files);
@@ -626,7 +954,7 @@ fn workspaceDiagnostics(
total += treeDiagnostics(gpa, arena, path, &tree, out) catch continue;
if (total >= max_rows) return;
}
- if (total == 0) lsp.row(gpa, out, req.path, 0, 0, try std.fmt.allocPrint(arena, "no diagnostics in {d} file(s)", .{files.items.len}));
+ if (total == 0) lsp.row(out, req.path, 0, 0, try std.fmt.allocPrint(arena, "no diagnostics in {d} file(s)", .{files.items.len}));
}
// ----------------------------------------------------------- code actions
@@ -644,11 +972,11 @@ fn codeActions(
analyser: *Analyser,
handle: *DocumentStore.Handle,
off: usize,
- out: *std.ArrayList(u8),
+ out: *std.Io.Writer,
) !void {
const tree = &handle.tree;
if (tree.errors.len != 0) {
- out.print(gpa, "no code actions: file does not parse\n", .{}) catch {};
+ out.print("no code actions: file does not parse\n", .{}) catch {};
return;
}
var bundle = try astCheck(gpa, "", tree);
@@ -666,9 +994,9 @@ fn codeActions(
builder.generateCodeActionsInRange(at) catch {};
for (builder.actions.items) |a| {
- out.print(gpa, "{s}\n", .{a.title}) catch return;
+ out.print("{s}\n", .{a.title}) catch return;
}
- if (builder.actions.items.len == 0) out.print(gpa, "no code actions\n", .{}) catch {};
+ if (builder.actions.items.len == 0) out.print("no code actions\n", .{}) catch {};
}
// ---------------------------------------------------------------- format
@@ -678,11 +1006,11 @@ fn codeActions(
/// row per line `zig fmt` would change, in the `+Lsp` buffer. That is the
/// honest shape of "format" behind a read-only seam, and it is still the
/// answer to the question the keypress asks.
-fn formatQuery(gpa: std.mem.Allocator, arena: std.mem.Allocator, req: lsp.Req, out: *std.ArrayList(u8)) !void {
+fn formatQuery(arena: std.mem.Allocator, req: lsp.Req, out: *std.Io.Writer) !void {
var tree: Ast = try .parse(arena, req.source, .zig);
defer tree.deinit(arena);
if (tree.errors.len != 0) {
- lsp.row(gpa, out, req.path, 0, 0, "cannot format: file does not parse");
+ lsp.row(out, req.path, 0, 0, "cannot format: file does not parse");
return;
}
var buf: std.ArrayList(u8) = .empty;
@@ -690,7 +1018,7 @@ fn formatQuery(gpa: std.mem.Allocator, arena: std.mem.Allocator, req: lsp.Req, o
tree.render(arena, &w.writer, .{}) catch return;
const formatted = w.written();
if (std.mem.eql(u8, formatted, req.source)) {
- lsp.row(gpa, out, req.path, 0, 0, "already formatted");
+ lsp.row(out, req.path, 0, 0, "already formatted");
return;
}
var a = std.mem.splitScalar(u8, req.source, '\n');
@@ -705,7 +1033,7 @@ fn formatQuery(gpa: std.mem.Allocator, arena: std.mem.Allocator, req: lsp.Req, o
const ys = y orelse "";
if (std.mem.eql(u8, xs, ys)) continue;
n += 1;
- lsp.row(gpa, out, req.path, ln, 0, try std.fmt.allocPrint(arena, "- {s} + {s}", .{
+ lsp.row(out, req.path, ln, 0, try std.fmt.allocPrint(arena, "- {s} + {s}", .{
std.mem.trim(u8, xs, " \t"), std.mem.trim(u8, ys, " \t"),
}));
}
diff --git a/src/pardes.zig b/src/pardes.zig
index 682b0e3e..07120954 100644
--- a/src/pardes.zig
+++ b/src/pardes.zig
@@ -46,7 +46,7 @@ pub const swap_enter_tab = false;
// each other: they are one pair — Find matches file NAMES, Grep their CONTENTS
// — and every word's start column is what a topbar click dispatches on, so
// appending is the edit that leaves the bar people already know where it was.
-pub const topbar_str = "Kill Newcol Tutor Debug NextColor Dump Find Grep";
+pub const topbar_str = "Kill Newcol Tutor Debug NextColor Dump Find Grep Help";
const pane_builtins_str = "Del";
const file_pane_builtins_str = "Save Del";
const pane_tail = " " ++ pane_builtins_str;
@@ -100,13 +100,12 @@ const Builtin = enum {
Up,
Right,
Toggleterm,
- // The language group. Every one of these is a helix `<space>` command and
- // keeps helix's key; the pardes builtins that used to sit on k/d/s moved
- // (see leader_path). They are builtins rather than bare keys for the same
- // reason Save is one: the word is executable wherever it appears, so a
- // middle-click on `Hover` in a tag does what SPC k does. The five GOTOS
- // are not here — helix binds them under `g` as motions, and a motion has
- // no business being a word you can click.
+ // The language group, reached as `SPC l <helix's letter>` — see
+ // leader_path for why the prefix exists. They are builtins rather than
+ // bare keys for the same reason Save is one: the word is executable
+ // wherever it appears, so a middle-click on `Hover` in a tag does what
+ // `SPC l k` does. The five GOTOS are not here — helix binds them under `g`
+ // as motions, and a motion has no business being a word you can click.
Hover,
Rename,
CodeAction,
@@ -115,38 +114,54 @@ const Builtin = enum {
WsSymbols,
Diagnostics,
WsDiagnostics,
+ // Introspection. A language backend that answers nothing looks exactly
+ // like one that is broken — from the outside, `gd` doing nothing is both
+ // "there is no definition" and "the analyser threw and we swallowed it".
+ // These two are how you tell: Lspinfo says what the backend IS, Lspwhy
+ // says what it just DID and where it stopped.
+ Lspinfo,
+ Lspwhy,
};
/// SPC leader: ONE key path per builtin, the whole remapping surface. An
/// EnumArray, so a new enum field is a compile error until it has a path.
/// Groups are just shared first letters (f files, h docs, c columns, t
-/// toggles, s session); `?` is Help's path and is honored at ANY depth — it
-/// lists what the prefix typed so far can still reach.
+/// toggles, s session, l language); `?` is Help's path and is honored at ANY
+/// depth — it lists what the prefix typed so far can still reach.
const leader_path = std.EnumArray(Builtin, []const u8).init(.{
.Help = "?",
- // HELIX OWNS THESE EIGHT LETTERS. The LSP commands keep the exact keys
- // helix gives them, which is the whole point of pardes's modal layer being
- // helix's — a muscle-memory map with three exceptions is not a map. What
- // moved is ours: Kill k->q, Del d->wc (it closes a window, and helix's
- // window group already spells close `c`), Dump/Restore s?->f? (writing and
- // reading a session file is a FILE operation), Tutor ht->T (freeing `h`).
- .Hover = "k",
- .Rename = "r",
- .CodeAction = "a",
- .SelectRefs = "h",
- .Symbols = "s",
- .WsSymbols = "S",
- .Diagnostics = "d",
- .WsDiagnostics = "D",
- .Kill = "q",
- .Tutor = "T",
+ // The whole LANGUAGE group lives under `l`, and pardes's own builtins keep
+ // the letters they always had — `SPC d` is Del, `SPC k` is Kill.
+ //
+ // Helix puts these on bare `<space>` letters, and an earlier pass followed
+ // it there, which cost `d`, `k`, `s`, `h` and the session group. That is
+ // the wrong trade: those five 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 more keystroke. Each one still keeps
+ // HELIX'S OWN LETTER inside the group, so the mapping is `<space>X` ->
+ // `SPC l X` with nothing to re-learn but the prefix.
+ //
+ // The five GOTOS are untouched and remain exactly helix's — `gd` `gD` `gy`
+ // `gi` `gr`, plus `]d`/`[d` and `=`. Those never collided with anything, so
+ // there was never a reason to move them.
+ .Hover = "lk",
+ .Rename = "lr",
+ .CodeAction = "la",
+ .SelectRefs = "lh",
+ .Symbols = "ls",
+ .WsSymbols = "lS",
+ .Diagnostics = "ld",
+ .WsDiagnostics = "lD",
+ .Lspinfo = "li",
+ .Lspwhy = "lw",
+ .Del = "d",
+ .Kill = "k",
// the `f` file group (spacemacs): Save left vim's `w` to join Find here,
// which frees `w` for the window group (SPC w h/j/k/l) to move into.
.Save = "fs",
.Find = "ff",
.Grep = "fg",
- .Dump = "fd",
- .Restore = "fr",
+ .Tutor = "ht",
.Newcol = "cn",
.Delcol = "cd",
.Debug = "td",
@@ -158,16 +173,16 @@ const leader_path = std.EnumArray(Builtin, []const u8).init(.{
.Petscii = "tp",
.Palette = "tl",
.Ascii = "ta",
+ .Dump = "sd",
+ .Restore = "sr",
// the `w` window group `Save` vacated: the four directional focus moves
// the Ctrl-w prefix does, spelled h/j/k/l because focus IS a motion, plus
- // `t` for the file<->terminal hop and `c` for close (helix's own spelling
- // in its window mode, and where Del landed when `d` went to diagnostics).
+ // `t` for the file<->terminal hop.
.Left = "wh",
.Down = "wj",
.Up = "wk",
.Right = "wl",
.Toggleterm = "wt",
- .Del = "wc",
});
/// The leader tree, flattened: one row per builtin SORTED BY PATH, so every
@@ -218,6 +233,15 @@ const leader_rows: [@typeInfo(Builtin).@"enum".fields.len]Leader = blk: {
// forget, and a bar you read every frame should not spend width on them now
// that `SPC t c` / `SPC t r` press them. NextColor stays — it is the one you
// cycle repeatedly, so a click beats a three-key path.
+//
+// Help is LAST and is the one word that has to be here. A bare `pardes` boots
+// straight into tty mode (main.zig: `args.len == 1`), where every printable
+// key belongs to the shell — so SPC never reaches the leader and `SPC ?`, the
+// thing that would tell you the leader exists, is exactly what you cannot
+// press. Row 0 is not a pane, so a middle-click on it is dispatched before any
+// pane's mode is consulted: this word works in tty mode, which is the only
+// reason it earns the width. Appended rather than inserted so every existing
+// word keeps its column and no golden's click coordinates move.
comptime {
@setEvalBranchQuota(8000); // the tokenizer walks the string one branch per byte, stringToEnum builds a map per name
var it = std.mem.tokenizeScalar(u8, topbar_str, ' ');
@@ -517,6 +541,11 @@ pub const Mouse = struct {
kind: Kind,
col: u16,
row: u16,
+ /// Ctrl held during the click. Only the left press reads it (ctrl-click =
+ /// goto-definition, the one chord every editor with an LSP has); every
+ /// other button ignores it, because acme's button semantics are already
+ /// the vocabulary here and modifiers are not part of it.
+ ctrl: bool = false,
};
pub const Key = struct {
@@ -821,7 +850,7 @@ pub const Pane = struct {
reply: [256]u8 = undefined,
reply_len: u16 = 0,
- fn cwdSlice(p: *const Pane) []const u8 {
+ pub fn cwdSlice(p: *const Pane) []const u8 {
return p.cwd[0..p.cwd_len];
}
@@ -930,7 +959,7 @@ const Drag = union(enum) {
tag: struct { id: usize },
/// chorded: a 1-2/1-3 cut/paste chord fired during this left drag —
/// the drag's own release is then inert
- select: struct { id: usize, button: Mouse.Button, chorded: bool = false },
+ select: struct { id: usize, button: Mouse.Button, chorded: bool = false, ctrl: bool = false },
};
const Rect = struct { x: u16, y: u16, w: u16, h: u16 };
@@ -2899,13 +2928,20 @@ pub const Pardes = struct {
fn lspRequest(p: *Pardes, id: usize, kind: lsp.Kind, arg: []const u8) void {
if (!lsp.supports.contains(kind)) return;
const pane = p.panes[id] orelse return;
- const f = pane.file orelse return;
- if (f.output) return;
+ // `status` is about the BACKEND, not about a document, so it answers
+ // from ANY pane — a terminal, a +Search, anywhere. That matters
+ // precisely when the pane you are sitting in is the thing going wrong.
+ // Every other kind needs a real file: a terminal's rows are a
+ // program's output and an output buffer is our own text.
+ if (kind != .status) {
+ const f = pane.file orelse return;
+ if (f.output) return;
+ }
if (arg.len > 128) return; // the effect's arg is a Buf(128)
- const off = modal.hxOff(f.content, .{
+ const off = if (pane.file) |f| modal.hxOff(f.content, .{
.row = @intCast(@max(0, pane.cur_row)),
.col = @intCast(@max(0, pane.cur_col)),
- });
+ }) else 0;
p.lsp_seq +%= 1;
p.lsp_wait = .{ .id = p.lsp_seq, .kind = kind, .pane = id };
p.emit(.{ .lsp = .{
@@ -4383,7 +4419,11 @@ pub const Pardes = struct {
const sc: i32 = @as(i32, mcol) - @as(i32, r.x + GUTTER);
const v: i32 = @as(i32, mrow) - @as(i32, r.y);
pane.sel[0] = .{ .state = .dragging, .c0 = sc, .c1 = sc, .r0 = v, .r1 = v };
- p.drag = .{ .select = .{ .id = id, .button = .left } };
+ // Ctrl rides on the drag rather than firing here: the
+ // click does not place the modal cursor until RELEASE
+ // (dragRelease), and a goto asked at press time would
+ // answer about wherever the cursor happened to be.
+ p.drag = .{ .select = .{ .id = id, .button = .left, .ctrl = m.ctrl } };
}
},
.drag => p.dragUpdate(mcol, mrow),
@@ -4564,6 +4604,12 @@ pub const Pardes = struct {
// dismisses it rather than dragging the anchored span
// to the click (explicit v/x keeps vim's click-extend)
if (!pane.vsel.explicit) pane.vsel.active = false;
+ // Ctrl-click IS `gd`, asked now that the cursor has
+ // landed — the mouse spelling of the keyboard motion,
+ // through the identical request. A ctrl-DRAG still
+ // selects and still asks, about where it started,
+ // which is the same thing `gd` would answer.
+ if (s.ctrl) p.lspRequest(s.id, .definition, "");
}
} else {
// acme execute (middle) / look (right): a no-drag click
@@ -5269,6 +5315,8 @@ pub const Pardes = struct {
.Symbols => p.lspRequest(id, .document_symbols, ""),
.Diagnostics => p.lspRequest(id, .diagnostics, ""),
.WsDiagnostics => p.lspRequest(id, .workspace_diagnostics, ""),
+ .Lspinfo => p.lspRequest(id, .status, ""),
+ .Lspwhy => p.lspRequest(id, .explain, ""),
// The two that need a word from the user, handled exactly the way
// Find and Grep are: an argument means run it now (a selection
// chorded onto the name), no argument arms the tag input and Enter
diff --git a/src/tty.zig b/src/tty.zig
index 818d8b48..6b43acd3 100644
--- a/src/tty.zig
+++ b/src/tty.zig
@@ -232,6 +232,7 @@ pub fn run(init: std.process.Init, opts: pardes.Options) !void {
},
.col = @intCast(m.col),
.row = @intCast(m.row),
+ .ctrl = m.mods.ctrl,
} });
},
.paste => |bytes| {
@@ -417,18 +418,19 @@ fn drainEffects(
.lsp => |q| {
if (!threads_ok) continue; // pre-loop drain: nothing to answer to yet
const pane = core.panes[q.pane] orelse continue;
- const f = pane.file orelse continue;
- // snapshot everything the worker may read (see LspJob)
+ // a pane with no file still asks `status` (it is about the backend,
+ // not the buffer): empty path and source, root from the pane's cwd
+ const f = pane.file;
const job = gpa.create(LspJob) catch continue;
job.* = .{
.id = q.id,
.kind = q.kind,
.offset = q.offset,
- .path = gpa.dupe(u8, f.path) catch {
+ .path = gpa.dupe(u8, if (f) |ff| ff.path else "") catch {
gpa.destroy(job);
continue;
},
- .source = gpa.dupeZ(u8, f.content) catch {
+ .source = gpa.dupeZ(u8, if (f) |ff| ff.content else "") catch {
gpa.free(job.path);
gpa.destroy(job);
continue;
@@ -439,7 +441,7 @@ fn drainEffects(
gpa.destroy(job);
continue;
},
- .root = gpa.dupe(u8, std.fs.path.dirname(f.path) orelse "/") catch {
+ .root = gpa.dupe(u8, if (f) |ff| (std.fs.path.dirname(ff.path) orelse "/") else pane.cwdSlice()) catch {
gpa.free(job.path);
gpa.free(job.source);
gpa.free(job.arg);
@@ -473,8 +475,9 @@ fn lspWorker(gpa: std.mem.Allocator, job: *LspJob, loop: *Loop) anyerror!void {
defer job.free(gpa);
var arena: std.heap.ArenaAllocator = .init(gpa);
defer arena.deinit();
- var out: std.ArrayList(u8) = .empty;
- defer out.deinit(gpa);
+ // the shell owns the result buffer; the backend only ever writes to it
+ var out: std.Io.Writer.Allocating = .init(gpa);
+ defer out.deinit();
pardes.lsp.query(gpa, arena.allocator(), .{
.kind = job.kind,
.path = job.path,
@@ -482,8 +485,8 @@ fn lspWorker(gpa: std.mem.Allocator, job: *LspJob, loop: *Loop) anyerror!void {
.offset = job.offset,
.arg = job.arg,
.root = job.root,
- }, &out);
- const rows = gpa.dupe(u8, out.items) catch return;
+ }, &out.writer);
+ const rows = gpa.dupe(u8, out.written()) catch return;
loop.postEvent(.{ .lsp_done = .{ .id = job.id, .rows = rows } }) catch gpa.free(rows);
return;
}
diff --git a/test/lspbench.zig b/test/lspbench.zig
index 307bdc49..9eddf2f0 100644
--- a/test/lspbench.zig
+++ b/test/lspbench.zig
@@ -81,7 +81,9 @@ const anchors = [_]Anchor{
.{ .file = "test/lspfixture/broken.zig", .needle = "unused_local", .at = 0, .kind = .diagnostics, .expect = "broken.zig" },
// the remaining kinds, probed once each so the matrix is complete
.{ .file = "src/lsp.zig", .needle = "lineCol(source", .at = 0, .kind = .declaration, .expect = "" },
- .{ .file = "src/lsp.zig", .needle = "out: *std.ArrayList(u8)", .at = 10, .kind = .type_definition, .expect = "" },
+ // cursor on `out`, whose type is `*std.Io.Writer` — a type_definition probe
+ // wants a NAME whose type must be resolved, not the type spelled out
+ .{ .file = "src/lsp.zig", .needle = "out: *std.Io.Writer", .at = 0, .kind = .type_definition, .expect = "" },
.{ .file = "src/lsp.zig", .needle = "pub const Kind", .at = 11, .kind = .implementation, .expect = "" },
.{ .file = "src/lsp.zig", .needle = "pub const Kind", .at = 11, .kind = .select_refs, .expect = "" },
.{ .file = "test/lspfixture/broken.zig", .needle = "badly_spaced", .at = 0, .kind = .format, .expect = "" },
@@ -156,12 +158,12 @@ pub fn main(init: std.process.Init) !void {
std.mem.sort(u64, &samples, {}, std.sort.asc(u64));
r.warm_us = samples[warm_iters / 2];
r.correct = !r.empty and (an.expect.len == 0 or blk: {
- var out: std.ArrayList(u8) = .empty;
- defer out.deinit(gpa);
+ var out: std.Io.Writer.Allocating = .init(gpa);
+ defer out.deinit();
var arena: std.heap.ArenaAllocator = .init(gpa);
defer arena.deinit();
- lsp.query(gpa, arena.allocator(), req, &out);
- break :blk std.mem.indexOf(u8, out.items, an.expect) != null;
+ lsp.query(gpa, arena.allocator(), req, &out.writer);
+ break :blk std.mem.indexOf(u8, out.written(), an.expect) != null;
});
try results.append(gpa, r);
}
@@ -173,14 +175,14 @@ pub fn main(init: std.process.Init) !void {
fn runOnce(gpa: std.mem.Allocator, req: lsp.Req, r: *Result) u64 {
var arena: std.heap.ArenaAllocator = .init(gpa);
defer arena.deinit();
- var out: std.ArrayList(u8) = .empty;
- defer out.deinit(gpa);
+ var out: std.Io.Writer.Allocating = .init(gpa);
+ defer out.deinit();
const t0 = nowNs();
- lsp.query(gpa, arena.allocator(), req, &out);
+ lsp.query(gpa, arena.allocator(), req, &out.writer);
const ns = nowNs() -| t0;
- if (out.items.len > 0) {
+ if (out.written().len > 0) {
r.empty = false;
- r.rows = std.mem.count(u8, out.items, "\n");
+ r.rows = std.mem.count(u8, out.written(), "\n");
}
return ns / 1000;
}
diff --git a/test/snapshot.zig b/test/snapshot.zig
index 31f2c8ea..aeb01187 100644
--- a/test/snapshot.zig
+++ b/test/snapshot.zig
@@ -40,7 +40,7 @@
// parses it as alt-<ch>. The scripts said 700ms and
// it cost the suite 28s; there is no timer in vaxis
// to outlast — 20ms passes, they use 100ms)
-// press|release <left|middle|right> <col> <row> SGR mouse, 1-based
+// press|release <[ctrl-]left|middle|right> <col> <row> SGR mouse, 1-based
// drag <btn> <col> <row> motion with button held
// motion <col> <row> button-less motion (hover)
// wheel <up|down> <col> <row>
@@ -307,6 +307,9 @@ fn runScript(arena: std.mem.Allocator, exe_z: [:0]const u8, script_path: []const
_ = setenv("HOME", try arena.dupeZ(u8, home), 1);
_ = setenv("TERM", "xterm-256color", 1);
_ = setenv("LC_ALL", "C", 1);
+ // durations cannot live in a golden; the lsp introspection views print
+ // `-` for them when this is set (see lsp_zls.zig hideTime)
+ _ = setenv("PARDES_LSP_NOTIME", "1", 1);
// Pin the dump path: live runs use a timestamped file under the user data
// dir (dump.outPath), which would make the dump/load/restore goldens
// nondeterministic. Per-SCRIPT, not one shared /tmp/pardes-dump.zon: four
@@ -722,10 +725,10 @@ fn colorStr(color: ghostty_vt.Style.Color, buf: *[16]u8) []const u8 {
fn keyBytes(name: []const u8) ?[]const u8 {
const map = .{
- .{ "enter", "\r" }, .{ "esc", "\x1b" }, .{ "tab", "\t" },
- .{ "bs", "\x7f" }, .{ "space", " " }, .{ "up", "\x1b[A" },
- .{ "down", "\x1b[B" }, .{ "right", "\x1b[C" }, .{ "left", "\x1b[D" },
- .{ "home", "\x1b[H" }, .{ "end", "\x1b[F" }, .{ "pgup", "\x1b[5~" },
+ .{ "enter", "\r" }, .{ "esc", "\x1b" }, .{ "tab", "\t" },
+ .{ "bs", "\x7f" }, .{ "space", " " }, .{ "up", "\x1b[A" },
+ .{ "down", "\x1b[B" }, .{ "right", "\x1b[C" }, .{ "left", "\x1b[D" },
+ .{ "home", "\x1b[H" }, .{ "end", "\x1b[F" }, .{ "pgup", "\x1b[5~" },
.{ "pgdn", "\x1b[6~" },
};
inline for (map) |e| if (std.mem.eql(u8, name, e[0])) return e[1];
@@ -749,7 +752,14 @@ fn keyBytes(name: []const u8) ?[]const u8 {
return null;
}
+/// SGR button code, with an optional `ctrl-` prefix folded in as bit 4 —
+/// which is exactly how a terminal encodes a modified click, and how vaxis
+/// decodes one (Parser.zig mouse_bits.ctrl = 0b00010000).
fn buttonCode(name: []const u8) ?u16 {
+ if (std.mem.startsWith(u8, name, "ctrl-")) {
+ const base = buttonCode(name["ctrl-".len..]) orelse return null;
+ return base + 16;
+ }
if (std.mem.eql(u8, name, "left")) return 0;
if (std.mem.eql(u8, name, "middle")) return 1;
if (std.mem.eql(u8, name, "right")) return 2;
diff --git a/test/snapshots/argv.golden b/test/snapshots/argv.golden
index 812740ac..35d36b88 100644
--- a/test/snapshots/argv.golden
+++ b/test/snapshots/argv.golden
@@ -1,5 +1,5 @@
== snap noargs grid=100x30 cursor=4,4
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| TTY /tmp/pardes-snap/argv/cwd Del
| $ echo ARGV''TTY
| ARGVTTY
@@ -30,7 +30,7 @@
|
|
== snap filearg grid=100x30 cursor=7,2
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/argv/cwd/notes.txt Save Del NOR /tmp/pardes-snap/argv/cwd Del
| 3 line 3
| 4 line 4 notes.txt zmarker.txt
@@ -61,7 +61,7 @@
|
|
== snap dirarg grid=100x30 cursor=4,4
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/argv/cwd/sub Del
|
| inside.txt
diff --git a/test/snapshots/badutf.golden b/test/snapshots/badutf.golden
index 452ad825..1a5eb6e1 100644
--- a/test/snapshots/badutf.golden
+++ b/test/snapshots/badutf.golden
@@ -1,5 +1,5 @@
== snap badbytes grid=100x30 cursor=7,2
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/badutf/cwd/bad.txt Save Del NOR /tmp/pardes-snap/badutf/cwd Del
| 1 hello �� world
| 2 latin-1 caf� tail bad.txt wide.txt
@@ -30,7 +30,7 @@
|
|
== snap hscroll-midglyph grid=100x30 cursor=46,2
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/badutf/cwd/wide.txt Save De NOR /tmp/pardes-snap/badutf/cwd Del
| 1 ��語 日本語 日本語 日本語 tail
| 2 bad.txt wide.txt
diff --git a/test/snapshots/boot.golden b/test/snapshots/boot.golden
index d6be06fa..f0918225 100644
--- a/test/snapshots/boot.golden
+++ b/test/snapshots/boot.golden
@@ -1,5 +1,5 @@
== snap boot grid=100x30 cursor=4,4
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/boot/cwd Del
|
| hello.txt
@@ -30,7 +30,7 @@
|
|
== style boot
-|0: 0-47 #949494,#121212, 48-99 d,#121212,
+|0: 0-52 #949494,#121212, 53-99 d,#121212,
|1: 0-1 d,#626262, 2-34 #949494,#121212, 35-99 d,#121212,
|2: 0-1 d,#444444, 2-99 #bdbdbd,#080808,
|3: 0-1 d,#444444, 2-99 #bdbdbd,#080808,
diff --git a/test/snapshots/chordcut.golden b/test/snapshots/chordcut.golden
index 6f2da745..a07145b3 100644
--- a/test/snapshots/chordcut.golden
+++ b/test/snapshots/chordcut.golden
@@ -1,5 +1,5 @@
== snap opened grid=90x30 cursor=7,2
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/chordcu NOR /tmp/pardes-snap/chordcu NOR /tmp/pardes-snap/chordcu
| 1 line 1
| 2 line 2 f.txt g.txt f.txt g.txt
@@ -30,7 +30,7 @@
|
|
== snap cut grid=90x30 cursor=7,3
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/chordcu NOR /tmp/pardes-snap/chordcu NOR /tmp/pardes-snap/chordcu
| 1 line 1
| 2 2 f.txt g.txt f.txt g.txt
@@ -61,7 +61,7 @@
|
|
== snap copied grid=90x30 cursor=10,4
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/chordcu NOR /tmp/pardes-snap/chordcu NOR /tmp/pardes-snap/chordcu
| 1 line 1
| 2 2 f.txt g.txt f.txt g.txt
@@ -92,7 +92,7 @@
|
|
== snap pointpaste grid=90x30 cursor=16,5
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/chordcu NOR /tmp/pardes-snap/chordcu NOR /tmp/pardes-snap/chordcu
| 1 line 1
| 2 2 f.txt g.txt f.txt g.txt
@@ -123,7 +123,7 @@
|
|
== snap replaced grid=90x30 cursor=11,6
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/chordcu NOR /tmp/pardes-snap/chordcu NOR /tmp/pardes-snap/chordcu
| 1 line 1
| 2 2 f.txt g.txt f.txt g.txt
@@ -154,7 +154,7 @@
|
|
== snap cancelexec grid=90x30 cursor=25,3
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/chordcu NOR /tmp/pardes-snap/chordcu NOR /tmp/pardes-snap/chordcu
| 1 line 1
| 2 2echo B''OO g.txt f.txt g.txt f.txt g.txt
@@ -185,7 +185,7 @@
|
|
== snap execafter grid=90x30 cursor=25,3
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/chordcu NOR /tmp/pardes-snap/chordcu NOR /tmp/pardes-snap/chordcu
| 1 line 1
| 2 2echo B''OO g.txt f.txt g.txt f.txt g.txt
@@ -216,7 +216,7 @@
|
|
== snap cancellook grid=90x30 cursor=25,3
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/chordcu NOR /tmp/pardes-snap/chordcu NOR /tmp/pardes-snap/chordcu
| 1 line 1
| 2 2echo B''OO g.txt f.txt g.txt f.txt g.txt
@@ -247,7 +247,7 @@
|
|
== snap lookafter grid=90x30 cursor=7,17
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/chordcu NOR /tmp/pardes-snap/chordcu NOR /tmp/pardes-snap/chordcu
| 1 line 1
| 2 2echo B''OO g.txt f.txt g.txt f.txt g.txt
@@ -278,7 +278,7 @@
|
|
== style chordsel
-|0: 0-47 #949494,#121212, 48-89 d,#121212,
+|0: 0-52 #949494,#121212, 53-89 d,#121212,
|1: 0-1 d,#626262, 2-29 #949494,#121212, 30-31 d,#262626, 32-59 #949494,#121212, 60-61 d,#262626, 62-89 #949494,#121212,
|2: 0-1 d,#444444, 2-6 #626262,#080808, 7-12 #bdbdbd,#080808, 13-29 d,#080808, 30-31 d,#444444, 32-59 #bdbdbd,#080808, 60-61 d,#444444, 62-89 #bdbdbd,#080808,
|3: 0-1 d,#444444, 2-6 #626262,#080808, 7-24 #bdbdbd,#080808, 25-29 d,#080808, 30-31 d,#444444, 32-59 #bdbdbd,#080808, 60-61 d,#444444, 62-89 #bdbdbd,#080808,
@@ -309,7 +309,7 @@
|28: 0-1 d,#444444, 2-6 #626262,#080808, 7-29 d,#080808, 30-31 d,#444444, 32-59 #bdbdbd,#080808, 60-61 d,#444444, 62-89 #bdbdbd,#080808,
|29: 0-1 d,#444444, 2-6 #626262,#080808, 7-29 d,#080808, 30-31 d,#444444, 32-59 #bdbdbd,#080808, 60-61 d,#444444, 62-89 #bdbdbd,#080808,
== style clickdismiss
-|0: 0-47 #949494,#121212, 48-89 d,#121212,
+|0: 0-52 #949494,#121212, 53-89 d,#121212,
|1: 0-1 d,#626262, 2-29 #949494,#121212, 30-31 d,#262626, 32-59 #949494,#121212, 60-61 d,#262626, 62-89 #949494,#121212,
|2: 0-1 d,#444444, 2-6 #626262,#080808, 7-12 #bdbdbd,#080808, 13-29 d,#080808, 30-31 d,#444444, 32-59 #bdbdbd,#080808, 60-61 d,#444444, 62-89 #bdbdbd,#080808,
|3: 0-1 d,#444444, 2-6 #626262,#080808, 7-24 #bdbdbd,#080808, 25-29 d,#080808, 30-31 d,#444444, 32-59 #bdbdbd,#080808, 60-61 d,#444444, 62-89 #bdbdbd,#080808,
@@ -340,7 +340,7 @@
|28: 0-1 d,#444444, 2-6 #626262,#080808, 7-29 d,#080808, 30-31 d,#444444, 32-59 #bdbdbd,#080808, 60-61 d,#444444, 62-89 #bdbdbd,#080808,
|29: 0-1 d,#444444, 2-6 #626262,#080808, 7-29 d,#080808, 30-31 d,#444444, 32-59 #bdbdbd,#080808, 60-61 d,#444444, 62-89 #bdbdbd,#080808,
== snap ttyprobe grid=90x30 cursor=44,13
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/chordcu TTY /tmp/pardes-snap/chordcu NOR /tmp/pardes-snap/chordcu
| 1 line 1 $ ls
| 2 2echo B''OO g.txt f.txt g.txt f.txt g.txt
@@ -371,7 +371,7 @@
|
|
== snap ttyprompt grid=90x30 cursor=38,15
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/chordcu TTY /tmp/pardes-snap/chordcu NOR /tmp/pardes-snap/chordcu
| 1 line 1 $ ls
| 2 2echo B''OO g.txt f.txt g.txt f.txt g.txt
diff --git a/test/snapshots/cursorline.golden b/test/snapshots/cursorline.golden
index aa24e77d..f7c0f9b8 100644
--- a/test/snapshots/cursorline.golden
+++ b/test/snapshots/cursorline.golden
@@ -1,5 +1,5 @@
== snap top grid=150x30 cursor=7,2
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/cursorline/cwd/cur.txt Save NOR /tmp/pardes-snap/cursorline/cwd Del NOR /tmp/pardes-snap/cursorline/cwd Del
| 1 line 1
| 2 line 2 cur.txt cur.txt
@@ -30,7 +30,7 @@
|
|
== style top
-|0: 0-47 #949494,#121212, 48-149 d,#121212,
+|0: 0-52 #949494,#121212, 53-149 d,#121212,
|1: 0-1 d,#626262, 2-49 #949494,#121212, 50-51 d,#262626, 52-90 #949494,#121212, 91-99 d,#121212, 100-101 d,#262626, 102-140 #949494,#121212, 141-149 d,#121212,
|2: 0-1 d,#444444, 2-6 #949494,#121212, 7-12 #bdbdbd,#080808, 13-49 d,#080808, 50-51 d,#444444, 52-99 #bdbdbd,#080808, 100-101 d,#444444, 102-149 #bdbdbd,#080808,
|3: 0-1 d,#444444, 2-6 #626262,#080808, 7-12 #bdbdbd,#080808, 13-49 d,#080808, 50-51 d,#444444, 52-99 #bdbdbd,#080808, 100-101 d,#444444, 102-149 #bdbdbd,#080808,
@@ -61,7 +61,7 @@
|28: 0-1 d,#444444, 2-6 #626262,#080808, 7-49 d,#080808, 50-51 d,#444444, 52-99 #bdbdbd,#080808, 100-101 d,#444444, 102-149 #bdbdbd,#080808,
|29: 0-1 d,#444444, 2-6 #626262,#080808, 7-49 d,#080808, 50-51 d,#444444, 52-99 #bdbdbd,#080808, 100-101 d,#444444, 102-149 #bdbdbd,#080808,
== snap down3 grid=150x30 cursor=7,5
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/cursorline/cwd/cur.txt Save NOR /tmp/pardes-snap/cursorline/cwd Del NOR /tmp/pardes-snap/cursorline/cwd Del
| 1 line 1
| 2 line 2 cur.txt cur.txt
@@ -92,7 +92,7 @@
|
|
== style down3
-|0: 0-47 #949494,#121212, 48-149 d,#121212,
+|0: 0-52 #949494,#121212, 53-149 d,#121212,
|1: 0-1 d,#626262, 2-49 #949494,#121212, 50-51 d,#262626, 52-90 #949494,#121212, 91-99 d,#121212, 100-101 d,#262626, 102-140 #949494,#121212, 141-149 d,#121212,
|2: 0-1 d,#444444, 2-6 #626262,#080808, 7-12 #bdbdbd,#080808, 13-49 d,#080808, 50-51 d,#444444, 52-99 #bdbdbd,#080808, 100-101 d,#444444, 102-149 #bdbdbd,#080808,
|3: 0-1 d,#444444, 2-6 #626262,#080808, 7-12 #bdbdbd,#080808, 13-49 d,#080808, 50-51 d,#444444, 52-99 #bdbdbd,#080808, 100-101 d,#444444, 102-149 #bdbdbd,#080808,
diff --git a/test/snapshots/dump.golden b/test/snapshots/dump.golden
index ce1c221d..338b574e 100644
--- a/test/snapshots/dump.golden
+++ b/test/snapshots/dump.golden
@@ -4,7 +4,7 @@
.version = 1,
.screen = .{ .cols = 100, .rows = 30 },
.active = 0,
- .topbar = "Kill Newcol Tutor Debug NextColor Dump Find Grep",
+ .topbar = "Kill Newcol Tutor Debug NextColor Dump Find Grep Help",
.theme = "helix",
.columns = .{ .{ .weight = 1, .panes = .{ 0, 1 } }, .{ .weight = 1, .panes = .{2} } },
.panes = .{
diff --git a/test/snapshots/edit.golden b/test/snapshots/edit.golden
index e3fd56d9..a52446d7 100644
--- a/test/snapshots/edit.golden
+++ b/test/snapshots/edit.golden
@@ -1,5 +1,5 @@
== snap inserted grid=100x30 cursor=16,9
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/edit/cwd Del NOR /tmp/pardes-snap/edit/cwd Del
|
| e.txt e.txt
@@ -30,7 +30,7 @@
|
|
== style inserted
-|0: 0-47 #949494,#121212, 48-99 d,#121212,
+|0: 0-52 #949494,#121212, 53-99 d,#121212,
|1: 0-1 d,#626262, 2-34 #949494,#121212, 35-49 d,#121212, 50-51 d,#262626, 52-84 #949494,#121212, 85-99 d,#121212,
|2: 0-1 d,#444444, 2-49 #bdbdbd,#080808, 50-51 d,#444444, 52-99 #bdbdbd,#080808,
|3: 0-1 d,#444444, 2-49 #bdbdbd,#080808, 50-51 d,#444444, 52-99 #bdbdbd,#080808,
diff --git a/test/snapshots/exec-bigdrag.golden b/test/snapshots/exec-bigdrag.golden
index 7b532a37..b7717ee5 100644
--- a/test/snapshots/exec-bigdrag.golden
+++ b/test/snapshots/exec-bigdrag.golden
@@ -1,5 +1,5 @@
== snap alive grid=200x60 cursor=119,37
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/exec-bigdrag/cwd Del NOR /tmp/pardes-snap/exec-bigdrag/cwd Del
| bash: line: command not found
| big.txt
diff --git a/test/snapshots/exec.golden b/test/snapshots/exec.golden
index 2b5ca6ff..f978571b 100644
--- a/test/snapshots/exec.golden
+++ b/test/snapshots/exec.golden
@@ -1,5 +1,5 @@
== snap exec grid=100x30 cursor=16,7
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/exec/cwd Del NOR /tmp/pardes-snap/exec/cwd Del
|
| e.txt e.txt
@@ -30,7 +30,7 @@
|
|
== snap kept grid=100x30 cursor=6,2
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/exec/cwd Del NOR /tmp/pardes-snap/exec/cwd Del
| ZZARG
| ./c.sh e.txt
@@ -61,7 +61,7 @@
|
|
== snap chord grid=100x30 cursor=6,2
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/exec/cwd Del NOR /tmp/pardes-snap/exec/cwd Del
| ZZARG
| ./c.sh e.txt
@@ -92,7 +92,7 @@
|
|
== snap deleted grid=100x30 cursor=4,4
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/exec/cwd Del NOR /tmp/pardes-snap/exec/cwd Del
|
| e.txt e.txt
diff --git a/test/snapshots/fileedit.golden b/test/snapshots/fileedit.golden
index ac73e9e5..0df45515 100644
--- a/test/snapshots/fileedit.golden
+++ b/test/snapshots/fileedit.golden
@@ -1,5 +1,5 @@
== snap edited grid=150x30 cursor=17,2
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/fileedit/cwd/f.txt Save Del NOR /tmp/pardes-snap/fileedit/cwd Del NOR /tmp/pardes-snap/fileedit/cwd Del
| 1 liEDIT''MEne 1
| 2 line 2 f.txt f.txt
@@ -30,7 +30,7 @@
|
|
== snap deleted grid=150x30 cursor=7,3
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/fileedit/cwd/f.txt Save Del NOR /tmp/pardes-snap/fileedit/cwd Del NOR /tmp/pardes-snap/fileedit/cwd Del
| 1 liEDIT''MEne 1
| 2 line 3 f.txt f.txt
@@ -61,7 +61,7 @@
|
|
== snap undone grid=150x30 cursor=13,3
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/fileedit/cwd/f.txt Save Del NOR /tmp/pardes-snap/fileedit/cwd Del NOR /tmp/pardes-snap/fileedit/cwd Del
| 1 liEDIT''MEne 1
| 2 line 2 f.txt f.txt
diff --git a/test/snapshots/find.golden b/test/snapshots/find.golden
index 83fb66b7..e272ae92 100644
--- a/test/snapshots/find.golden
+++ b/test/snapshots/find.golden
@@ -1,5 +1,5 @@
== snap group grid=120x40 cursor=7,2
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/find/cwd/here.txt Save Del SPC f NOR /tmp/pardes-snap/find/cwd Del
| 1 Find
| here.txt other.txt sub zqmark-alpha.txt
@@ -40,7 +40,7 @@
|
|
== snap armed grid=120x40 cursor=56,1
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| INS /tmp/pardes-snap/find/cwd/here.txt Save Del Find / NOR /tmp/pardes-snap/find/cwd Del
| 1 Find
| here.txt other.txt sub zqmark-alpha.txt
@@ -81,7 +81,7 @@
|
|
== snap typing grid=120x40 cursor=59,1
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| INS /tmp/pardes-snap/find/cwd/here.txt Save Del Find /zqm NOR /tmp/pardes-snap/find/cwd Del
| 1 Find
| here.txt other.txt sub zqmark-alpha.txt
@@ -122,7 +122,7 @@
|
|
== snap results grid=120x40 cursor=7,2
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/find/cwd/here.txt Save Del NOR /tmp/pardes-snap/find/cwd Del
| 1 Find
| here.txt other.txt sub zqmark-alpha.txt
@@ -163,7 +163,7 @@
| 2 sub/nest/zqmark-gamma.txt
| 3 zqmark-alpha.txt
== snap first grid=120x40 cursor=7,2
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/find/cwd/here.txt Save Del NOR /tmp/pardes-snap/find/cwd Del
| 1 Find
| here.txt other.txt sub zqmark-alpha.txt
@@ -204,7 +204,7 @@
| 2 sub/nest/zqmark-gamma.txt
| 3 zqmark-alpha.txt
== style first
-|0: 0-47 #949494,#121212, 48-119 d,#121212,
+|0: 0-52 #949494,#121212, 53-119 d,#121212,
|1: 0-1 d,#626262, 2-48 #949494,#121212, 49-59 d,#121212, 60-61 d,#262626, 62-94 #949494,#121212, 95-119 d,#121212,
|2: 0-1 d,#444444, 2-6 #949494,#121212, 7-10 #bdbdbd,#080808, 11-59 d,#080808, 60-61 d,#444444, 62-119 #bdbdbd,#080808,
|3: 0-1 d,#444444, 2-6 #626262,#080808, 7-59 d,#080808, 60-61 d,#444444, 62-119 #bdbdbd,#080808,
@@ -245,7 +245,7 @@
|38: 0-1 d,#444444, 2-6 #626262,#080808, 7-31 #bdbdbd,#080808, 32-59 d,#080808, 60-61 d,#444444, 62-119 #bdbdbd,#080808,
|39: 0-1 d,#121212, 2-6 #626262,#080808, 7-22 #bdbdbd,#080808, 23-59 d,#080808, 60-61 d,#444444, 62-119 #bdbdbd,#080808,
== snap second grid=120x40 cursor=7,2
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/find/cwd/here.txt Save Del NOR /tmp/pardes-snap/find/cwd Del
| 1 Find
| here.txt other.txt sub zqmark-alpha.txt
@@ -286,7 +286,7 @@
| 2 sub/nest/zqmark-gamma.txt
| 3 zqmark-alpha.txt
== snap third grid=120x40 cursor=7,2
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/find/cwd/here.txt Save Del NOR /tmp/pardes-snap/find/cwd Del
| 1 Find
| here.txt other.txt sub zqmark-alpha.txt
@@ -327,7 +327,7 @@
| 3 zqmark-alpha.txt
| 4
== snap back grid=120x40 cursor=7,2
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/find/cwd/here.txt Save Del NOR /tmp/pardes-snap/find/cwd Del
| 1 Find
| here.txt other.txt sub zqmark-alpha.txt
@@ -368,7 +368,7 @@
| 2 sub/nest/zqmark-gamma.txt
| 3 zqmark-alpha.txt
== snap word grid=120x40 cursor=56,1
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| INS /tmp/pardes-snap/find/cwd/here.txt Save Del Find / NOR /tmp/pardes-snap/find/cwd Del
| 1 Find
| here.txt other.txt sub zqmark-alpha.txt
@@ -409,7 +409,7 @@
| 2 sub/nest/zqmark-gamma.txt
| 3 zqmark-alpha.txt
== snap cancel grid=120x40 cursor=7,2
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/find/cwd/here.txt Save Del NOR /tmp/pardes-snap/find/cwd Del
| 1 Find
| here.txt other.txt sub zqmark-alpha.txt
@@ -450,7 +450,7 @@
| 2 sub/nest/zqmark-gamma.txt
| 3 zqmark-alpha.txt
== snap nomatch grid=120x40 cursor=7,2
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/find/cwd/here.txt Save Del NOR /tmp/pardes-snap/find/cwd Del
| 1 Find
| here.txt other.txt sub zqmark-alpha.txt
@@ -491,7 +491,7 @@
| 2 sub/nest/zqmark-gamma.txt
| 3 zqmark-alpha.txt
== snap refit grid=120x40 cursor=7,2
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/find/cwd/here.txt Save Del NOR /tmp/pardes-snap/find/cwd Del
|╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌
| NOR /tmp/pardes-snap/find/cwd/+Search Del here.txt other.txt sub zqmark-alpha.txt
@@ -532,7 +532,7 @@
| 2 sub/nest/zqmark-gamma.txt
| 3 zqmark-alpha.txt
== snap topbar grid=120x40 cursor=12,7
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/find/cwd/here.txt Save Del NOR /tmp/pardes-snap/find/cwd Del
| 1 Find
| NOR /tmp/pardes-snap/find/cwd/+Search Del here.txt other.txt sub zqmark-alpha.txt
diff --git a/test/snapshots/fsearch.golden b/test/snapshots/fsearch.golden
index 5b1b6574..02176d84 100644
--- a/test/snapshots/fsearch.golden
+++ b/test/snapshots/fsearch.golden
@@ -1,5 +1,5 @@
== snap opened grid=180x30 cursor=7,2
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/fsearch/cwd/g.txt Save Del NOR /tmp/pardes-snap/fsearch/cwd Del NOR /tmp/pardes-snap/fsearch/cwd Del
| 1 l1
| 2 MARK a g.txt g.txt
@@ -30,7 +30,7 @@
|
|
== snap typing grid=180x30 cursor=55,1
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| INS /tmp/pardes-snap/fsearch/cwd/g.txt Save Del /MARK NOR /tmp/pardes-snap/fsearch/cwd Del NOR /tmp/pardes-snap/fsearch/cwd Del
| 1 l1
| 2 MARK a g.txt g.txt
@@ -61,7 +61,7 @@
|
|
== snap results grid=180x30 cursor=7,2
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/fsearch/cwd/g.txt Save Del NOR /tmp/pardes-snap/fsearch/cwd Del NOR /tmp/pardes-snap/fsearch/cwd Del
| 1 l1
| 2 MARK a g.txt g.txt
@@ -92,7 +92,7 @@
| 2 g.txt:6:1 MARK b
| 3 g.txt:10:1 MARK c
== snap first grid=180x30 cursor=7,3
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/fsearch/cwd/g.txt Save Del NOR /tmp/pardes-snap/fsearch/cwd Del NOR /tmp/pardes-snap/fsearch/cwd Del
| 1 l1
| 2 MARK a g.txt g.txt
@@ -123,7 +123,7 @@
| 2 g.txt:6:1 MARK b
| 3 g.txt:10:1 MARK c
== style first
-|0: 0-47 #949494,#121212, 48-179 d,#121212,
+|0: 0-52 #949494,#121212, 53-179 d,#121212,
|1: 0-1 d,#626262, 2-48 #949494,#121212, 49-59 d,#121212, 60-61 d,#262626, 62-97 #949494,#121212, 98-119 d,#121212, 120-121 d,#262626, 122-157 #949494,#121212, 158-179 d,#121212,
|2: 0-1 d,#444444, 2-6 #626262,#080808, 7-8 #bdbdbd,#080808, 9-59 d,#080808, 60-61 d,#444444, 62-119 #bdbdbd,#080808, 120-121 d,#444444, 122-179 #bdbdbd,#080808,
|3: 0-1 d,#444444, 2-6 #949494,#121212, 7-12 #bdbdbd,#080808, 13-59 d,#080808, 60-61 d,#444444, 62-119 #bdbdbd,#080808, 120-121 d,#444444, 122-179 #bdbdbd,#080808,
@@ -154,7 +154,7 @@
|28: 0-1 d,#444444, 2-6 #626262,#080808, 7-22 #bdbdbd,#080808, 23-59 d,#080808, 60-61 d,#444444, 62-119 #bdbdbd,#080808, 120-121 d,#444444, 122-179 #bdbdbd,#080808,
|29: 0-1 d,#121212, 2-6 #626262,#080808, 7-23 #bdbdbd,#080808, 24-59 d,#080808, 60-61 d,#444444, 62-119 #bdbdbd,#080808, 120-121 d,#444444, 122-179 #bdbdbd,#080808,
== snap second grid=180x30 cursor=7,7
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/fsearch/cwd/g.txt Save Del NOR /tmp/pardes-snap/fsearch/cwd Del NOR /tmp/pardes-snap/fsearch/cwd Del
| 1 l1
| 2 MARK a g.txt g.txt
@@ -185,7 +185,7 @@
| 2 g.txt:6:1 MARK b
| 3 g.txt:10:1 MARK c
== snap third grid=180x30 cursor=7,11
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/fsearch/cwd/g.txt Save Del NOR /tmp/pardes-snap/fsearch/cwd Del NOR /tmp/pardes-snap/fsearch/cwd Del
| 1 l1
| 2 MARK a g.txt g.txt
@@ -216,7 +216,7 @@
| 3 g.txt:10:1 MARK c
| 4
== snap back grid=180x30 cursor=7,7
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/fsearch/cwd/g.txt Save Del NOR /tmp/pardes-snap/fsearch/cwd Del NOR /tmp/pardes-snap/fsearch/cwd Del
| 1 l1
| 2 MARK a g.txt g.txt
@@ -247,7 +247,7 @@
| 2 g.txt:6:1 MARK b
| 3 g.txt:10:1 MARK c
== snap cancel grid=180x30 cursor=7,7
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/fsearch/cwd/g.txt Save Del NOR /tmp/pardes-snap/fsearch/cwd Del NOR /tmp/pardes-snap/fsearch/cwd Del
| 1 l1
| 2 MARK a g.txt g.txt
@@ -278,7 +278,7 @@
| 2 g.txt:6:1 MARK b
| 3 g.txt:10:1 MARK c
== snap nomatch grid=180x30 cursor=7,7
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/fsearch/cwd/g.txt Save Del NOR /tmp/pardes-snap/fsearch/cwd Del NOR /tmp/pardes-snap/fsearch/cwd Del
| 1 l1
| 2 MARK a g.txt g.txt
diff --git a/test/snapshots/ghostty-mid.golden b/test/snapshots/ghostty-mid.golden
index ba757099..7fc743f5 100644
--- a/test/snapshots/ghostty-mid.golden
+++ b/test/snapshots/ghostty-mid.golden
@@ -1,5 +1,5 @@
== snap ghostty-mid grid=100x30 cursor=4,7
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/ghostty-mid/cwd Del NOR /tmp/pardes-snap/ghostty-mid/cwd Del
| ZZPAD
| ./g.sh g.txt
diff --git a/test/snapshots/grep.golden b/test/snapshots/grep.golden
index 2f32ac4f..768c56dc 100644
--- a/test/snapshots/grep.golden
+++ b/test/snapshots/grep.golden
@@ -1,5 +1,5 @@
== snap opened grid=180x30 cursor=7,2
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/grep/cwd/a.txt Save Del NOR /tmp/pardes-snap/grep/cwd Del NOR /tmp/pardes-snap/grep/cwd Del
| 1 hello TARGET one
| 2 nothing here a.txt noise.txt sub a.txt noise.txt sub
@@ -30,7 +30,7 @@
|
|
== snap typing grid=180x30 cursor=59,1
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| INS /tmp/pardes-snap/grep/cwd/a.txt Save Del Grep /TARGET NOR /tmp/pardes-snap/grep/cwd Del NOR /tmp/pardes-snap/grep/cwd Del
| 1 hello TARGET one
| 2 nothing here a.txt noise.txt sub a.txt noise.txt sub
@@ -61,7 +61,7 @@
|
|
== snap results grid=180x30 cursor=7,2
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/grep/cwd/a.txt Save Del NOR /tmp/pardes-snap/grep/cwd Del NOR /tmp/pardes-snap/grep/cwd Del
| 1 hello TARGET one
| 2 nothing here a.txt noise.txt sub a.txt noise.txt sub
@@ -92,7 +92,7 @@
| 2 a.txt:3:6 last TARGET line
| 3 sub/b.txt:2:1 TARGET inside sub
== snap first grid=180x30 cursor=13,2
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/grep/cwd/a.txt Save Del NOR /tmp/pardes-snap/grep/cwd Del NOR /tmp/pardes-snap/grep/cwd Del
| 1 hello TARGET one
| 2 nothing here a.txt noise.txt sub a.txt noise.txt sub
@@ -123,7 +123,7 @@
| 2 a.txt:3:6 last TARGET line
| 3 sub/b.txt:2:1 TARGET inside sub
== snap opened-hit grid=180x30 cursor=12,4
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/grep/cwd/a.txt Save Del NOR /tmp/pardes-snap/grep/cwd Del NOR /tmp/pardes-snap/grep/cwd Del
| 1 hello TARGET one
| 2 nothing here a.txt noise.txt sub a.txt noise.txt sub
@@ -154,7 +154,7 @@
| 3 sub/b.txt:2:1 TARGET inside sub
| 4
== snap nomatch grid=180x30 cursor=13,2
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/grep/cwd/a.txt Save Del NOR /tmp/pardes-snap/grep/cwd Del NOR /tmp/pardes-snap/grep/cwd Del
| 1 hello TARGET one
| 2 nothing here a.txt noise.txt sub a.txt noise.txt sub
@@ -185,7 +185,7 @@
| 3 sub/b.txt:2:1 TARGET inside sub
| 4
== snap chordsel grid=180x30 cursor=19,2
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/grep/cwd/a.txt Save Del NOR /tmp/pardes-snap/grep/cwd Del NOR /tmp/pardes-snap/grep/cwd Del
| 1 hello TARGET one
| 2 nothing here a.txt noise.txt sub a.txt noise.txt sub
@@ -216,7 +216,7 @@
| 3 sub/b.txt:2:1 TARGET inside sub
| 4
== snap chord grid=180x30 cursor=19,2
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/grep/cwd/a.txt Save Del NOR /tmp/pardes-snap/grep/cwd Del NOR /tmp/pardes-snap/grep/cwd Del
| 1 hello TARGET one
| 2 nothing here a.txt noise.txt sub a.txt noise.txt sub
diff --git a/test/snapshots/hscroll.golden b/test/snapshots/hscroll.golden
index 4110f555..a91f4244 100644
--- a/test/snapshots/hscroll.golden
+++ b/test/snapshots/hscroll.golden
@@ -1,5 +1,5 @@
== snap opened grid=90x30 cursor=7,2
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/hscroll NOR /tmp/pardes-snap/hscroll NOR /tmp/pardes-snap/hscroll
| 1 short1 END_A_MARKER_WAY
| wide.txt wide.txt
@@ -30,7 +30,7 @@
|
|
== snap wheeled grid=90x30 cursor=7,2
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/hscroll NOR /tmp/pardes-snap/hscroll NOR /tmp/pardes-snap/hscroll
| 1 ND_A_MARKER_WAY_OUT_RIG
| wide.txt wide.txt
@@ -61,7 +61,7 @@
|
|
== snap clamped grid=90x30 cursor=7,2
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/hscroll NOR /tmp/pardes-snap/hscroll NOR /tmp/pardes-snap/hscroll
| 1 short1 END_A_MARKER_WAY
| wide.txt wide.txt
@@ -92,7 +92,7 @@
|
|
== snap dollar grid=90x30 cursor=26,2
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/hscroll NOR /tmp/pardes-snap/hscroll NOR /tmp/pardes-snap/hscroll
| 1 padpadpadpadpad_TAIL
| wide.txt wide.txt
@@ -123,7 +123,7 @@
|
|
== snap zero grid=90x30 cursor=7,2
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/hscroll NOR /tmp/pardes-snap/hscroll NOR /tmp/pardes-snap/hscroll
| 1 short1 END_A_MARKER_WAY
| wide.txt wide.txt
diff --git a/test/snapshots/images.golden b/test/snapshots/images.golden
index 76b40d1b..2c06a51f 100644
--- a/test/snapshots/images.golden
+++ b/test/snapshots/images.golden
@@ -1,5 +1,5 @@
== snap img-open grid=150x30 cursor=11,7
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| img /tmp/pardes-snap/images/cwd/pic.ppm Del NOR /tmp/pardes-snap/images/cwd Del NOR /tmp/pardes-snap/images/cwd Del
|
| pic.ppm pic.ppm
@@ -30,7 +30,7 @@
|
|
== style img-open
-|0: 0-47 #949494,#121212, 48-149 d,#121212,
+|0: 0-52 #949494,#121212, 53-149 d,#121212,
|1: 0-1 d,#626262, 2-44 #949494,#121212, 45-49 d,#121212, 50-51 d,#262626, 52-86 #949494,#121212, 87-99 d,#121212, 100-101 d,#262626, 102-136 #949494,#121212, 137-149 d,#121212,
|2: 0-1 d,#121212, 2-49 d,#080808, 50-51 d,#444444, 52-99 #bdbdbd,#080808, 100-101 d,#444444, 102-149 #bdbdbd,#080808,
|3: 0-1 d,#121212, 2-49 d,#080808, 50-51 d,#444444, 52-99 #bdbdbd,#080808, 100-101 d,#444444, 102-149 #bdbdbd,#080808,
@@ -61,7 +61,7 @@
|28: 0-1 d,#121212, 2-49 d,#080808, 50-51 d,#444444, 52-99 #bdbdbd,#080808, 100-101 d,#444444, 102-149 #bdbdbd,#080808,
|29: 0-1 d,#121212, 2-49 d,#080808, 50-51 d,#444444, 52-99 #bdbdbd,#080808, 100-101 d,#444444, 102-149 #bdbdbd,#080808,
== style term-palette
-|0: 0-47 #949494,#121212, 48-149 d,#121212,
+|0: 0-52 #949494,#121212, 53-149 d,#121212,
|1: 0-1 d,#626262, 2-44 #949494,#121212, 45-49 d,#121212, 50-51 d,#262626, 52-86 #949494,#121212, 87-99 d,#121212, 100-101 d,#262626, 102-136 #949494,#121212, 137-149 d,#121212,
|2: 0-1 d,#121212, 2-49 d,#080808, 50-51 d,#444444, 52-99 #bdbdbd,#080808, 100-101 d,#444444, 102-149 #bdbdbd,#080808,
|3: 0-1 d,#121212, 2-49 d,#080808, 50-51 d,#444444, 52-99 #bdbdbd,#080808, 100-101 d,#444444, 102-149 #bdbdbd,#080808,
@@ -92,7 +92,7 @@
|28: 0-1 d,#121212, 2-49 d,#080808, 50-51 d,#444444, 52-99 #bdbdbd,#080808, 100-101 d,#444444, 102-149 #bdbdbd,#080808,
|29: 0-1 d,#121212, 2-49 d,#080808, 50-51 d,#444444, 52-99 #bdbdbd,#080808, 100-101 d,#444444, 102-149 #bdbdbd,#080808,
== snap no-ascii grid=150x30 cursor=11,7
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| img /tmp/pardes-snap/images/cwd/pic.ppm Del NOR /tmp/pardes-snap/images/cwd Del NOR /tmp/pardes-snap/images/cwd Del
|
| pic.ppm pic.ppm
@@ -123,7 +123,7 @@
|
|
== snap tag-edit grid=150x30 cursor=45,1
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| img /tmp/pardes-snap/images/cwd/pic.ppmZork Del NOR /tmp/pardes-snap/images/cwd Del NOR /tmp/pardes-snap/images/cwd Del
|
| pic.ppm pic.ppm
diff --git a/test/snapshots/layout-close.golden b/test/snapshots/layout-close.golden
index c3893c2d..0b745305 100644
--- a/test/snapshots/layout-close.golden
+++ b/test/snapshots/layout-close.golden
@@ -1,5 +1,5 @@
== snap built grid=140x40 cursor=4,16
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/layout-close/cwd Del NOR /tmp/pardes-snap/layout-close/cwd Del
|
| marker.txt marker.txt
@@ -40,7 +40,7 @@
|
|
== snap altc grid=140x40 cursor=98,4
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/layout-close/cwd Del NOR /tmp/pardes-snap/layout-close/cwd Del NOR /tmp/pardes-snap/layout-close/cwd Del
|
| marker.txt marker.txt marker.txt
@@ -81,7 +81,7 @@
|
|
== snap del grid=140x40 cursor=98,4
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/layout-close/cwd Del NOR /tmp/pardes-snap/layout-close/cwd Del NOR /tmp/pardes-snap/layout-close/cwd Del
|
| marker.txt marker.txt marker.txt
@@ -122,7 +122,7 @@
|
|
== snap exit grid=140x40 cursor=98,4
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/layout-close/cwd Del NOR /tmp/pardes-snap/layout-close/cwd Del NOR /tmp/pardes-snap/layout-close/cwd Del
|
| marker.txt marker.txt marker.txt
@@ -163,7 +163,7 @@
|
|
== snap colclose grid=140x40 cursor=4,7
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/layout-close/cwd Del NOR /tmp/pardes-snap/layout-close/cwd Del
|
| marker.txt marker.txt
diff --git a/test/snapshots/layout-open.golden b/test/snapshots/layout-open.golden
index e95cf9cc..aebb4caa 100644
--- a/test/snapshots/layout-open.golden
+++ b/test/snapshots/layout-open.golden
@@ -1,5 +1,5 @@
== snap before grid=100x30 cursor=2,8
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/layout-open/cwd Del NOR /tmp/pardes-snap/layout-open/cwd Del
|
| sub sub
@@ -30,7 +30,7 @@
|
|
== snap altn-left grid=100x30 cursor=4,8
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/layout-open/cwd Del NOR /tmp/pardes-snap/layout-open/cwd Del
|
| sub sub
@@ -61,7 +61,7 @@
|
|
== snap altn-right grid=100x30 cursor=54,8
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/layout-open/cwd Del NOR /tmp/pardes-snap/layout-open/cwd Del
|
| sub sub
@@ -92,7 +92,7 @@
|
|
== snap file-open grid=100x30 cursor=7,2
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/layout-ope NOR /tmp/pardes-snap/layout-ope NOR /tmp/pardes-snap/layout-open
| 1 echo 'TTY'OK
| sub sub
@@ -123,7 +123,7 @@
|
|
== snap ttydir grid=100x30 cursor=7,2
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/layout-ope NOR /tmp/pardes-snap/layout-ope NOR /tmp/pardes-snap/layout-open
| 1 echo 'TTY'OK
| sub sub
diff --git a/test/snapshots/leader.golden b/test/snapshots/leader.golden
index 5215b6ae..6f88ad7e 100644
--- a/test/snapshots/leader.golden
+++ b/test/snapshots/leader.golden
@@ -1,5 +1,5 @@
== snap spc grid=100x40 cursor=7,2
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/leader/cwd/cmds.txt Sav SPC NOR /tmp/pardes-snap/leader/cwd Del
| 1 Help
| cmds.txt
@@ -39,9 +39,9 @@
|
|
|
-== snap spc-f grid=100x40 cursor=7,2
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
-| NOR /tmp/pardes-snap/leader/cwd/cmds.txt S SPC f NOR /tmp/pardes-snap/leader/cwd Del
+== snap spc-h grid=100x40 cursor=7,2
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
+| NOR /tmp/pardes-snap/leader/cwd/cmds.txt S SPC h NOR /tmp/pardes-snap/leader/cwd Del
| 1 Help
| cmds.txt
|
@@ -81,7 +81,7 @@
|
|
== snap abandoned grid=100x40 cursor=7,2
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/leader/cwd/cmds.txt Save De NOR /tmp/pardes-snap/leader/cwd Del
| 1 Help
| cmds.txt
@@ -122,7 +122,7 @@
|
|
== snap unmapped grid=100x40 cursor=7,2
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/leader/cwd/cmds.txt Save De NOR /tmp/pardes-snap/leader/cwd Del
| 1 Help
| cmds.txt
@@ -163,7 +163,7 @@
|
|
== snap help-word grid=100x40 cursor=7,22
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/leader/cwd/cmds.txt Save De NOR /tmp/pardes-snap/leader/cwd Del
| 1 Help
| cmds.txt
@@ -189,22 +189,22 @@
| 2 or execute the name anywhere
| 3
| 4 SPC ? Help
-| 5 SPC D WsDiagnostics
-| 6 SPC S WsSymbols
-| 7 SPC T Tutor
-| 8 SPC a CodeAction
-| 9 SPC c d Delcol
-| 10 SPC c n Newcol
-| 11 SPC d Diagnostics
-| 12 SPC f d Dump
-| 13 SPC f f Find
-| 14 SPC f g Grep
-| 15 SPC f r Restore
-| 16 SPC f s Save
-| 17 SPC h SelectRefs
-| 18 SPC k Hover
+| 5 SPC c d Delcol
+| 6 SPC c n Newcol
+| 7 SPC d Del
+| 8 SPC f f Find
+| 9 SPC f g Grep
+| 10 SPC f s Save
+| 11 SPC h t Tutor
+| 12 SPC k Kill
+| 13 SPC l D WsDiagnostics
+| 14 SPC l S WsSymbols
+| 15 SPC l a CodeAction
+| 16 SPC l d Diagnostics
+| 17 SPC l h SelectRefs
+| 18 SPC l i Lspinfo
== snap help-group grid=100x40 cursor=7,22
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/leader/cwd/cmds.txt Save De NOR /tmp/pardes-snap/leader/cwd Del
| 1 Help
| cmds.txt
@@ -226,14 +226,14 @@
|
|
| NOR /tmp/pardes-snap/leader/cwd/+Help Del
-| 1 pardes builtins under SPC f
+| 1 pardes builtins under SPC h
| 2
-| 3 SPC f d Dump
-| 4 SPC f f Find
-| 5 SPC f g Grep
-| 6 SPC f r Restore
-| 7 SPC f s Save
-| 8
+| 3 SPC h t Tutor
+| 4
+|
+|
+|
+|
|
|
|
@@ -245,7 +245,7 @@
|
|
== snap tutor grid=100x40 cursor=7,12
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/leader/cwd/cmds.txt Save De NOR /tmp/pardes-snap/leader/cwd Del
| 1 Help
| cmds.txt
@@ -267,14 +267,14 @@
| 8
| 9
| NOR /tmp/pardes-snap/leader/cwd/+Help Del
-| 1 pardes builtins under SPC f
+| 1 pardes builtins under SPC h
| 2
-| 3 SPC f d Dump
-| 4 SPC f f Find
-| 5 SPC f g Grep
-| 6 SPC f r Restore
-| 7 SPC f s Save
-| 8
+| 3 SPC h t Tutor
+| 4
+|
+|
+|
+|
|
|
|
@@ -286,7 +286,7 @@
|
|
== snap deleted grid=100x40 cursor=7,22
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/leader/cwd/cmds.txt Save De NOR /tmp/pardes-snap/leader/cwd Del
| 1 Help
| cmds.txt
@@ -308,14 +308,14 @@
|
|
| NOR /tmp/pardes-snap/leader/cwd/+Help Del
-| 1 pardes builtins under SPC f
+| 1 pardes builtins under SPC h
| 2
-| 3 SPC f d Dump
-| 4 SPC f f Find
-| 5 SPC f g Grep
-| 6 SPC f r Restore
-| 7 SPC f s Save
-| 8
+| 3 SPC h t Tutor
+| 4
+|
+|
+|
+|
|
|
|
@@ -327,7 +327,7 @@
|
|
== snap help-all grid=100x40 cursor=7,22
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/leader/cwd/cmds.txt Save De NOR /tmp/pardes-snap/leader/cwd Del
| 1 Help
| cmds.txt
@@ -353,22 +353,22 @@
| 2 or execute the name anywhere
| 3
| 4 SPC ? Help
-| 5 SPC D WsDiagnostics
-| 6 SPC S WsSymbols
-| 7 SPC T Tutor
-| 8 SPC a CodeAction
-| 9 SPC c d Delcol
-| 10 SPC c n Newcol
-| 11 SPC d Diagnostics
-| 12 SPC f d Dump
-| 13 SPC f f Find
-| 14 SPC f g Grep
-| 15 SPC f r Restore
-| 16 SPC f s Save
-| 17 SPC h SelectRefs
-| 18 SPC k Hover
+| 5 SPC c d Delcol
+| 6 SPC c n Newcol
+| 7 SPC d Del
+| 8 SPC f f Find
+| 9 SPC f g Grep
+| 10 SPC f s Save
+| 11 SPC h t Tutor
+| 12 SPC k Kill
+| 13 SPC l D WsDiagnostics
+| 14 SPC l S WsSymbols
+| 15 SPC l a CodeAction
+| 16 SPC l d Diagnostics
+| 17 SPC l h SelectRefs
+| 18 SPC l i Lspinfo
== snap help-toggles grid=100x40 cursor=7,22
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/leader/cwd/cmds.txt Save De NOR /tmp/pardes-snap/leader/cwd Del
| 1 Help
| cmds.txt
@@ -409,7 +409,7 @@
|
|
== snap help-window grid=100x40 cursor=7,22
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/leader/cwd/cmds.txt Save De NOR /tmp/pardes-snap/leader/cwd Del
| 1 Help
| cmds.txt
@@ -433,24 +433,65 @@
| NOR /tmp/pardes-snap/leader/cwd/+Help Del
| 1 pardes builtins under SPC w
| 2
-| 3 SPC w c Del
-| 4 SPC w h Left
-| 5 SPC w j Down
-| 6 SPC w k Up
-| 7 SPC w l Right
-| 8 SPC w t Toggleterm
-| 9
+| 3 SPC w h Left
+| 4 SPC w j Down
+| 5 SPC w k Up
+| 6 SPC w l Right
+| 7 SPC w t Toggleterm
+| 8
+|
+|
+|
+|
|
|
|
|
|
|
+== snap help-language grid=100x40 cursor=7,22
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
+| NOR /tmp/pardes-snap/leader/cwd/cmds.txt Save De NOR /tmp/pardes-snap/leader/cwd Del
+| 1 Help
+| cmds.txt
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+| NOR /tmp/pardes-snap/leader/cwd/+Help Del
+| 1 pardes builtins under SPC l
+| 2
+| 3 SPC l D WsDiagnostics
+| 4 SPC l S WsSymbols
+| 5 SPC l a CodeAction
+| 6 SPC l d Diagnostics
+| 7 SPC l h SelectRefs
+| 8 SPC l i Lspinfo
+| 9 SPC l k Hover
+| 10 SPC l r Rename
+| 11 SPC l s Symbols
+| 12 SPC l w Lspwhy
+| 13
+|
+|
|
|
|
== snap esc-del grid=100x40 cursor=7,2
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/leader/cwd/cmds.txt Save De NOR /tmp/pardes-snap/leader/cwd Del
| 1 Help
| cmds.txt
diff --git a/test/snapshots/leader.snap b/test/snapshots/leader.snap
index e06d5a3c..7cd0b98d 100644
--- a/test/snapshots/leader.snap
+++ b/test/snapshots/leader.snap
@@ -6,10 +6,6 @@
# pane with no file behind it, like +Search). The paths, the Help lines and
# the execute dispatch are all folded out of ONE enum at comptime — so
# executing the WORD `Help` runs the same builtin the leader does.
-#
-# The single-letter slots k/r/a/h/s/S/d/D belong to helix's LSP commands, so
-# pardes's own builtins live around them: Kill on `q`, Del in the window group
-# as `w c`, Dump/Restore in the file group, Tutor on `T`.
file cmds.txt Help
start 40 100 cmds.txt
wait 8000 Kill Newcol
@@ -19,10 +15,10 @@ stable 700 20000
key space
stable 400 5000
snap spc
-# ... and grows as the path is typed (`f` = the file group)
-key f
+# ... and grows as the path is typed (`h` = the docs group)
+key h
stable 400 5000
-snap spc-f
+snap spc-h
# Esc abandons the sequence: indicator gone, nothing ran, cursor untouched
key esc
settle 100
@@ -31,43 +27,43 @@ snap abandoned
# an UNMAPPED key abandons too, rather than waiting: a typo must not leave the
# next keystroke armed at a builtin that closes panes
key space
-key z
+key q
stable 400 5000
snap unmapped
# executing the WORD `Help` (middle-click) runs the builtin — the enum IS the
# lookup, so a name works anywhere text lives. Every builtin, with its keys.
press middle 9 3
release middle 9 3
-wait 10000 SPC T
+wait 10000 SPC h t
stable 700 15000
snap help-word
-# `SPC f ?`: only the `f` group, rewritten into the SAME +Help buffer
+# `SPC h ?`: only the `h` group, rewritten into the SAME +Help buffer
key space
-key f
+key h
key ?
-wait 10000 under SPC f
+wait 10000 under SPC h
stable 700 15000
snap help-group
-# `SPC T`: the Tutor builtin, zero arguments. It runs from the +Help pane,
+# `SPC h t`: the Tutor builtin, zero arguments. It runs from the +Help pane,
# but that is an output pane and not a document — so the tutor lands under
# cmds.txt, the real doc, with the listing left at the foot of the column.
key space
-key T
+key h
+key t
wait 10000 PARDES TUTOR
stable 700 15000
snap tutor
-# `SPC w c`: Del is pane-scoped — it closes the tutor, focus falls back. It
-# sits in the window group because closing a pane IS a window operation, and
-# because `d` now belongs to the diagnostics picker.
+# `SPC d`: Del is pane-scoped — it closes the tutor, focus falls back
key space
-key w
-key c
+key d
stable 700 15000
snap deleted
-# `SPC ?` at the root lists everything again
+# `SPC ?` at the root lists everything again. Waits on an EARLY row: the full
+# listing outgrew this pane when the language group landed (Restore, which this
+# used to watch for, is now row 21 of 33 and falls off the bottom).
key space
key ?
-wait 10000 SPC f r
+wait 10000 SPC c n
stable 700 15000
snap help-all
# `SPC t ?`: the toggle group, seven of them now that the image renderer
@@ -79,14 +75,25 @@ key ?
wait 10000 Petscii
stable 700 15000
snap help-toggles
-# `SPC w ?`: the window group — the four focus moves, the terminal hop, and
-# Del. They are the tail of the full listing above and fall off its bottom.
+# `SPC w ?`: the window group, whose five builtins are the tail of the full
+# listing above and fall off the bottom of this pane there
key space
key w
key ?
wait 10000 Toggleterm
stable 700 15000
snap help-window
+# `SPC l ?`: the LANGUAGE group — every LSP command lives here rather than on
+# the bare `<space>` letters helix uses, so `d` stays Del and `k` stays Kill.
+# Each one keeps helix's own letter INSIDE the group (hover k, rename r, code
+# action a, symbols s/S, diagnostics d/D, select-refs h), plus the two
+# introspection builtins that are ours: i and w.
+key space
+key l
+key ?
+wait 10000 WsDiagnostics
+stable 700 15000
+snap help-language
# Esc in the BODY of an output buffer IS Del: +Help has no file behind it and
# nothing worth keeping, so the key that elsewhere only drops a selection
# dismisses the whole pane and hands its height back to the pane above.
diff --git a/test/snapshots/load.golden b/test/snapshots/load.golden
index 801a1e2b..eaf0a449 100644
--- a/test/snapshots/load.golden
+++ b/test/snapshots/load.golden
@@ -1,5 +1,5 @@
== snap loaded grid=100x30 cursor=4,15
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/load/cwd Del NOR /tmp/pardes-snap/load/cwd Del
|
| LOADMARK d.txt
@@ -30,7 +30,7 @@
|
|
== style loaded
-|0: 0-47 #949494,#121212, 48-99 d,#121212,
+|0: 0-52 #949494,#121212, 53-99 d,#121212,
|1: 0-1 d,#626262, 2-34 #949494,#121212, 35-49 d,#121212, 50-51 d,#262626, 52-84 #949494,#121212, 85-99 d,#121212,
|2: 0-1 d,#444444, 2-49 #bdbdbd,#080808, 50-51 d,#444444, 52-99 #bdbdbd,#080808,
|3: 0-1 d,#444444, 2-49 #bdbdbd,#080808, 50-51 d,#444444, 52-99 #bdbdbd,#080808,
diff --git a/test/snapshots/logquiet.golden b/test/snapshots/logquiet.golden
index 446c0dab..0e5ce9b8 100644
--- a/test/snapshots/logquiet.golden
+++ b/test/snapshots/logquiet.golden
@@ -1,5 +1,5 @@
== snap quiet grid=100x30 cursor=62,4
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| TTY /tmp/pardes-snap/logquiet/cwd Del
| $ ls
| $ printf '\033_Ga=q,i=1,s=1,v=1,f=24,t=d;AAAA\033\\\033[>0p'
diff --git a/test/snapshots/look-center.golden b/test/snapshots/look-center.golden
index f5309a32..b9496e57 100644
--- a/test/snapshots/look-center.golden
+++ b/test/snapshots/look-center.golden
@@ -1,5 +1,5 @@
== snap center-open grid=150x30 cursor=7,16
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/look-center/cwd/big.txt Sav NOR /tmp/pardes-snap/look-center/cwd Del NOR /tmp/pardes-snap/look-center/cwd Del
| 86 line 86
| 87 line 87 big.txt big.txt
@@ -30,7 +30,7 @@
| 112 line 112
| 113 line 113
== snap center-dedup grid=150x30 cursor=7,16
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/look-center/cwd/big.txt Sav NOR /tmp/pardes-snap/look-center/cwd Del NOR /tmp/pardes-snap/look-center/cwd Del
| 86 line 86
| 87 line 87 big.txt big.txt
@@ -61,7 +61,7 @@
| 112 line 112
| 113 line 113
== snap center-clamp grid=150x30 cursor=7,16
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/look-center/cwd/big.txt Sav NOR /tmp/pardes-snap/look-center/cwd Del NOR /tmp/pardes-snap/look-center/cwd Del
| 86 line 86
| 87 line 87 big.txt big.txt
diff --git a/test/snapshots/look-dir.golden b/test/snapshots/look-dir.golden
index 5b77d8f4..ae81beca 100644
--- a/test/snapshots/look-dir.golden
+++ b/test/snapshots/look-dir.golden
@@ -1,5 +1,5 @@
== snap dir-open grid=100x30 cursor=4,8
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/look-dir/cwd Del NOR /tmp/pardes-snap/look-dir/cwd Del
|
| sub top.txt sub top.txt
diff --git a/test/snapshots/look-file-1col.golden b/test/snapshots/look-file-1col.golden
index ff4c90c7..f38f062d 100644
--- a/test/snapshots/look-file-1col.golden
+++ b/test/snapshots/look-file-1col.golden
@@ -1,5 +1,5 @@
== snap file-open-1col grid=100x30 cursor=7,16
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/look-file-1col/cwd/big.txt NOR /tmp/pardes-snap/look-file-1col/cwd Del
| 26 line 26
| 27 line 27 big.txt
diff --git a/test/snapshots/look-file.golden b/test/snapshots/look-file.golden
index 81280d94..0289ba29 100644
--- a/test/snapshots/look-file.golden
+++ b/test/snapshots/look-file.golden
@@ -1,5 +1,5 @@
== snap file-open grid=150x30 cursor=7,16
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/look-file/cwd/big.txt Save NOR /tmp/pardes-snap/look-file/cwd Del NOR /tmp/pardes-snap/look-file/cwd Del
| 26 line 26
| 27 line 27 big.txt big.txt
@@ -30,7 +30,7 @@
| 52 line 52
| 53 line 53
== style file-open
-|0: 0-47 #949494,#121212, 48-149 d,#121212,
+|0: 0-52 #949494,#121212, 53-149 d,#121212,
|1: 0-1 d,#626262, 2-49 #949494,#121212, 50-51 d,#262626, 52-89 #949494,#121212, 90-99 d,#121212, 100-101 d,#262626, 102-139 #949494,#121212, 140-149 d,#121212,
|2: 0-1 d,#121212, 2-6 #626262,#080808, 7-13 #bdbdbd,#080808, 14-49 d,#080808, 50-51 d,#444444, 52-99 #bdbdbd,#080808, 100-101 d,#444444, 102-149 #bdbdbd,#080808,
|3: 0-1 d,#121212, 2-6 #626262,#080808, 7-13 #bdbdbd,#080808, 14-49 d,#080808, 50-51 d,#444444, 52-99 #bdbdbd,#080808, 100-101 d,#444444, 102-149 #bdbdbd,#080808,
diff --git a/test/snapshots/lookloaded.golden b/test/snapshots/lookloaded.golden
index e4720500..03b63b57 100644
--- a/test/snapshots/lookloaded.golden
+++ b/test/snapshots/lookloaded.golden
@@ -1,5 +1,5 @@
== snap file-open grid=100x30 cursor=7,16
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/lookloaded NOR /tmp/pardes-snap/lookloaded NOR /tmp/pardes-snap/lookloaded/
| 26 line 26
| 27 line 27 big.txt big.txt
@@ -30,7 +30,7 @@
| 52 line 52
| 53 line 53
== snap removed grid=100x30 cursor=37,10
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/lookloaded NOR /tmp/pardes-snap/lookloaded NOR /tmp/pardes-snap/lookloaded/
| 26 line 26
| 27 line 27 big.txt big.txt
@@ -61,7 +61,7 @@
| 52 line 52
| 53 line 53
== snap look-noFS grid=100x30 cursor=7,11
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/lookloaded NOR /tmp/pardes-snap/lookloaded NOR /tmp/pardes-snap/lookloaded/
| 1 line 1
| 2 line 2 big.txt big.txt
diff --git a/test/snapshots/lookpanes.golden b/test/snapshots/lookpanes.golden
index 48fdbbdd..93a940c5 100644
--- a/test/snapshots/lookpanes.golden
+++ b/test/snapshots/lookpanes.golden
@@ -1,5 +1,5 @@
== snap shells grid=130x50 cursor=122,3
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/lookpanes/cwd/beta/bmark.txt Save Del NOR /tmp/pardes-snap/lookpanes/cwd Del
| 1 both.txt
| 2 b-marker alpha beta zzboot.txt zqonly.txt pick.txt twin.txt
@@ -50,7 +50,7 @@
|
|
== snap other-dir grid=130x50 cursor=7,27
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/lookpanes/cwd/beta/bmark.txt Save Del NOR /tmp/pardes-snap/lookpanes/cwd Del
| 1 both.txt
| 2 b-marker alpha beta zzboot.txt zqonly.txt pick.txt twin.txt
@@ -101,7 +101,7 @@
|
|
== snap clicked-wins grid=130x50 cursor=7,15
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/lookpanes/cwd/beta/bmark.txt Save Del NOR /tmp/pardes-snap/lookpanes/cwd Del
| 1 both.txt
| 2 b-marker alpha beta zzboot.txt zqonly.txt pick.txt twin.txt
@@ -152,7 +152,7 @@
|
|
== snap mru-alpha grid=130x50 cursor=7,9
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/lookpanes/cwd/beta/bmark.txt Save Del NOR /tmp/pardes-snap/lookpanes/cwd Del
| 1 both.txt
| 2 b-marker alpha beta zzboot.txt zqonly.txt pick.txt twin.txt
@@ -203,7 +203,7 @@
|
|
== snap mru-beta grid=130x50 cursor=7,5
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/lookpanes/cwd/beta/bmark.txt Save Del NOR /tmp/pardes-snap/lookpanes/cwd Del
| 1 both.txt
| 2 b-marker alpha beta zzboot.txt zqonly.txt pick.txt twin.txt
@@ -254,7 +254,7 @@
|
|
== style mru-beta
-|0: 0-47 #949494,#121212, 48-129 d,#121212,
+|0: 0-52 #949494,#121212, 53-129 d,#121212,
|1: 0-1 d,#262626, 2-59 #949494,#121212, 60-64 d,#121212, 65-66 d,#262626, 67-104 #949494,#121212, 105-129 d,#121212,
|2: 0-1 d,#444444, 2-6 #626262,#080808, 7-14 #bdbdbd,#080808, 15-64 d,#080808, 65-66 d,#444444, 67-129 #bdbdbd,#080808,
|3: 0-1 d,#444444, 2-6 #626262,#080808, 7-14 #bdbdbd,#080808, 15-64 d,#080808, 65-66 d,#444444, 67-121 #bdbdbd,#080808, 122-129 d,#080808,
diff --git a/test/snapshots/lsp.golden b/test/snapshots/lsp.golden
index c85a412b..32d5b6d0 100644
--- a/test/snapshots/lsp.golden
+++ b/test/snapshots/lsp.golden
@@ -1,5 +1,5 @@
== snap opened grid=120x40 cursor=7,2
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/lsp/cwd/a.zig Save Del NOR /tmp/pardes-snap/lsp/cwd Del
| 1 const std = @import("std");
| 2 a.zig
@@ -40,7 +40,7 @@
|
|
== snap cursor grid=120x40 cursor=17,9
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/lsp/cwd/a.zig Save Del NOR /tmp/pardes-snap/lsp/cwd Del
| 1 const std = @import("std");
| 2 a.zig
@@ -81,7 +81,7 @@
|
|
== snap definition grid=120x40 cursor=10,4
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/lsp/cwd/a.zig Save Del NOR /tmp/pardes-snap/lsp/cwd Del
| 1 const std = @import("std");
| 2 a.zig
@@ -122,7 +122,7 @@
|
|
== snap hover grid=120x40 cursor=10,4
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/lsp/cwd/a.zig Save Del NOR /tmp/pardes-snap/lsp/cwd Del
| 1 const std = @import("std");
| 2 a.zig
@@ -163,7 +163,7 @@
| 1 fn helper(x: u32) u32
| 2 (fn (u32) u32)
== snap symbols grid=120x40 cursor=10,4
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/lsp/cwd/a.zig Save Del NOR /tmp/pardes-snap/lsp/cwd Del
| 1 const std = @import("std");
| 2 a.zig
@@ -204,7 +204,7 @@
| 1 fn helper(x: u32) u32
| 2 (fn (u32) u32)
== snap step grid=120x40 cursor=13,2
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/lsp/cwd/a.zig Save Del NOR /tmp/pardes-snap/lsp/cwd Del
| 1 const std = @import("std");
| 2 a.zig
@@ -245,7 +245,7 @@
| 1 fn helper(x: u32) u32
| 2 (fn (u32) u32)
== snap nothing grid=120x40 cursor=7,4
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/lsp/cwd/a.zig Save Del NOR /tmp/pardes-snap/lsp/cwd Del
| 1 const std = @import("std");
| 2 a.zig
diff --git a/test/snapshots/lsp.snap b/test/snapshots/lsp.snap
index 9ea84e1f..a1cc056c 100644
--- a/test/snapshots/lsp.snap
+++ b/test/snapshots/lsp.snap
@@ -27,16 +27,18 @@ key g
key d
stable 700 15000
snap definition
-# SPC k is hover (K is keep_selections in helix and stays that way). The answer
+# SPC l k is hover (K is keep_selections in helix and stays that way). The answer
# is prose, not locations, so it opens +Hover and does NOT arm the n/N stepper.
key space
+key l
key k
stable 700 15000
snap hover
-# SPC s lists the file's own symbols. Several rows, so it opens a +Search
+# SPC l s lists the file's own symbols. Several rows, so it opens a +Search
# buffer — which IS the picker: n steps a row and looks it, exactly as the Find
# and `/` results already do, with no picker code of its own.
key space
+key l
key s
stable 700 15000
snap symbols
diff --git a/test/snapshots/lspdebug.golden b/test/snapshots/lspdebug.golden
new file mode 100644
index 00000000..2bce4aa6
--- /dev/null
+++ b/test/snapshots/lspdebug.golden
@@ -0,0 +1,225 @@
+== snap opened grid=120x44 cursor=7,2
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
+| NOR /tmp/pardes-snap/lspdebug/cwd/z.zig Save Del NOR /tmp/pardes-snap/lspdebug/cwd Del
+| 1 const std = @import("std");
+| 2 z.zig
+| 3 fn helper() u32 {
+| 4 return 3;
+| 5 }
+| 6
+| 7 pub fn main() void {
+| 8 const v = helper();
+| 9 _ = v;
+| 10 }
+| 11
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+== snap ctrlclick grid=120x44 cursor=10,4
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
+| NOR /tmp/pardes-snap/lspdebug/cwd/z.zig Save Del NOR /tmp/pardes-snap/lspdebug/cwd Del
+| 1 const std = @import("std");
+| 2 z.zig
+| 3 fn helper() u32 {
+| 4 return 3;
+| 5 }
+| 6
+| 7 pub fn main() void {
+| 8 const v = helper();
+| 9 _ = v;
+| 10 }
+| 11
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+== snap plainclick grid=120x44 cursor=21,9
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
+| NOR /tmp/pardes-snap/lspdebug/cwd/z.zig Save Del NOR /tmp/pardes-snap/lspdebug/cwd Del
+| 1 const std = @import("std");
+| 2 z.zig
+| 3 fn helper() u32 {
+| 4 return 3;
+| 5 }
+| 6
+| 7 pub fn main() void {
+| 8 const v = helper();
+| 9 _ = v;
+| 10 }
+| 11
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+== snap why grid=120x44 cursor=7,4
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
+| NOR /tmp/pardes-snap/lspdebug/cwd/z.zig Save Del NOR /tmp/pardes-snap/lspdebug/cwd Del
+| 1 const std = @import("std");
+| 2 z.zig
+| 3 fn helper() u32 {
+| 4 return 3;
+| 5 }
+| 6
+| 7 pub fn main() void {
+| 8 const v = helper();
+| 9 _ = v;
+| 10 }
+| 11
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+| NOR /tmp/pardes-snap/lspdebug/cwd/+Lsp Del
+| 1 lsp explain — the definition query at byte 29 of z.zi
+| 2
+| 3 zig lib dir: /usr/lib/zig (open) — `std` imports reso
+| 4 parsed 122 bytes, 0 syntax error(s)
+| 5 position context: .empty
+| 6 STOP: nothing to resolve in a .empty context — `gd` o
+| 7 an identifier, a field access, a label, an enum
+| 8
+| 9 0 row(s)
+== snap info grid=120x44 cursor=7,4
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
+| NOR /tmp/pardes-snap/lspdebug/cwd/z.zig Save Del NOR /tmp/pardes-snap/lspdebug/cwd Del
+| 1 const std = @import("std");
+| 2 z.zig
+| 3 fn helper() u32 {
+| 4 return 3;
+| 5 }
+| 6
+| 7 pub fn main() void {
+| 8 const v = helper();
+| 9 _ = v;
+| 10 }
+| 11
+|
+|
+|
+|
+|
+| NOR /tmp/pardes-snap/lspdebug/cwd/+Lsp Del
+| 1 backend: zls-inproc
+| 2 zls: 0.16.1-dev+3e0d0820 (compiled in — no server pro
+| 3 zig lib dir: /usr/lib/zig [OK]
+| 4 offsets: utf-8 walk caps: 512 files, 2000 rows
+| 5
+| 6 dependency imports gd can follow (6):
+| 7 zls /home/goblin/00-projects/0x4200.cafe
+| 8 tree-sitter /home/goblin/00-projects/0x4200.cafe
+| 9 zstbi /home/goblin/00-projects/0x4200.cafe
+| 10 ghostty-vt /home/goblin/00-projects/0x4200.cafe
+| 11 vaxis /home/goblin/00-projects/0x4200.cafe
+| 12 uucode /home/goblin/00-projects/0x4200.cafe
+| 13 asked from: /tmp/pardes-snap/lspdebug/cwd/z.zig
+| 14
+| 15 answers: definition, declaration, type_definition, im
+| NOR /tmp/pardes-snap/lspdebug/cwd/+Lsp Del
+| 1 lsp explain — the definition query at byte 29 of z.zi
+| 2
+| 3 zig lib dir: /usr/lib/zig (open) — `std` imports reso
+| 4 parsed 122 bytes, 0 syntax error(s)
+| 5 position context: .empty
+| 6 STOP: nothing to resolve in a .empty context — `gd` o
+| 7 an identifier, a field access, a label, an enum
+| 8
+| 9 0 row(s)
diff --git a/test/snapshots/lspdebug.snap b/test/snapshots/lspdebug.snap
new file mode 100644
index 00000000..a2160408
--- /dev/null
+++ b/test/snapshots/lspdebug.snap
@@ -0,0 +1,52 @@
+# The mouse chord and the two introspection builtins.
+#
+# Ctrl-left-click IS `gd`. It rides the ordinary left-click drag rather than
+# firing on the press, because a click does not place the modal cursor until
+# RELEASE — asking at press time would answer about wherever the cursor
+# happened to be sitting, which is the bug this test would not have caught.
+#
+# `SPC l w` and `SPC l i` exist because this backend never fails loudly: a
+# thrown analyser must not take the editor with it, but that makes a broken
+# backend and a correct one that found nothing look identical. These two tell
+# them apart, so they are worth a test that proves they say something TRUE.
+file z.zig const std = @import("std");\n\nfn helper() u32 {\n return 3;\n}\n\npub fn main() void {\n const v = helper();\n _ = v;\n}\n
+start 44 120 z.zig
+wait 8000 fn helper
+stable 700 20000
+snap opened
+# Ctrl-click on the `helper` of the CALL (row 10 = file line 8, col 22 = the
+# `h`). One definition, so it jumps rather than listing: the cursor lands on
+# line 3, the `helper` of `fn helper()`, in this same pane.
+press ctrl-left 22 10
+release ctrl-left 22 10
+stable 700 15000
+snap ctrlclick
+# A PLAIN left click in the same place must NOT jump — the modifier is the
+# whole difference, and without this the test above would pass on a bug that
+# made every click a goto.
+press left 22 10
+release left 22 10
+stable 700 15000
+snap plainclick
+# `SPC l w` on a keyword: `gd` finds nothing there, and the point of Lspwhy is
+# that it says WHY rather than leaving you with a no-op key. It narrates the
+# real resolution path — the position context is the analyser's own answer,
+# not a guess reconstructed beside it.
+text 3gg1g|
+stable 400 10000
+key space
+key l
+key w
+wait 10000 position context
+stable 700 15000
+snap why
+# `SPC l i`: which ZLS, which stdlib, what it answers, and the query log —
+# which by now holds the two gotos and the explain above, with their timings.
+# It answers from any pane, including one with no file, because it is about
+# the BACKEND.
+key space
+key l
+key i
+wait 10000 zls-inproc
+stable 700 15000
+snap info
diff --git a/test/snapshots/modal.golden b/test/snapshots/modal.golden
index 616341ce..7ff3073d 100644
--- a/test/snapshots/modal.golden
+++ b/test/snapshots/modal.golden
@@ -1,5 +1,5 @@
== snap top grid=100x30 cursor=2,2
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/modal/cwd Del NOR /tmp/pardes-snap/modal/cwd Del
|
| words.txt words.txt
@@ -30,7 +30,7 @@
|
|
== snap moved grid=100x30 cursor=5,6
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/modal/cwd Del NOR /tmp/pardes-snap/modal/cwd Del
|
| words.txt words.txt
@@ -61,7 +61,7 @@
|
|
== snap xsel grid=100x30 cursor=15,6
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/modal/cwd Del NOR /tmp/pardes-snap/modal/cwd Del
|
| words.txt words.txt
@@ -92,7 +92,7 @@
|
|
== style xsel
-|0: 0-47 #949494,#121212, 48-99 d,#121212,
+|0: 0-52 #949494,#121212, 53-99 d,#121212,
|1: 0-1 d,#626262, 2-35 #949494,#121212, 36-49 d,#121212, 50-51 d,#262626, 52-85 #949494,#121212, 86-99 d,#121212,
|2: 0-1 d,#444444, 2-49 #bdbdbd,#080808, 50-51 d,#444444, 52-99 #bdbdbd,#080808,
|3: 0-1 d,#444444, 2-49 #bdbdbd,#080808, 50-51 d,#444444, 52-99 #bdbdbd,#080808,
@@ -123,7 +123,7 @@
|28: 0-1 d,#444444, 2-49 #bdbdbd,#080808, 50-51 d,#444444, 52-99 #bdbdbd,#080808,
|29: 0-1 d,#444444, 2-49 #bdbdbd,#080808, 50-51 d,#444444, 52-99 #bdbdbd,#080808,
== snap xsel2 grid=100x30 cursor=15,7
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/modal/cwd Del NOR /tmp/pardes-snap/modal/cwd Del
|
| words.txt words.txt
@@ -154,7 +154,7 @@
|
|
== snap yanked grid=100x30 cursor=15,7
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/modal/cwd Del NOR /tmp/pardes-snap/modal/cwd Del
|
| words.txt words.txt
@@ -185,7 +185,7 @@
|
|
== snap vsel grid=100x30 cursor=16,8
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/modal/cwd Del NOR /tmp/pardes-snap/modal/cwd Del
|
| words.txt words.txt
@@ -216,7 +216,7 @@
|
|
== style vsel
-|0: 0-47 #949494,#121212, 48-99 d,#121212,
+|0: 0-52 #949494,#121212, 53-99 d,#121212,
|1: 0-1 d,#626262, 2-35 #949494,#121212, 36-49 d,#121212, 50-51 d,#262626, 52-85 #949494,#121212, 86-99 d,#121212,
|2: 0-1 d,#444444, 2-49 #bdbdbd,#080808, 50-51 d,#444444, 52-99 #bdbdbd,#080808,
|3: 0-1 d,#444444, 2-49 #bdbdbd,#080808, 50-51 d,#444444, 52-99 #bdbdbd,#080808,
@@ -247,7 +247,7 @@
|28: 0-1 d,#444444, 2-49 #bdbdbd,#080808, 50-51 d,#444444, 52-99 #bdbdbd,#080808,
|29: 0-1 d,#444444, 2-49 #bdbdbd,#080808, 50-51 d,#444444, 52-99 #bdbdbd,#080808,
== snap typed grid=100x30 cursor=7,6
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/modal/cwd Del NOR /tmp/pardes-snap/modal/cwd Del
|
| words.txt words.txt
@@ -278,7 +278,7 @@
|
|
== snap undone grid=100x30 cursor=16,8
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/modal/cwd Del NOR /tmp/pardes-snap/modal/cwd Del
|
| words.txt words.txt
@@ -309,7 +309,7 @@
|
|
== snap redone grid=100x30 cursor=7,6
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/modal/cwd Del NOR /tmp/pardes-snap/modal/cwd Del
|
| words.txt words.txt
@@ -340,7 +340,7 @@
|
|
== snap bottom grid=100x30 cursor=2,9
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/modal/cwd Del NOR /tmp/pardes-snap/modal/cwd Del
|
| words.txt words.txt
diff --git a/test/snapshots/psearch.golden b/test/snapshots/psearch.golden
index e1414ffa..2bd9fc81 100644
--- a/test/snapshots/psearch.golden
+++ b/test/snapshots/psearch.golden
@@ -1,5 +1,5 @@
== snap output grid=140x30 cursor=4,8
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/psearch/cwd Del
|
| x MARK a
@@ -30,7 +30,7 @@
|
|
== snap typing grid=140x30 cursor=44,1
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| INS /tmp/pardes-snap/psearch/cwd Del /MARK
|
| x MARK a
@@ -61,7 +61,7 @@
|
|
== snap results grid=140x30 cursor=4,8
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/psearch/cwd Del
|
| x MARK a
@@ -92,7 +92,7 @@
| 2 @p0:4:3 x MARK b
| 3 @p0:6:3 x MARK c
== snap first grid=140x30 cursor=4,3
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/psearch/cwd Del
|
| x MARK a
@@ -123,7 +123,7 @@
| 2 @p0:4:3 x MARK b
| 3 @p0:6:3 x MARK c
== style first
-|0: 0-47 #949494,#121212, 48-139 d,#121212,
+|0: 0-52 #949494,#121212, 53-139 d,#121212,
|1: 0-1 d,#626262, 2-37 #949494,#121212, 38-139 d,#121212,
|2: 0-1 d,#444444, 2-139 #bdbdbd,#080808,
|3: 0-1 d,#444444, 2-139 #bdbdbd,#080808,
@@ -154,7 +154,7 @@
|28: 0-1 d,#444444, 2-6 #626262,#080808, 7-22 #bdbdbd,#080808, 23-139 d,#080808,
|29: 0-1 d,#121212, 2-6 #626262,#080808, 7-22 #bdbdbd,#080808, 23-139 d,#080808,
== snap second grid=140x30 cursor=4,5
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/psearch/cwd Del
|
| x MARK a
@@ -185,7 +185,7 @@
| 2 @p0:4:3 x MARK b
| 3 @p0:6:3 x MARK c
== snap back grid=140x30 cursor=4,3
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/psearch/cwd Del
|
| x MARK a
@@ -216,7 +216,7 @@
| 2 @p0:4:3 x MARK b
| 3 @p0:6:3 x MARK c
== snap nomatch grid=140x30 cursor=4,3
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/psearch/cwd Del
|
| x MARK a
@@ -247,7 +247,7 @@
| 2 @p0:4:3 x MARK b
| 3 @p0:6:3 x MARK c
== snap ttyinert grid=140x30 cursor=4,8
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| TTY /tmp/pardes-snap/psearch/cwd Del
| $ printf 'x MA''RK a\nzz\nx MA''RK b\nzz\nx MA''RK c\n'
| x MARK a
@@ -278,7 +278,7 @@
| 2 @p0:4:3 x MARK b
| 3 @p0:6:3 x MARK c
== snap rightsearch grid=140x30 cursor=4,3
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/psearch/cwd Del
|
| x MARK a
diff --git a/test/snapshots/reflow.golden b/test/snapshots/reflow.golden
index 5d4462e2..55c226ad 100644
--- a/test/snapshots/reflow.golden
+++ b/test/snapshots/reflow.golden
@@ -1,5 +1,5 @@
== snap widened grid=200x24 cursor=4,19
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| TTY /tmp/pardes-snap/reflow/cwd Del
| $ printf 'y%.0s' $(seq 1 3000); echo do''ne
| yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
diff --git a/test/snapshots/respawn.golden b/test/snapshots/respawn.golden
index a0bb6ac9..02ed7601 100644
--- a/test/snapshots/respawn.golden
+++ b/test/snapshots/respawn.golden
@@ -1,5 +1,5 @@
== snap respawn grid=100x30 cursor=4,8
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/respawn/cwd Del NOR /tmp/pardes-snap/respawn/cwd Del
|
|
diff --git a/test/snapshots/restore.golden b/test/snapshots/restore.golden
index afb048d3..8e2ec9e6 100644
--- a/test/snapshots/restore.golden
+++ b/test/snapshots/restore.golden
@@ -1,5 +1,5 @@
== snap dumped grid=100x30 cursor=4,5
-|Kill Newcol Tutor Debug NextColor Dump Find Grep Restore /tmp/pardes-snap/restore/dump.zon
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help Restore /tmp/pardes-snap/restore/dump.zon
| TTY /tmp/pardes-snap/restore/cwd Del
| $ ls
| $ echo KEEP''ME
@@ -30,7 +30,7 @@
|
|
== snap restored grid=100x30 cursor=45,1
-|Kill Newcol Tutor Debug NextColor Dump Find Grep Restore /tmp/pardes-snap/restore/dump.zon
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help Restore /tmp/pardes-snap/restore/dump.zon
| INS /tmp/pardes-snap/restore/cwd Del Find /
|
|
diff --git a/test/snapshots/rsearch.golden b/test/snapshots/rsearch.golden
index c577456c..ee2a1cb4 100644
--- a/test/snapshots/rsearch.golden
+++ b/test/snapshots/rsearch.golden
@@ -1,5 +1,5 @@
== snap opened grid=180x30 cursor=7,2
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/rsearch/cwd/code.txt Save Del NOR /tmp/pardes-snap/rsearch/cwd Del NOR /tmp/pardes-snap/rsearch/cwd Del
| 1 run count_x now
| 2 open sub/dep.txt:3 here code.txt sub code.txt sub
@@ -30,7 +30,7 @@
|
|
== snap search grid=180x30 cursor=7,2
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/rsearch/cwd/code.txt Save Del NOR /tmp/pardes-snap/rsearch/cwd Del NOR /tmp/pardes-snap/rsearch/cwd Del
| 1 run count_x now
| 2 open sub/dep.txt:3 here code.txt sub code.txt sub
@@ -61,7 +61,7 @@
| 1 code.txt:1:5 run count_x now
| 2 code.txt:3:1 count_x again
== snap select grid=180x30 cursor=7,2
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/rsearch/cwd/code.txt Save Del NOR /tmp/pardes-snap/rsearch/cwd Del NOR /tmp/pardes-snap/rsearch/cwd Del
| 1 run count_x now
| 2 open sub/dep.txt:3 here code.txt sub code.txt sub
@@ -92,7 +92,7 @@
| 1 code.txt:1:5 run count_x now
| 2 code.txt:3:1 count_x again
== snap path-open grid=180x30 cursor=7,16
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/rsearch/cwd/code.txt Save Del NOR /tmp/pardes-snap/rsearch/cwd Del NOR /tmp/pardes-snap/rsearch/cwd Del
| 1 run count_x now
| 2 open sub/dep.txt:3 here code.txt sub code.txt sub
diff --git a/test/snapshots/scroll.golden b/test/snapshots/scroll.golden
index 4faf71b2..e1a44f1f 100644
--- a/test/snapshots/scroll.golden
+++ b/test/snapshots/scroll.golden
@@ -1,5 +1,5 @@
== snap bottom grid=100x30 cursor=4,15
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/scroll/cwd Del NOR /tmp/pardes-snap/scroll/cwd Del
| 188
| 189 s.txt
@@ -30,7 +30,7 @@
|
|
== snap wheel3 grid=100x30 cursor=4,15
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/scroll/cwd Del NOR /tmp/pardes-snap/scroll/cwd Del
| 185
| 186 s.txt
@@ -61,7 +61,7 @@
|
|
== snap gutter-up grid=100x30 cursor=4,15
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/scroll/cwd Del NOR /tmp/pardes-snap/scroll/cwd Del
| 178
| 179 s.txt
@@ -92,7 +92,7 @@
|
|
== snap gutter-down grid=100x30 cursor=4,15
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/scroll/cwd Del NOR /tmp/pardes-snap/scroll/cwd Del
| 180
| 181 s.txt
@@ -123,7 +123,7 @@
|
|
== snap wheel-down grid=100x30 cursor=4,15
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/scroll/cwd Del NOR /tmp/pardes-snap/scroll/cwd Del
| 181
| 182 s.txt
@@ -154,7 +154,7 @@
|
|
== style wheel-down
-|0: 0-47 #949494,#121212, 48-99 d,#121212,
+|0: 0-52 #949494,#121212, 53-99 d,#121212,
|1: 0-1 d,#626262, 2-36 #949494,#121212, 37-49 d,#121212, 50-51 d,#262626, 52-86 #949494,#121212, 87-99 d,#121212,
|2: 0-1 d,#121212, 2-49 #bdbdbd,#080808, 50-51 d,#444444, 52-99 #bdbdbd,#080808,
|3: 0-1 d,#121212, 2-49 #bdbdbd,#080808, 50-51 d,#444444, 52-99 #bdbdbd,#080808,
diff --git a/test/snapshots/scrolloff.golden b/test/snapshots/scrolloff.golden
index 9210d589..2264d902 100644
--- a/test/snapshots/scrolloff.golden
+++ b/test/snapshots/scrolloff.golden
@@ -1,5 +1,5 @@
== snap top grid=150x11 cursor=7,2
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/scrolloff/cwd/g.txt Save De NOR /tmp/pardes-snap/scrolloff/cwd Del NOR /tmp/pardes-snap/scrolloff/cwd Del
| 1 line 1
| 2 line 2 g.txt g.txt
@@ -11,7 +11,7 @@
| 8 line 8
| 9 line 9
== snap edge grid=150x11 cursor=7,7
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/scrolloff/cwd/g.txt Save De NOR /tmp/pardes-snap/scrolloff/cwd Del NOR /tmp/pardes-snap/scrolloff/cwd Del
| 1 line 1
| 2 line 2 g.txt g.txt
@@ -23,7 +23,7 @@
| 8 line 8
| 9 line 9
== snap scrolled1 grid=150x11 cursor=7,7
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/scrolloff/cwd/g.txt Save De NOR /tmp/pardes-snap/scrolloff/cwd Del NOR /tmp/pardes-snap/scrolloff/cwd Del
| 2 line 2
| 3 line 3 g.txt g.txt
@@ -35,7 +35,7 @@
| 9 line 9
| 10 line 10
== snap jdown grid=150x11 cursor=7,7
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/scrolloff/cwd/g.txt Save De NOR /tmp/pardes-snap/scrolloff/cwd Del NOR /tmp/pardes-snap/scrolloff/cwd Del
| 6 line 6
| 7 line 7 g.txt g.txt
@@ -47,7 +47,7 @@
| 13 line 13
| 14 line 14
== snap end grid=150x11 cursor=7,9
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/scrolloff/cwd/g.txt Save De NOR /tmp/pardes-snap/scrolloff/cwd Del NOR /tmp/pardes-snap/scrolloff/cwd Del
| 33 line 33
| 34 line 34 g.txt g.txt
@@ -59,7 +59,7 @@
| 40 line 40
| 41
== snap kup grid=150x11 cursor=7,5
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/scrolloff/cwd/g.txt Save De NOR /tmp/pardes-snap/scrolloff/cwd Del NOR /tmp/pardes-snap/scrolloff/cwd Del
| 29 line 29
| 30 line 30 g.txt g.txt
@@ -71,7 +71,7 @@
| 36 line 36
| 37 line 37
== snap top2 grid=150x11 cursor=7,2
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/scrolloff/cwd/g.txt Save De NOR /tmp/pardes-snap/scrolloff/cwd Del NOR /tmp/pardes-snap/scrolloff/cwd Del
| 1 line 1
| 2 line 2 g.txt g.txt
diff --git a/test/snapshots/selarg.golden b/test/snapshots/selarg.golden
index f20b80de..57cecdfd 100644
--- a/test/snapshots/selarg.golden
+++ b/test/snapshots/selarg.golden
@@ -1,5 +1,5 @@
== snap kept grid=100x30 cursor=6,2
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/selarg/cwd Del NOR /tmp/pardes-snap/selarg/cwd Del
| ZZARG ZZVEE ./c.sh
|
@@ -30,7 +30,7 @@
|
|
== snap crosspane grid=100x30 cursor=6,2
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/selarg/cwd Del NOR /tmp/pardes-snap/selarg/cwd Del
| ZZARG ZZVEE ./c.sh
|
@@ -61,7 +61,7 @@
|
|
== snap vselarg grid=100x30 cursor=12,2
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/selarg/cwd Del NOR /tmp/pardes-snap/selarg/cwd Del
| ZZARG ZZVEE ./c.sh
|
diff --git a/test/snapshots/shrinktag.golden b/test/snapshots/shrinktag.golden
index 3f2e1ecf..9bdd4073 100644
--- a/test/snapshots/shrinktag.golden
+++ b/test/snapshots/shrinktag.golden
@@ -1,5 +1,5 @@
== snap before grid=100x30 cursor=2,8
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/shrinktag/cwd Del NOR /tmp/pardes-snap/shrinktag/cwd Del
|
| w.txt w.txt
@@ -30,7 +30,7 @@
|
|
== snap shrunk grid=100x30 cursor=2,8
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/shrinktag/cwd Del NOR /tmp/pardes-snap/shrinktag/cwd Del
| NOR /tmp/pardes-snap/shrinktag/cwd Del
| w.txt
@@ -61,7 +61,7 @@
|
|
== snap move-preview grid=100x30 cursor=2,8
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/shrinktag/cwd Del NOR /tmp/pardes-snap/shrinktag/cwd Del
| NOR /tmp/pardes-snap/shrinktag/cwd Del
| w.txt
@@ -92,7 +92,7 @@
|
|
== snap restored grid=100x30 cursor=2,8
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/shrinktag/cwd Del NOR /tmp/pardes-snap/shrinktag/cwd Del
|
| w.txt w.txt
@@ -123,7 +123,7 @@
|
|
== snap bottom-shrunk grid=100x30 cursor=2,8
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/shrinktag/cwd Del NOR /tmp/pardes-snap/shrinktag/cwd Del
|
| w.txt w.txt
diff --git a/test/snapshots/splitparent.golden b/test/snapshots/splitparent.golden
index 614ec15e..37af9fab 100644
--- a/test/snapshots/splitparent.golden
+++ b/test/snapshots/splitparent.golden
@@ -1,5 +1,5 @@
== snap shrunk grid=100x30 cursor=4,3
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/splitparent/cwd Del NOR /tmp/pardes-snap/splitparent/cwd Del
| NOR /tmp/pardes-snap/splitparent/cwd Del
|
@@ -30,7 +30,7 @@
|
|
== snap swap-parent grid=100x30 cursor=4,7
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/splitparent/cwd Del NOR /tmp/pardes-snap/splitparent/cwd Del
| NOR /tmp/pardes-snap/splitparent/cwd Del
|
@@ -61,13 +61,13 @@
|
|
== snap tallest grid=100x5 cursor=54,4
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/splitparent/cwd Del NOR /tmp/pardes-snap/splitparent/cwd Del
| NOR /tmp/pardes-snap/splitparent/cwd Del
| NOR /tmp/pardes-snap/splitparent/cwd Del NOR /tmp/pardes-snap/splitparent/cwd Del
|
== snap regrown grid=100x30 cursor=54,18
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/splitparent/cwd Del NOR /tmp/pardes-snap/splitparent/cwd Del
| NOR /tmp/pardes-snap/splitparent/cwd Del
|
diff --git a/test/snapshots/syntax.golden b/test/snapshots/syntax.golden
index d92ba339..87333aaa 100644
--- a/test/snapshots/syntax.golden
+++ b/test/snapshots/syntax.golden
@@ -1,5 +1,5 @@
== snap zig-open grid=150x30 cursor=7,2
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/syntax/cwd/demo.zig Save De NOR /tmp/pardes-snap/syntax/cwd Del NOR /tmp/pardes-snap/syntax/cwd Del
| 1 const std = @import("std"); // greet
| 2 pub fn main() void { demo.zig demo.zig
@@ -30,7 +30,7 @@
|
|
== style zig-open
-|0: 0-47 #949494,#121212, 48-149 d,#121212,
+|0: 0-52 #949494,#121212, 53-149 d,#121212,
|1: 0-1 d,#626262, 2-49 #949494,#121212, 50-51 d,#262626, 52-86 #949494,#121212, 87-99 d,#121212, 100-101 d,#262626, 102-136 #949494,#121212, 137-149 d,#121212,
|2: 0-1 d,#444444, 2-6 #949494,#121212, 7-18 #bdbdbd,#080808, 19-25 #cf87e8,#080808,b 26-26 #bdbdbd,#080808, 27-31 #e3c78a,#080808, 32-34 #bdbdbd,#080808, 35-42 #ffffff,#080808,b 43-49 d,#080808, 50-51 d,#444444, 52-99 #bdbdbd,#080808, 100-101 d,#444444, 102-149 #bdbdbd,#080808,
|3: 0-1 d,#444444, 2-6 #626262,#080808, 7-10 #bdbdbd,#080808, 11-12 #cf87e8,#080808,b 13-26 #bdbdbd,#080808, 27-49 d,#080808, 50-51 d,#444444, 52-99 #bdbdbd,#080808, 100-101 d,#444444, 102-149 #bdbdbd,#080808,
@@ -61,7 +61,7 @@
|28: 0-1 d,#444444, 2-6 #626262,#080808, 7-49 d,#080808, 50-51 d,#444444, 52-99 #bdbdbd,#080808, 100-101 d,#444444, 102-149 #bdbdbd,#080808,
|29: 0-1 d,#444444, 2-6 #626262,#080808, 7-49 d,#080808, 50-51 d,#444444, 52-99 #bdbdbd,#080808, 100-101 d,#444444, 102-149 #bdbdbd,#080808,
== style colors-off
-|0: 0-47 #949494,#121212, 48-149 d,#121212,
+|0: 0-52 #949494,#121212, 53-149 d,#121212,
|1: 0-1 d,#626262, 2-49 #949494,#121212, 50-51 d,#262626, 52-86 #949494,#121212, 87-99 d,#121212, 100-101 d,#262626, 102-136 #949494,#121212, 137-149 d,#121212,
|2: 0-1 d,#444444, 2-6 #949494,#121212, 7-42 #bdbdbd,#080808, 43-49 d,#080808, 50-51 d,#444444, 52-99 d,#080808, 100-101 d,#444444, 102-149 d,#080808,
|3: 0-1 d,#444444, 2-6 #626262,#080808, 7-26 #bdbdbd,#080808, 27-49 d,#080808, 50-51 d,#444444, 52-59 #bdbdbd,#080808, 60-99 d,#080808, 100-101 d,#444444, 102-109 #bdbdbd,#080808, 110-149 d,#080808,
@@ -92,7 +92,7 @@
|28: 0-1 d,#444444, 2-6 #626262,#080808, 7-49 d,#080808, 50-51 d,#444444, 52-99 d,#080808, 100-101 d,#444444, 102-149 d,#080808,
|29: 0-1 d,#444444, 2-6 #626262,#080808, 7-49 d,#080808, 50-51 d,#444444, 52-99 d,#080808, 100-101 d,#444444, 102-149 d,#080808,
== style colors-on
-|0: 0-47 #949494,#121212, 48-149 d,#121212,
+|0: 0-52 #949494,#121212, 53-149 d,#121212,
|1: 0-1 d,#626262, 2-49 #949494,#121212, 50-51 d,#262626, 52-86 #949494,#121212, 87-99 d,#121212, 100-101 d,#262626, 102-136 #949494,#121212, 137-149 d,#121212,
|2: 0-1 d,#444444, 2-6 #949494,#121212, 7-18 #bdbdbd,#080808, 19-25 #cf87e8,#080808,b 26-26 #bdbdbd,#080808, 27-31 #e3c78a,#080808, 32-34 #bdbdbd,#080808, 35-42 #ffffff,#080808,b 43-49 d,#080808, 50-51 d,#444444, 52-99 #bdbdbd,#080808, 100-101 d,#444444, 102-149 #bdbdbd,#080808,
|3: 0-1 d,#444444, 2-6 #626262,#080808, 7-10 #bdbdbd,#080808, 11-12 #cf87e8,#080808,b 13-26 #bdbdbd,#080808, 27-49 d,#080808, 50-51 d,#444444, 52-99 #bdbdbd,#080808, 100-101 d,#444444, 102-149 #bdbdbd,#080808,
diff --git a/test/snapshots/tag.golden b/test/snapshots/tag.golden
index d351a4df..78dc9610 100644
--- a/test/snapshots/tag.golden
+++ b/test/snapshots/tag.golden
@@ -1,5 +1,5 @@
== snap tag-focus grid=150x30 cursor=34,1
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| INS /tmp/pardes-snap/tag/cwd Del NOR /tmp/pardes-snap/tag/cwd Del
|
| t.txt t.txt
@@ -30,7 +30,7 @@
|
|
== snap tag-typed grid=150x30 cursor=40,1
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| INS /tmp/pardes-snap/tag/cwd Del t.txt NOR /tmp/pardes-snap/tag/cwd Del
|
| t.txt t.txt
@@ -61,7 +61,7 @@
|
|
== snap tag-del grid=150x30 cursor=36,1
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| INS /tmp/pardes-snap/tag/cwd Del t NOR /tmp/pardes-snap/tag/cwd Del
|
| t.txt t.txt
@@ -92,7 +92,7 @@
|
|
== snap tag-exit grid=150x30 cursor=4,4
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/tag/cwd Del t.txt NOR /tmp/pardes-snap/tag/cwd Del
|
| t.txt t.txt
@@ -123,7 +123,7 @@
|
|
== snap tag-look grid=150x30 cursor=7,2
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/tag/cwd/t.txt Save Del INS /tmp/pardes-snap/tag/cwd Del t.txt NOR /tmp/pardes-snap/tag/cwd Del
| 1 ZZLOOKED
| t.txt t.txt
diff --git a/test/snapshots/tagcmd.golden b/test/snapshots/tagcmd.golden
index 55468539..0080f448 100644
--- a/test/snapshots/tagcmd.golden
+++ b/test/snapshots/tagcmd.golden
@@ -1,5 +1,5 @@
== snap edited grid=100x30 cursor=13,2
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/tagcmd/cwd/c.txt Save Del NOR /tmp/pardes-snap/tagcmd/cwd Del
| 1 ZZEDITline 1
| 2 line 2 c.txt
@@ -30,7 +30,7 @@
|
|
== snap colon grid=100x30 cursor=39,1
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/tagcmd/cwd/c.txt Save Del NOR /tmp/pardes-snap/tagcmd/cwd Del
| 1 ZZEDITline 1
| 2 line 2 c.txt
@@ -61,7 +61,7 @@
|
|
== snap word grid=100x30 cursor=44,1
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/tagcmd/cwd/c.txt Save Del NOR /tmp/pardes-snap/tagcmd/cwd Del
| 1 ZZEDITline 1
| 2 line 2 c.txt
@@ -92,7 +92,7 @@
|
|
== snap saved grid=100x30 cursor=13,2
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/tagcmd/cwd/c.txt Save Del NOR /tmp/pardes-snap/tagcmd/cwd Del
| 1 ZZEDITline 1
| 2 line 2 c.txt
@@ -132,7 +132,7 @@ line 6
== end file
== snap escaped grid=100x30 cursor=13,2
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/tagcmd/cwd/c.txt Save Del NOR /tmp/pardes-snap/tagcmd/cwd Del
| 1 ZZEDITline 1
| 2 line 2 c.txt
diff --git a/test/snapshots/tagnav.golden b/test/snapshots/tagnav.golden
index bd87b811..e1bc7643 100644
--- a/test/snapshots/tagnav.golden
+++ b/test/snapshots/tagnav.golden
@@ -1,5 +1,5 @@
== snap start grid=100x30 cursor=7,2
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/tagnav/cwd/w.txt Save Del NOR /tmp/pardes-snap/tagnav/cwd Del
| 1 alpha
| 2 beta w.txt
@@ -30,7 +30,7 @@
|
|
== snap colon grid=100x30 cursor=39,1
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/tagnav/cwd/w.txt Save Del NOR /tmp/pardes-snap/tagnav/cwd Del
| 1 alpha
| 2 beta w.txt
@@ -61,7 +61,7 @@
|
|
== snap right-tag grid=100x30 cursor=83,1
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/tagnav/cwd/w.txt Save Del NOR /tmp/pardes-snap/tagnav/cwd Del
| 1 alpha
| 2 beta w.txt
@@ -92,7 +92,7 @@
|
|
== snap left-tag grid=100x30 cursor=39,1
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/tagnav/cwd/w.txt Save Del NOR /tmp/pardes-snap/tagnav/cwd Del
| 1 alpha
| 2 beta w.txt
@@ -123,7 +123,7 @@
|
|
== snap down-tag grid=100x30 cursor=33,16
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/tagnav/cwd/w.txt Save Del NOR /tmp/pardes-snap/tagnav/cwd Del
| 1 alpha
| 2 beta w.txt
@@ -154,7 +154,7 @@
|
|
== snap up-tag grid=100x30 cursor=39,1
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/tagnav/cwd/w.txt Save Del NOR /tmp/pardes-snap/tagnav/cwd Del
| 1 alpha
| 2 beta w.txt
@@ -185,7 +185,7 @@
|
|
== snap up-edge grid=100x30 cursor=0,0
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/tagnav/cwd/w.txt Save Del NOR /tmp/pardes-snap/tagnav/cwd Del
| 1 alpha
| 2 beta w.txt
@@ -216,7 +216,7 @@
|
|
== snap topbar-word grid=100x30 cursor=4,0
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/tagnav/cwd/w.txt Save Del NOR /tmp/pardes-snap/tagnav/cwd Del
| 1 alpha
| 2 beta w.txt
@@ -247,7 +247,7 @@
|
|
== snap topbar-graphemes grid=100x30 cursor=6,0
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/tagnav/cwd/w.txt Save Del NOR /tmp/pardes-snap/tagnav/cwd Del
| 1 alpha
| 2 beta w.txt
@@ -278,7 +278,7 @@
|
|
== snap back-down grid=100x30 cursor=39,1
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/tagnav/cwd/w.txt Save Del NOR /tmp/pardes-snap/tagnav/cwd Del
| 1 alpha
| 2 beta w.txt
@@ -309,7 +309,7 @@
|
|
== snap arrows-still-motion grid=100x30 cursor=41,1
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/tagnav/cwd/w.txt Save Del NOR /tmp/pardes-snap/tagnav/cwd Del
| 1 alpha
| 2 beta w.txt
@@ -340,7 +340,7 @@
|
|
== snap back-to-body grid=100x30 cursor=7,2
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/tagnav/cwd/w.txt Save Del NOR /tmp/pardes-snap/tagnav/cwd Del
| 1 alpha
| 2 beta w.txt
@@ -371,7 +371,7 @@
|
|
== snap tty-on grid=100x30 cursor=54,4
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/tagnav/cwd/w.txt Save Del TTY /tmp/pardes-snap/tagnav/cwd Del
| 1 alpha $ ls
| 2 beta w.txt
@@ -402,7 +402,7 @@
|
|
== snap tty-tag grid=100x30 cursor=83,1
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/tagnav/cwd/w.txt Save Del NOR /tmp/pardes-snap/tagnav/cwd Del
| 1 alpha
| 2 beta w.txt
@@ -433,7 +433,7 @@
|
|
== snap tty-restored grid=100x30 cursor=54,4
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/tagnav/cwd/w.txt Save Del TTY /tmp/pardes-snap/tagnav/cwd Del
| 1 alpha $ ls
| 2 beta w.txt
@@ -463,8 +463,8 @@
|
|
|
-== snap topbar-dollar grid=100x30 cursor=47,0
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+== snap topbar-dollar grid=100x30 cursor=52,0
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/tagnav/cwd/w.txt Save Del TTY /tmp/pardes-snap/tagnav/cwd Del
| 1 alpha $ ls
| 2 beta w.txt
@@ -494,9 +494,9 @@
|
|
|
-== snap topbar-exec grid=100x30 cursor=47,0
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
-| INS /tmp/pardes-snap/tagnav/cwd/w.txt Save Del G TTY /tmp/pardes-snap/tagnav/cwd Del
+== snap topbar-exec grid=100x30 cursor=7,10
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
+| NOR /tmp/pardes-snap/tagnav/cwd/w.txt Save Del TTY /tmp/pardes-snap/tagnav/cwd Del
| 1 alpha $ ls
| 2 beta w.txt
| 3 gamma $
@@ -504,13 +504,13 @@
|
|
|
-|
-|
-|
-|
-|
-|
-|
+| NOR /tmp/pardes-snap/tagnav/cwd/+Help Del
+| 1 pardes builtins - SPC then the keys,
+| 2 or execute the name anywhere
+| 3
+| 4 SPC ? Help
+| 5 SPC c d Delcol
+| 6 SPC c n Newcol
| NOR /tmp/pardes-snap/tagnav/cwd Del
|
| w.txt
@@ -525,9 +525,9 @@
|
|
|
-== snap topbar-restore-word grid=100x30 cursor=47,0
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
-| INS /tmp/pardes-snap/tagnav/cwd/w.txt Save Del G TTY /tmp/pardes-snap/tagnav/cwd Del
+== snap topbar-restore-word grid=100x30 cursor=40,1
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
+| NOR /tmp/pardes-snap/tagnav/cwd/w.txt Save Del TTY /tmp/pardes-snap/tagnav/cwd Del
| 1 alpha $ ls
| 2 beta w.txt
| 3 gamma $
@@ -535,13 +535,13 @@
|
|
|
-|
-|
-|
-|
-|
-|
-|
+| NOR /tmp/pardes-snap/tagnav/cwd/+Help Del
+| 1 pardes builtins - SPC then the keys,
+| 2 or execute the name anywhere
+| 3
+| 4 SPC ? Help
+| 5 SPC c d Delcol
+| 6 SPC c n Newcol
| NOR /tmp/pardes-snap/tagnav/cwd Del
|
| w.txt
@@ -557,22 +557,22 @@
|
|
== snap topbar-restored grid=100x30 cursor=7,2
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/tagnav/cwd/w.txt Save Del TTY /tmp/pardes-snap/tagnav/cwd Del
| 1 alpha $ ls
| 2 beta w.txt
| 3 gamma $
|
|
-|
-|
-|
-|
-|
-|
-|
| NOR /tmp/pardes-snap/tagnav/cwd/+Search Del
| 1
+| NOR /tmp/pardes-snap/tagnav/cwd/+Help Del
+| 1 pardes builtins - SPC then the keys,
+| 2 or execute the name anywhere
+| 3
+| 4 SPC ? Help
+| 5 SPC c d Delcol
+| 6 SPC c n Newcol
| NOR /tmp/pardes-snap/tagnav/cwd Del
|
| w.txt
diff --git a/test/snapshots/tagpath.golden b/test/snapshots/tagpath.golden
index e6fee53f..0f194ce4 100644
--- a/test/snapshots/tagpath.golden
+++ b/test/snapshots/tagpath.golden
@@ -1,5 +1,5 @@
== snap start grid=100x30 cursor=7,2
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/tagpath/cwd/c.txt Save Del NOR /tmp/pardes-snap/tagpath/cwd Del
| 1 line 1
| 2 line 2 c.txt
@@ -30,7 +30,7 @@
|
|
== snap colon grid=100x30 cursor=40,1
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/tagpath/cwd/c.txt Save Del NOR /tmp/pardes-snap/tagpath/cwd Del
| 1 line 1
| 2 line 2 c.txt
@@ -61,7 +61,7 @@
|
|
== snap col0 grid=100x30 cursor=2,1
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/tagpath/cwd/c.txt Save Del NOR /tmp/pardes-snap/tagpath/cwd Del
| 1 line 1
| 2 line 2 c.txt
@@ -92,7 +92,7 @@
|
|
== snap sel-nor grid=100x30 cursor=5,1
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/tagpath/cwd/c.txt Save Del NOR /tmp/pardes-snap/tagpath/cwd Del
| 1 line 1
| 2 line 2 c.txt
@@ -123,7 +123,7 @@
|
|
== snap sel-path grid=100x30 cursor=39,1
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/tagpath/cwd/c.txt Save Del NOR /tmp/pardes-snap/tagpath/cwd Del
| 1 line 1
| 2 line 2 c.txt
@@ -154,7 +154,7 @@
|
|
== style sel-path
-|0: 0-47 #949494,#121212, 48-99 d,#121212,
+|0: 0-52 #949494,#121212, 53-99 d,#121212,
|1: 0-1 d,#626262, 2-4 #949494,#121212, 5-39 #d8c8a8,#4a3a1e, 40-48 #949494,#121212, 49-49 d,#121212, 50-51 d,#262626, 52-87 #949494,#121212, 88-99 d,#121212,
|2: 0-1 d,#444444, 2-6 #626262,#080808, 7-12 #bdbdbd,#080808, 13-49 d,#080808, 50-51 d,#444444, 52-99 #bdbdbd,#080808,
|3: 0-1 d,#444444, 2-6 #626262,#080808, 7-12 #bdbdbd,#080808, 13-49 d,#080808, 50-51 d,#444444, 52-99 #bdbdbd,#080808,
@@ -185,7 +185,7 @@
|28: 0-1 d,#444444, 2-6 #626262,#080808, 7-49 d,#080808, 50-51 d,#444444, 52-99 #bdbdbd,#080808,
|29: 0-1 d,#444444, 2-6 #626262,#080808, 7-49 d,#080808, 50-51 d,#444444, 52-99 #bdbdbd,#080808,
== snap yanked-path grid=100x30 cursor=42,2
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/tagpath/cwd/c.txt Save Del NOR /tmp/pardes-snap/tagpath/cwd Del
| 1 l /tmp/pardes-snap/tagpath/cwd/c.txtine 1
| 2 line 2 c.txt
@@ -216,7 +216,7 @@
|
|
== snap drag-cross grid=100x30 cursor=45,1
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| INS /tmp/pardes-snap/tagpath/cwd/c.txt Save Del NOR /tmp/pardes-snap/tagpath/cwd Del
| 1 l /tmp/pardes-snap/tagpath/cwd/c.txtine 1
| 2 line 2 c.txt
@@ -247,7 +247,7 @@
|
|
== style drag-cross
-|0: 0-47 #949494,#121212, 48-99 d,#121212,
+|0: 0-52 #949494,#121212, 53-99 d,#121212,
|1: 0-1 d,#626262, 2-10 #949494,#121212, 11-45 #d8c8a8,#4a3a1e, 46-48 #949494,#121212, 49-49 d,#121212, 50-51 d,#262626, 52-87 #949494,#121212, 88-99 d,#121212,
|2: 0-1 d,#444444, 2-6 #626262,#080808, 7-47 #bdbdbd,#080808, 48-49 d,#080808, 50-51 d,#444444, 52-99 #bdbdbd,#080808,
|3: 0-1 d,#444444, 2-6 #626262,#080808, 7-12 #bdbdbd,#080808, 13-49 d,#080808, 50-51 d,#444444, 52-99 #bdbdbd,#080808,
@@ -278,7 +278,7 @@
|28: 0-1 d,#444444, 2-6 #626262,#080808, 7-49 d,#080808, 50-51 d,#444444, 52-99 #bdbdbd,#080808,
|29: 0-1 d,#444444, 2-6 #626262,#080808, 7-49 d,#080808, 50-51 d,#444444, 52-99 #bdbdbd,#080808,
== snap path-inert grid=100x30 cursor=11,1
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| INS /tmp/pardes-snap/tagpath/cwd/c.txt Save Del NOR /tmp/pardes-snap/tagpath/cwd Del
| 1 l /tmp/pardes-snap/tagpath/cwd/c.txtine 1
| 2 line 2 c.txt
diff --git a/test/snapshots/theme.golden b/test/snapshots/theme.golden
index 8f61a888..520258ff 100644
--- a/test/snapshots/theme.golden
+++ b/test/snapshots/theme.golden
@@ -1,5 +1,5 @@
== snap helix grid=100x30 cursor=4,4
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/theme/cwd Del NOR /tmp/pardes-snap/theme/cwd Del
|
| t.txt t.txt
@@ -30,7 +30,7 @@
|
|
== style helix
-|0: 0-47 #949494,#121212, 48-99 d,#121212,
+|0: 0-52 #949494,#121212, 53-99 d,#121212,
|1: 0-1 d,#626262, 2-35 #949494,#121212, 36-49 d,#121212, 50-51 d,#262626, 52-85 #949494,#121212, 86-99 d,#121212,
|2: 0-1 d,#444444, 2-49 #bdbdbd,#080808, 50-51 d,#444444, 52-99 #bdbdbd,#080808,
|3: 0-1 d,#444444, 2-49 #bdbdbd,#080808, 50-51 d,#444444, 52-99 #bdbdbd,#080808,
@@ -61,7 +61,7 @@
|28: 0-1 d,#444444, 2-49 #bdbdbd,#080808, 50-51 d,#444444, 52-99 #bdbdbd,#080808,
|29: 0-1 d,#444444, 2-49 #bdbdbd,#080808, 50-51 d,#444444, 52-99 #bdbdbd,#080808,
== snap dark grid=100x30 cursor=4,4
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/theme/cwd Del NOR /tmp/pardes-snap/theme/cwd Del
|
| t.txt t.txt
@@ -92,7 +92,7 @@
|
|
== style dark
-|0: 0-47 #969696,#2c2a3e, 48-99 d,#2c2a3e,
+|0: 0-52 #969696,#2c2a3e, 53-99 d,#2c2a3e,
|1: 0-1 d,#6e4fd0, 2-35 #969696,#2c2a3e, 36-49 d,#2c2a3e, 50-51 d,#383c54, 52-85 #969696,#2c2a3e, 86-99 d,#2c2a3e,
|2: 0-1 d,#525252, 2-49 d,d, 50-51 d,#525252, 52-99 d,d,
|3: 0-1 d,#525252, 2-49 d,d, 50-51 d,#525252, 52-99 d,d,
@@ -123,7 +123,7 @@
|28: 0-1 d,#525252, 2-49 d,d, 50-51 d,#525252, 52-99 d,d,
|29: 0-1 d,#525252, 2-49 d,d, 50-51 d,#525252, 52-99 d,d,
== snap acme grid=100x30 cursor=4,4
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/theme/cwd Del NOR /tmp/pardes-snap/theme/cwd Del
|
| t.txt t.txt
@@ -154,7 +154,7 @@
|
|
== style acme
-|0: 0-47 #000000,#eaffff, 48-99 d,#eaffff,
+|0: 0-52 #000000,#eaffff, 53-99 d,#eaffff,
|1: 0-1 d,#6e4fd0, 2-35 #000000,#eaffff, 36-49 d,#eaffff, 50-51 d,#383c54, 52-85 #000000,#eaffff, 86-99 d,#eaffff,
|2: 0-1 d,#ffffea, 2-49 #000000,#ffffea, 50-51 d,#ffffea, 52-99 #000000,#ffffea,
|3: 0-1 d,#ffffea, 2-49 #000000,#ffffea, 50-51 d,#ffffea, 52-99 #000000,#ffffea,
@@ -185,7 +185,7 @@
|28: 0-1 d,#ffffea, 2-49 #000000,#ffffea, 50-51 d,#ffffea, 52-99 #000000,#ffffea,
|29: 0-1 d,#ffffea, 2-49 #000000,#ffffea, 50-51 d,#ffffea, 52-99 #000000,#ffffea,
== snap colors-off grid=100x30 cursor=4,4
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/theme/cwd Del NOR /tmp/pardes-snap/theme/cwd Del
|
| t.txt t.txt
@@ -216,7 +216,7 @@
|
|
== style colors-off
-|0: 0-47 #000000,#eaffff, 48-99 d,#eaffff,
+|0: 0-52 #000000,#eaffff, 53-99 d,#eaffff,
|1: 0-1 d,#6e4fd0, 2-35 #000000,#eaffff, 36-49 d,#eaffff, 50-51 d,#383c54, 52-85 #000000,#eaffff, 86-99 d,#eaffff,
|2: 0-99 d,#ffffea,
|3: 0-1 d,#ffffea, 2-6 #000000,#ffffea, 7-51 d,#ffffea, 52-56 #000000,#ffffea, 57-99 d,#ffffea,
@@ -247,7 +247,7 @@
|28: 0-99 d,#ffffea,
|29: 0-99 d,#ffffea,
== snap helix-again grid=100x30 cursor=4,4
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/theme/cwd Del NOR /tmp/pardes-snap/theme/cwd Del
|
| t.txt t.txt
@@ -278,7 +278,7 @@
|
|
== style helix-again
-|0: 0-47 #949494,#121212, 48-99 d,#121212,
+|0: 0-52 #949494,#121212, 53-99 d,#121212,
|1: 0-1 d,#626262, 2-35 #949494,#121212, 36-49 d,#121212, 50-51 d,#262626, 52-85 #949494,#121212, 86-99 d,#121212,
|2: 0-1 d,#444444, 2-49 #bdbdbd,#080808, 50-51 d,#444444, 52-99 #bdbdbd,#080808,
|3: 0-1 d,#444444, 2-49 #bdbdbd,#080808, 50-51 d,#444444, 52-99 #bdbdbd,#080808,
diff --git a/test/snapshots/tinywin.golden b/test/snapshots/tinywin.golden
index da6a7ad1..3ffdaf9d 100644
--- a/test/snapshots/tinywin.golden
+++ b/test/snapshots/tinywin.golden
@@ -1,5 +1,5 @@
== snap stacked grid=100x30 cursor=4,14
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| TTY /tmp/pardes-snap/tinywin/cwd Del
| $
| NOR /tmp/pardes-snap/tinywin/cwd Del
@@ -30,11 +30,11 @@
|
|
== snap shrunk grid=60x3 cursor=59,2
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| TTY /tmp/pardes-snap/tinywin/cwd Del
| NOR /tmp/pardes-snap/tinywin/cwd Del
== snap columns grid=100x30 cursor=79,3
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| TTY /tmp/pardes-snap/ti NOR /tmp/pardes-snap/ti NOR /tmp/pardes-snap/ti NOR /tmp/pardes-snap/ti
| $
| NOR /tmp/pardes-snap/ti
diff --git a/test/snapshots/tty.golden b/test/snapshots/tty.golden
index 471e81cf..34a34cd3 100644
--- a/test/snapshots/tty.golden
+++ b/test/snapshots/tty.golden
@@ -1,5 +1,5 @@
== snap tty-on grid=100x30 cursor=4,4
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| TTY /tmp/pardes-snap/tty/cwd Del NOR /tmp/pardes-snap/tty/cwd Del
| $ ls
| m.txt m.txt
@@ -30,7 +30,7 @@
|
|
== snap tty-echo grid=100x30 cursor=4,6
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| TTY /tmp/pardes-snap/tty/cwd Del NOR /tmp/pardes-snap/tty/cwd Del
| $ ls
| m.txt m.txt
@@ -61,7 +61,7 @@
|
|
== snap tty-off grid=100x30 cursor=4,6
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/tty/cwd Del NOR /tmp/pardes-snap/tty/cwd Del
|
| m.txt m.txt
@@ -92,7 +92,7 @@
|
|
== snap shift-esc-on grid=100x30 cursor=4,6
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| TTY /tmp/pardes-snap/tty/cwd Del NOR /tmp/pardes-snap/tty/cwd Del
| $ ls
| m.txt m.txt
@@ -123,7 +123,7 @@
|
|
== snap shift-esc-off grid=100x30 cursor=4,6
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/tty/cwd Del NOR /tmp/pardes-snap/tty/cwd Del
|
| m.txt m.txt
diff --git a/test/snapshots/ttyclick.golden b/test/snapshots/ttyclick.golden
index 62f540af..842fa7ff 100644
--- a/test/snapshots/ttyclick.golden
+++ b/test/snapshots/ttyclick.golden
@@ -1,5 +1,5 @@
== snap tty-bodyclick grid=100x30 cursor=4,4
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| TTY /tmp/pardes-snap/ttyclick/cwd Del NOR /tmp/pardes-snap/ttyclick/cwd Del
| $ ls
| probe.txt probe.txt
@@ -30,7 +30,7 @@
|
|
== snap tty-tagedit grid=100x30 cursor=39,1
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| INS /tmp/pardes-snap/ttyclick/cwd Del NOR /tmp/pardes-snap/ttyclick/cwd Del
|
| probe.txt probe.txt
@@ -61,7 +61,7 @@
|
|
== snap tty-tagexit grid=100x30 cursor=4,4
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| TTY /tmp/pardes-snap/ttyclick/cwd Del NOR /tmp/pardes-snap/ttyclick/cwd Del
| $ ls
| probe.txt probe.txt
@@ -92,7 +92,7 @@
|
|
== snap ins-bodyclick grid=100x30 cursor=11,3
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| INS /tmp/pardes-snap/ttyclick/cwd Del NOR /tmp/pardes-snap/ttyclick/cwd Del
|
| probe.txt probe.txt
diff --git a/test/snapshots/ttyedit.golden b/test/snapshots/ttyedit.golden
index febffe16..89e6c02f 100644
--- a/test/snapshots/ttyedit.golden
+++ b/test/snapshots/ttyedit.golden
@@ -1,5 +1,5 @@
== snap before grid=100x30 cursor=7,6
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/ttyedit/cwd Del NOR /tmp/pardes-snap/ttyedit/cwd Del
|
| words.txt words.txt
@@ -30,7 +30,7 @@
|
|
== snap split grid=100x30 cursor=2,7
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| INS /tmp/pardes-snap/ttyedit/cwd Del NOR /tmp/pardes-snap/ttyedit/cwd Del
|
| words.txt words.txt
@@ -61,7 +61,7 @@
|
|
== snap opened grid=100x30 cursor=6,8
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/ttyedit/cwd Del NOR /tmp/pardes-snap/ttyedit/cwd Del
|
| words.txt words.txt
@@ -92,7 +92,7 @@
|
|
== snap joined grid=100x30 cursor=10,7
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/ttyedit/cwd Del NOR /tmp/pardes-snap/ttyedit/cwd Del
|
| words.txt words.txt
@@ -123,7 +123,7 @@
|
|
== snap undone grid=100x30 cursor=7,6
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/ttyedit/cwd Del NOR /tmp/pardes-snap/ttyedit/cwd Del
|
| words.txt words.txt
diff --git a/test/snapshots/ttyfollow.golden b/test/snapshots/ttyfollow.golden
index 6c993bb5..997f37be 100644
--- a/test/snapshots/ttyfollow.golden
+++ b/test/snapshots/ttyfollow.golden
@@ -1,5 +1,5 @@
== snap held-pre grid=100x30 cursor=4,15
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/ttyfollow/cwd Del NOR /tmp/pardes-snap/ttyfollow/cwd Del
| 185
| 186 s.txt
@@ -30,7 +30,7 @@
|
|
== snap held-post grid=100x30 cursor=54,7
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/ttyfollow/cwd Del TTY /tmp/pardes-snap/ttyfollow/cwd Del
| 185 $ ls
| 186 s.txt
@@ -61,7 +61,7 @@
|
|
== snap tty-follows grid=100x30 cursor=4,15
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| TTY /tmp/pardes-snap/ttyfollow/cwd Del TTY /tmp/pardes-snap/ttyfollow/cwd Del
| 288 $ ls
| 289 s.txt
diff --git a/test/snapshots/ttyhelp.golden b/test/snapshots/ttyhelp.golden
new file mode 100644
index 00000000..6cb6d930
--- /dev/null
+++ b/test/snapshots/ttyhelp.golden
@@ -0,0 +1,93 @@
+== snap boot grid=100x30 cursor=4,2
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
+| TTY /tmp/pardes-snap/ttyhelp/cwd Del
+| $
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+== snap helped grid=100x30 cursor=7,4
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
+| TTY /tmp/pardes-snap/ttyhelp/cwd Del
+| $
+| NOR /tmp/pardes-snap/ttyhelp/cwd/+Help Del
+| 1 pardes builtins - SPC then the keys,
+| 2 or execute the name anywhere
+| 3
+| 4 SPC ? Help
+| 5 SPC c d Delcol
+| 6 SPC c n Newcol
+| 7 SPC d Del
+| 8 SPC f f Find
+| 9 SPC f g Grep
+| 10 SPC f s Save
+| 11 SPC h t Tutor
+| 12 SPC k Kill
+| 13 SPC l D WsDiagnostics
+| 14 SPC l S WsSymbols
+| 15 SPC l a CodeAction
+| 16 SPC l d Diagnostics
+| 17 SPC l h SelectRefs
+| 18 SPC l i Lspinfo
+| 19 SPC l k Hover
+| 20 SPC l r Rename
+| 21 SPC l s Symbols
+| 22 SPC l w Lspwhy
+| 23 SPC s d Dump
+| 24 SPC s r Restore
+| 25 SPC t a Ascii
+| 26 SPC t c Colors
+== snap leaderworks grid=100x30 cursor=7,4
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
+| TTY /tmp/pardes-snap/ttyhelp/cwd Del
+| $
+| NOR /tmp/pardes-snap/ttyhelp/cwd/+Help Del
+| 1 pardes builtins - SPC then the keys,
+| 2 or execute the name anywhere
+| 3
+| 4 SPC ? Help
+| 5 SPC c d Delcol
+| 6 SPC c n Newcol
+| 7 SPC d Del
+| 8 SPC f f Find
+| 9 SPC f g Grep
+| 10 SPC f s Save
+| 11 SPC h t Tutor
+| 12 SPC k Kill
+| 13 SPC l D WsDiagnostics
+| 14 SPC l S WsSymbols
+| 15 SPC l a CodeAction
+| 16 SPC l d Diagnostics
+| 17 SPC l h SelectRefs
+| 18 SPC l i Lspinfo
+| 19 SPC l k Hover
+| 20 SPC l r Rename
+| 21 SPC l s Symbols
+| 22 SPC l w Lspwhy
+| 23 SPC s d Dump
+| 24 SPC s r Restore
+| 25 SPC t a Ascii
+| 26 SPC t c Colors
diff --git a/test/snapshots/ttyhelp.snap b/test/snapshots/ttyhelp.snap
new file mode 100644
index 00000000..48323189
--- /dev/null
+++ b/test/snapshots/ttyhelp.snap
@@ -0,0 +1,21 @@
+# bare boot = tty mode: SPC belongs to the shell, so the topbar Help word is
+# the only route to the command list. Row 0 is not a pane, so a middle-click
+# there is dispatched before any pane's mode is consulted.
+start 30 100
+wait 8000 Kill Newcol
+stable 700 20000
+snap boot
+press middle 51 1
+release middle 51 1
+wait 10000 pardes builtins
+stable 700 15000
+snap helped
+# and the shell is untouched: still TTY, still at its prompt. The click went to
+# row 0, which is not a pane, so the terminal never saw it.
+key c-b
+stable 600 10000
+key space
+key ?
+wait 10000 SPC c n
+stable 700 15000
+snap leaderworks
diff --git a/test/snapshots/ttylook.golden b/test/snapshots/ttylook.golden
index 3bdbe3ed..24c8124a 100644
--- a/test/snapshots/ttylook.golden
+++ b/test/snapshots/ttylook.golden
@@ -1,5 +1,5 @@
== snap tok1 grid=120x30 cursor=2,3
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/ttylook/cwd Del NOR /tmp/pardes-snap/ttylook/cwd Del
|
| big.txt plain.txt sub big.txt plain.txt sub
@@ -30,7 +30,7 @@
|
|
== style tok1
-|0: 0-47 #949494,#121212, 48-119 d,#121212,
+|0: 0-52 #949494,#121212, 53-119 d,#121212,
|1: 0-1 d,#626262, 2-37 #949494,#121212, 38-59 d,#121212, 60-61 d,#262626, 62-97 #949494,#121212, 98-119 d,#121212,
|2: 0-1 d,#444444, 2-59 #bdbdbd,#080808, 60-61 d,#444444, 62-119 #bdbdbd,#080808,
|3: 0-1 d,#444444, 2-8 #d8c8a8,#4a3a1e, 9-59 #bdbdbd,#080808, 60-61 d,#444444, 62-119 #bdbdbd,#080808,
@@ -61,7 +61,7 @@
|28: 0-1 d,#444444, 2-59 #bdbdbd,#080808, 60-61 d,#444444, 62-119 #bdbdbd,#080808,
|29: 0-1 d,#444444, 2-59 #bdbdbd,#080808, 60-61 d,#444444, 62-119 #bdbdbd,#080808,
== snap tok2 grid=120x30 cursor=11,3
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/ttylook/cwd Del NOR /tmp/pardes-snap/ttylook/cwd Del
|
| big.txt plain.txt sub big.txt plain.txt sub
@@ -92,7 +92,7 @@
|
|
== snap tokback grid=120x30 cursor=2,3
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/ttylook/cwd Del NOR /tmp/pardes-snap/ttylook/cwd Del
|
| big.txt plain.txt sub big.txt plain.txt sub
@@ -123,7 +123,7 @@
|
|
== snap insert grid=120x30 cursor=4,3
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/ttylook/cwd Del NOR /tmp/pardes-snap/ttylook/cwd Del
|
| nnbig.txt plain.txt sub big.txt plain.txt sub
@@ -154,7 +154,7 @@
|
|
== snap tok3 grid=120x30 cursor=22,3
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/ttylook/cwd Del NOR /tmp/pardes-snap/ttylook/cwd Del
|
| big.txt plain.txt sub big.txt plain.txt sub
@@ -185,7 +185,7 @@
|
|
== snap diropen grid=120x30 cursor=4,7
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/ttylook/cwd Del NOR /tmp/pardes-snap/ttylook/cwd Del
|
| big.txt plain.txt sub big.txt plain.txt sub
@@ -216,7 +216,7 @@
|
|
== snap noop grid=120x30 cursor=4,7
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/ttylook/cwd Del NOR /tmp/pardes-snap/ttylook/cwd Del
|
| big.txt plain.txt sub big.txt plain.txt sub
@@ -247,7 +247,7 @@
|
|
== snap fileopen grid=120x30 cursor=7,2
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/ttylook/cwd/big.t NOR /tmp/pardes-snap/ttylook/cwd Del NOR /tmp/pardes-snap/ttylook/cwd Del
| 1 line 1
| 2 line 2 big.txt plain.txt sub big.txt plain.txt sub
diff --git a/test/snapshots/ttyonly.golden b/test/snapshots/ttyonly.golden
index 2a52eab1..a1bdb852 100644
--- a/test/snapshots/ttyonly.golden
+++ b/test/snapshots/ttyonly.golden
@@ -1,5 +1,5 @@
== snap ttyonly grid=100x30 cursor=4,4
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| TTY /tmp/pardes-snap/ttyonly/cwd Del
| $ echo TTY''ONLY
| TTYONLY
@@ -30,7 +30,7 @@
|
|
== style ttyonly
-|0: 0-47 #949494,#121212, 48-99 d,#121212,
+|0: 0-52 #949494,#121212, 53-99 d,#121212,
|1: 0-1 d,#626262, 2-37 #949494,#121212, 38-99 d,#121212,
|2: 0-1 d,#444444, 2-99 #bdbdbd,#080808,
|3: 0-1 d,#444444, 2-99 #bdbdbd,#080808,
diff --git a/test/snapshots/tutor.golden b/test/snapshots/tutor.golden
index d6a51e82..6618f39d 100644
--- a/test/snapshots/tutor.golden
+++ b/test/snapshots/tutor.golden
@@ -1,5 +1,5 @@
== snap tutor grid=150x30 cursor=7,2
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /Tutor Save Del NOR /tmp/pardes-snap/tutor/cwd Del NOR /tmp/pardes-snap/tutor/cwd Del
| 1
| 2 PARDES TUTOR
diff --git a/test/snapshots/winch.golden b/test/snapshots/winch.golden
index 97ab4e76..ff73b6d2 100644
--- a/test/snapshots/winch.golden
+++ b/test/snapshots/winch.golden
@@ -1,5 +1,5 @@
== snap storm grid=100x30 cursor=4,6
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| TTY /tmp/pardes-snap/winch/cwd Del NOR /tmp/pardes-snap/winch/cwd Del
| $ ls
| $ for i in $(seq 600); do kill -WINCH $PPID; don
@@ -30,7 +30,7 @@
|
|
== snap resized grid=106x34 cursor=4,6
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| TTY /tmp/pardes-snap/winch/cwd Del NOR /tmp/pardes-snap/winch/cwd Del
| $ ls
| $ for i in $(seq 600); do kill -WINCH $PPID; done;
diff --git a/test/snapshots/windownav.golden b/test/snapshots/windownav.golden
index ada71876..421d9bfe 100644
--- a/test/snapshots/windownav.golden
+++ b/test/snapshots/windownav.golden
@@ -1,5 +1,5 @@
== snap start grid=100x30 cursor=7,2
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/windownav/cwd/w.txt Save De NOR /tmp/pardes-snap/windownav/cwd Del
| 1 alpha
| 2 beta w.txt
@@ -30,7 +30,7 @@
|
|
== snap to-term grid=100x30 cursor=54,4
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/windownav/cwd/w.txt Save De NOR /tmp/pardes-snap/windownav/cwd Del
| 1 alpha
| 2 beta w.txt
@@ -61,7 +61,7 @@
|
|
== snap back-to-file grid=100x30 cursor=7,2
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/windownav/cwd/w.txt Save De NOR /tmp/pardes-snap/windownav/cwd Del
| 1 alpha
| 2 beta w.txt
@@ -92,7 +92,7 @@
|
|
== snap altn grid=100x30 cursor=4,19
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/windownav/cwd/w.txt Save De NOR /tmp/pardes-snap/windownav/cwd Del
| 1 alpha
| 2 beta w.txt
@@ -123,7 +123,7 @@
|
|
== snap up grid=100x30 cursor=7,2
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/windownav/cwd/w.txt Save De NOR /tmp/pardes-snap/windownav/cwd Del
| 1 alpha
| 2 beta w.txt
@@ -154,7 +154,7 @@
|
|
== snap right grid=100x30 cursor=54,4
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/windownav/cwd/w.txt Save De NOR /tmp/pardes-snap/windownav/cwd Del
| 1 alpha
| 2 beta w.txt
@@ -185,7 +185,7 @@
|
|
== snap left grid=100x30 cursor=7,2
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/windownav/cwd/w.txt Save De NOR /tmp/pardes-snap/windownav/cwd Del
| 1 alpha
| 2 beta w.txt
@@ -216,7 +216,7 @@
|
|
== snap down grid=100x30 cursor=4,19
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/windownav/cwd/w.txt Save De NOR /tmp/pardes-snap/windownav/cwd Del
| 1 alpha
| 2 beta w.txt
@@ -247,7 +247,7 @@
|
|
== snap toggle-doc grid=100x30 cursor=7,2
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/windownav/cwd/w.txt Save De NOR /tmp/pardes-snap/windownav/cwd Del
| 1 alpha
| 2 beta w.txt
@@ -278,7 +278,7 @@
|
|
== snap toggle-back grid=100x30 cursor=4,19
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/windownav/cwd/w.txt Save De NOR /tmp/pardes-snap/windownav/cwd Del
| 1 alpha
| 2 beta w.txt
diff --git a/test/snapshots/windowops.golden b/test/snapshots/windowops.golden
index 724095e1..7bf19204 100644
--- a/test/snapshots/windowops.golden
+++ b/test/snapshots/windowops.golden
@@ -1,5 +1,5 @@
== snap hover-v grid=100x30 cursor=4,4
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/windowops/cwd Del ╎ NOR /tmp/pardes-snap/windowops/cwd Del
| ╎
| w.txt ╎ w.txt
@@ -30,7 +30,7 @@
| ╎
| ╎
== snap hover-h grid=100x30 cursor=4,4
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/windowops/cwd Del NOR /tmp/pardes-snap/windowops/cwd Del
|
| w.txt w.txt
@@ -61,7 +61,7 @@
|
|
== snap border-drag grid=100x30 cursor=4,4
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/windowops/cwd De╎ NOR /tmp/pardes-snap/windowops/cwd Del
| ╎
| w.txt ╎ w.txt
@@ -92,7 +92,7 @@
| ╎
| ╎
== snap border-done grid=100x30 cursor=4,4
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/windowops/cwd De╎ NOR /tmp/pardes-snap/windowops/cwd Del
| ╎
| w.txt ╎ w.txt
@@ -123,7 +123,7 @@
| ╎
| ╎
== snap hborder-done grid=100x30 cursor=4,4
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/windowops/cwd Del NOR /tmp/pardes-snap/windowops/cwd Del
|
| w.txt w.txt
@@ -154,7 +154,7 @@
|
|
== snap move-preview grid=100x30 cursor=4,15
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/windowops/cwd Del NOR /tmp/pardes-snap/windowops/cwd Del
|
| w.txt w.txt
@@ -185,7 +185,7 @@
|
|
== snap moved grid=100x30 cursor=4,15
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/windowops/cwd Del NOR /tmp/pardes-snap/windowops/cwd Del
|
| w.txt w.txt
@@ -216,7 +216,7 @@
|
|
== snap altn grid=100x30 cursor=4,19
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/windowops/cwd Del NOR /tmp/pardes-snap/windowops/cwd Del
|
| w.txt w.txt
@@ -247,7 +247,7 @@
|
|
== snap focus-right grid=100x30 cursor=44,4
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/windowops/cwd Del NOR /tmp/pardes-snap/windowops/cwd Del
|
| w.txt w.txt
@@ -278,7 +278,7 @@
|
|
== snap debug-on grid=100x30 cursor=44,4
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/windowops/cwd Del NOR /tmp/pardes-snap/windowo╭────────────────────────────╮
| │pardes resizes=1 │
| w.txt w.txt │terms 4 cols 2 │
@@ -309,7 +309,7 @@
|
|
== style debug-on
-|0: 0-47 #949494,#121212, 48-99 d,#121212,
+|0: 0-52 #949494,#121212, 53-99 d,#121212,
|1: 0-1 d,#262626, 2-39 #949494,#121212, 40-41 d,#626262, 42-69 #949494,#121212, 70-99 d,d,
|2: 0-1 d,#444444, 2-39 #bdbdbd,#080808, 40-41 d,#444444, 42-69 #bdbdbd,#080808, 70-70 d,d, 71-87 #949494,d, 88-98 d,#121212, 99-99 d,d,
|3: 0-1 d,#444444, 2-39 #bdbdbd,#080808, 40-41 d,#444444, 42-69 #bdbdbd,#080808, 70-70 d,d, 71-85 #949494,d, 86-98 d,#121212, 99-99 d,d,
@@ -340,7 +340,7 @@
|28: 0-1 d,#444444, 2-39 #bdbdbd,#080808, 40-41 d,#444444, 42-99 #bdbdbd,#080808,
|29: 0-1 d,#444444, 2-39 #bdbdbd,#080808, 40-41 d,#444444, 42-99 #bdbdbd,#080808,
== snap debug-off grid=100x30 cursor=44,4
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/windowops/cwd Del NOR /tmp/pardes-snap/windowops/cwd Del
|
| w.txt w.txt
diff --git a/test/snapshots/yankpaste.golden b/test/snapshots/yankpaste.golden
index 523d9d29..12c974bf 100644
--- a/test/snapshots/yankpaste.golden
+++ b/test/snapshots/yankpaste.golden
@@ -1,5 +1,5 @@
== snap linewise-below grid=100x30 cursor=13,5
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/yankpaste/cwd/f.txt Save De NOR /tmp/pardes-snap/yankpaste/cwd Del
| 1 line 1
| 2 line 2 f.txt
@@ -30,7 +30,7 @@
|
|
== snap linewise-above grid=100x30 cursor=13,6
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/yankpaste/cwd/f.txt Save De NOR /tmp/pardes-snap/yankpaste/cwd Del
| 1 line 1
| 2 line 2 f.txt
@@ -61,7 +61,7 @@
|
|
== snap charwise-inline grid=100x30 cursor=10,2
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/yankpaste/cwd/f.txt Save De NOR /tmp/pardes-snap/yankpaste/cwd Del
| 1 liline 1
| 2 line 2 f.txt
@@ -92,7 +92,7 @@
|
|
== snap blankline grid=100x30 cursor=7,4
-|Kill Newcol Tutor Debug NextColor Dump Find Grep
+|Kill Newcol Tutor Debug NextColor Dump Find Grep Help
| NOR /tmp/pardes-snap/yankpaste/cwd/f.txt Save De NOR /tmp/pardes-snap/yankpaste/cwd Del
| 1 liline 1
| 2 f.txt