diff options
| -rw-r--r-- | next-steps.txt | 2 | ||||
| -rw-r--r-- | src/output_pane.zig | 36 | ||||
| -rw-r--r-- | src/pardes.zig | 159 | ||||
| -rw-r--r-- | test/snapshots/builtins.golden | 366 | ||||
| -rw-r--r-- | test/snapshots/builtins.snap | 60 | ||||
| -rw-r--r-- | test/snapshots/leader.golden | 90 | ||||
| -rw-r--r-- | test/snapshots/tagnav.golden | 36 | ||||
| -rw-r--r-- | test/snapshots/ttyhelp.golden | 104 |
8 files changed, 690 insertions, 163 deletions
diff --git a/next-steps.txt b/next-steps.txt index 9cc22419..2718848e 100644 --- a/next-steps.txt +++ b/next-steps.txt @@ -2,7 +2,7 @@ + Carve out and isolate the Output pane as its own semantic entity, right now we are doing specific stuff on the output pane based on the command that opened it, let's make this part of the data structure that represents it, the heuristics for special handling of the output panes will be done by reading the Command that originated it field from itself. Make this centralized on the code so its clear to see and tweak those heuristics. - File panes need to split the latest column which a file pane was being used. - Add multiple cursor support, and Ctrl-c auto comments. Use the same methodology of running helix in a harness as the oracle for differential testing. Also add regex interactive selection like on helix and the more specific selection semantics, use https://github.com/mnemnion/mvzr for regexes, add it using zig fetch. -- Add a new builtin that will list all builtins and their respective shortcuts if they have any (note that shortcuts may be spc+... or just keyboard or mouse chords/movements) ++ Add a new builtin that will list all builtins and their respective shortcuts if they have any (note that shortcuts may be spc+... or just keyboard or mouse chords/movements) - Scrolling on a touchpad moves horizontally accidentally way too much, add some heuristics to prioritize vertical scrolling and make horizontal scrolling work only when the user is a bit more explicit about it - for example by measuring if there was recent high-enough vertical movement, etc. + Add a new builtin to list the themes and create an output window to select those themes; each theme now must live on its own .zig file, when moving with n/N on out ThemeSel output window it will select that theme so it's a interactive way to select the themes. We're being clever now with how these output windows will work, this feature depends on the new semantics for output windows but basically now the ThemeSel output panes will set the Command flag that will basically tell that when doing n/N movement on the output pane instead of Look-ing it will Execute the line, so the ThemeSel output pane will be like: (Theme acme, Theme a, Theme b) seperated by lines so the n/N will automatically consider selecting the Theme + argument (this is not output pane specific, it should be generalized to work on every pane kind), and will Exec it. Add new themes that will be automatically exported from helix and zed, a new binary will execute that will generate .zig files, this binary will be added as a execute step on the build.zig so when building it will regenarate those .zig that will be then included on the runtime as themes. - Use zig's 0.16 new threaded io and the std functions that the build system uses to listen for file changes, it needs to use something from the os so it's not a busy wait. It will only track files on open panes. when a file is updated, doing Undo will return to the state that it was before so if a file automatically updates the user won't lose the unsaved state as it was before and the editor won't need to handle with merging the unsaved changes and the new update. diff --git a/src/output_pane.zig b/src/output_pane.zig index a0583506..9c004dff 100644 --- a/src/output_pane.zig +++ b/src/output_pane.zig @@ -123,6 +123,14 @@ pub fn traits(o: Origin) Traits { // rows are `location text`, so n/N walk them .search => .{ .name = config.search_buffer, .steps = true }, .cmd => |b| switch (b) { + // The builtin index. Neither steppable nor executable, and that is + // a decision rather than an omission: its rows are not locations + // (a look on `SPC` would go looking for a file called SPC), and + // `executes` — which is exactly what makes ThemeSel a picker — + // would mean walking the list runs Kill, Del and Delcol in turn. + // Wearing a theme is free; wearing Kill ends the session. The + // names in it are still live text, so middle-clicking the ONE you + // want does the picking, which is all a picker was for. .Help => .{ .name = config.help_buffer }, // the focus history, one location per row: not a search, but the // same kind of list, so n/N walk it and a row is a look target @@ -303,24 +311,36 @@ fn openStepped(p: *Pardes, id: usize, from: Origin, text: []const u8) void { pane.search_row = null; } -/// The Help builtin: every builtin reachable from `prefix` (empty = all -/// of them) with the keys that run it, written into an output buffer -/// (acme's +Errors) — ordinary text, so the names in it are LIVE: middle- -/// click `Tutor` there and the tutor opens. Reuses the open +Help buffer -/// instead of piling panes up, and focus follows: you asked to read it. +/// The Help builtin: THE INDEX of builtins — every one of them, and every way +/// to run it — filtered to what `prefix` can still reach, written into an +/// output buffer (acme's +Errors). Ordinary text, so the names in it are LIVE: +/// middle-click `Tutor` there and the tutor opens. Reuses the open +Help +/// buffer instead of piling panes up, and focus follows: you asked to read it. +/// +/// ONE builtin and not two. The complete index and the mid-chord "what can +/// `SPC h` still reach" are the same array (pardes.builtin_rows) read with a +/// different prefix — the empty one matches every row, including the builtins +/// SPC cannot reach at all, so the reference page IS the filter's degenerate +/// case. A second builtin would have been a second renderer over a superset of +/// these rows, and the two would have drifted the first time a column moved. pub fn openHelp(p: *Pardes, id: usize, prefix: []const u8) void { const pane = p.panes[id] orelse return; const arena = p.scratch.allocator(); var out: std.ArrayList(u8) = .empty; if (prefix.len == 0) { - out.appendSlice(arena, "pardes builtins - SPC then the keys,\nor execute the name anywhere\n\n") catch return; + // the header names the four KINDS of shortcut a row's columns can + // hold, because a blank column is only readable once you know what + // would have been in it + out.appendSlice(arena, "pardes builtins, and how to run each:\nSPC and its keys, a chord, a button, the\ntopbar - or the name, executed anywhere.\n\n") catch return; } else { out.appendSlice(arena, "pardes builtins under SPC") catch return; for (prefix) |c| out.appendSlice(arena, &[_]u8{ ' ', c }) catch return; out.appendSlice(arena, "\n\n") catch return; } - for (pardes.leader_rows) |row| { - if (!std.mem.startsWith(u8, row.path, prefix)) continue; + for (pardes.builtin_rows) |row| { + // a path-less builtin filters as the empty path: in the full listing + // (which starts with nothing) and out of every group + if (!std.mem.startsWith(u8, row.path orelse "", prefix)) continue; out.appendSlice(arena, row.line) catch return; out.append(arena, '\n') catch return; } diff --git a/src/pardes.zig b/src/pardes.zig index 4d6556f3..47892108 100644 --- a/src/pardes.zig +++ b/src/pardes.zig @@ -85,53 +85,132 @@ const file_pane_tail = " " ++ config.file_pane_builtins_str; // execute) and `std.meta.stringToEnum` is still the lookup with no name table // to keep in sync. It lands here rather than in builtins.zig because a // container cannot hold a decl folded out of its own decl list, and here it -// sits with the other two comptime folds (leader_rows, the topbar check). +// sits with the other two comptime folds (builtin_rows, the topbar check). const Builtin = builtins.Builtin(); -/// The leader tree, flattened: one row per builtin SORTED BY PATH, so every -/// prefix's subtree is a contiguous run — which is all the two runtime -/// readers need. The matcher asks "exact hit? still a prefix of something?" -/// and Help filters the same rows by the same prefix. A node-and-pointer trie -/// for thirteen two-character paths would be ceremony. `line` is the Help -/// rendering, padded here so Help is a filter over an array of lines. -const Leader = struct { path: []const u8, cmd: Builtin, line: []const u8 }; -/// how many builtins HAVE a leader path — Look and Exec do not (their -/// shortcuts are keys and buttons), so this is no longer the enum's own length -const leader_n = blk: { - var n: usize = 0; - for (std.enums.values(Builtin)) |b| n += @intFromBool(config.leader_path.get(b) != null); - break :blk n; -}; -pub const leader_rows: [leader_n]Leader = blk: { - // the insertion sort below is O(n²) comptime branches, and n grew with the - // language group - @setEvalBranchQuota(8000); - var rows: [leader_n]Leader = undefined; - // the widest spaced-out path ("h t" = 3), so the names line up +/// How a `Chord` is SPELLED in the index. The named keys come from Key's OWN +/// declarations rather than a table beside them — a new special key names +/// itself here, and a wrong name is impossible because there is only one. The +/// rest is the printable character; anything else is a compile error, because +/// a private-use codepoint cast to a byte would render as silent garbage in a +/// listing nobody diffs. +fn chordName(comptime c: config.Chord) []const u8 { + comptime { + const mods = (if (c.ctrl) "C-" else "") ++ (if (c.alt) "A-" else "") ++ (if (c.shift) "S-" else ""); + for (@typeInfo(Key).@"struct".decls) |d| { + if (@TypeOf(@field(Key, d.name)) != u21) continue; + if (@field(Key, d.name) == c.cp) return mods ++ d.name; + } + if (c.cp < 0x20 or c.cp > 0x7e) @compileError("chord has no name for the index"); + return mods ++ &[_]u8{@as(u8, @intCast(c.cp))}; + } +} + +/// Every way to run `b` that is NOT its leader path: the chords and buttons +/// config binds to it, plus the topbar if it has a word up there (row 0 is a +/// click target, and the only shortcut that works in tty mode where SPC +/// belongs to the shell). Walked from config's own tables — window_keys' and +/// jump_keys' `cmd` columns, look_cmd/exec_cmd, topbar_str — so retargeting a +/// binding there re-renders here with nothing to keep in step. +/// +/// What is NOT here, and cannot be: a chord that reaches no builtin. Alt-n, +/// Alt-c, the tty toggle and the 1-2/1-3 cut/paste chords are inline handlers +/// with no word to index by. The day one of them becomes a builtin — a struct +/// in builtins.zig and a `cmd` column beside its binding — it appears here for +/// free, which is the upgrade path rather than a special case here. +fn shortcuts(comptime b: Builtin) []const u8 { + comptime { + @setEvalBranchQuota(20000); + var parts: []const []const u8 = &.{}; + // both spellings of the four directional moves: the arrow is a real + // key someone presses, and the table carries it precisely so it is + // discoverable from the builtin as well as the other way round + for (config.window_keys) |wk| { + if (wk.cmd != b) continue; + // the prefix has one spelling and this is it + const pfx = chordName(config.window_prefix[0]) ++ " "; + parts = parts ++ &[_][]const u8{ pfx ++ chordName(wk.letter), pfx ++ chordName(wk.arrow) }; + } + for (config.jump_keys) |jk| { + if (jk.cmd == b) parts = parts ++ &[_][]const u8{chordName(jk.chord)}; + } + // the two acme verbs, a key and a mouse button each. Asked of the + // BINDING (look_cmd/exec_cmd point at a builtin) rather than of Look + // and Exec by name, so pointing look_cmd at Grep moves the row. + if (config.look_cmd == b) { + for (config.look_key) |k| parts = parts ++ &[_][]const u8{chordName(k)}; + parts = parts ++ &[_][]const u8{@tagName(config.look_button) ++ "-click"}; + } + if (config.exec_cmd == b) { + for (config.exec_key) |k| parts = parts ++ &[_][]const u8{chordName(k)}; + parts = parts ++ &[_][]const u8{@tagName(config.exec_button) ++ "-click"}; + } + var it = std.mem.tokenizeScalar(u8, config.topbar_str, ' '); + while (it.next()) |w| { + if (std.mem.eql(u8, w, @tagName(b))) parts = parts ++ &[_][]const u8{"topbar"}; + } + var out: []const u8 = ""; + for (parts, 0..) |s, i| out = out ++ (if (i > 0) ", " else "") ++ s; + return out; + } +} + +/// THE BUILTIN INDEX, flattened: one row per builtin — the leader path that +/// runs it (null: SPC does not reach it), every other way to run it, and the +/// Help line those are rendered into. SORTED BY PATH, so every prefix's +/// subtree is a contiguous run, which is all the two runtime readers need. The +/// matcher asks "exact hit? still a prefix of something?" and Help filters the +/// same rows by the same prefix. A node-and-pointer trie for forty +/// two-character paths would be ceremony. +/// +/// A row per BUILTIN and no longer a row per leader PATH, which is what makes +/// Help the complete index instead of a second builtin listing a superset of +/// what Help lists. A path-less builtin (Look, Exec, Theme) is a row like any +/// other and its empty key column is the information: SPC does not reach this +/// one, the last column does — or nothing does, which is also worth knowing. +/// The mid-chord filter is the SAME array read with a non-empty prefix, and it +/// drops those rows by itself because an empty path starts with nothing. +const Row = struct { path: ?[]const u8, cmd: Builtin, line: []const u8 }; +pub const builtin_rows: [std.enums.values(Builtin).len]Row = blk: { + // one pass per builtin per config table, and the insertion sort below is + // O(n²) comptime branches on top of it + @setEvalBranchQuota(200000); + var rows: [std.enums.values(Builtin).len]Row = undefined; + // the widest spaced-out path ("l D" = 3) and the widest name, so the three + // columns line up var keyw: usize = 0; + var namew: usize = 0; for (std.enums.values(Builtin)) |b| { - const p = config.leader_path.get(b) orelse continue; - keyw = @max(keyw, 2 * p.len - 1); + if (config.leader_path.get(b)) |p| keyw = @max(keyw, 2 * p.len - 1); + namew = @max(namew, @tagName(b).len); } - var n: usize = 0; - for (std.enums.values(Builtin)) |b| { - const path = config.leader_path.get(b) orelse continue; + for (std.enums.values(Builtin), 0..) |b, i| { var keys: []const u8 = ""; - for (path, 0..) |c, k| { - if (k > 0) keys = keys ++ " "; - keys = keys ++ &[_]u8{c}; + if (config.leader_path.get(b)) |path| { + keys = "SPC "; + for (path, 0..) |c, k| { + if (k > 0) keys = keys ++ " "; + keys = keys ++ &[_]u8{c}; + } } - rows[n] = .{ - .path = path, + // the name column is only padded when something follows it: a row + // whose builtin has no other shortcut ends at the name, so the listing + // carries no trailing whitespace + const rest = shortcuts(b); + const named = @tagName(b) ++ (if (rest.len == 0) "" else (" " ** (namew - @tagName(b).len)) ++ " " ++ rest); + rows[i] = .{ + .path = config.leader_path.get(b), .cmd = b, - .line = "SPC " ++ keys ++ (" " ** (keyw - keys.len)) ++ " " ++ @tagName(b), + .line = keys ++ (" " ** (4 + keyw - keys.len)) ++ " " ++ named, }; - n += 1; } - // insertion sort by path: a group sorts right before what extends it + // insertion sort by path: a group sorts right before what extends it, and + // a path-less builtin sorts after every path — DEL is not a path because + // leaderKey only ever stores a printable key + const last = "\x7f"; for (1..rows.len) |i| { var j = i; - while (j > 0 and std.mem.lessThan(u8, rows[j].path, rows[j - 1].path)) : (j -= 1) { + while (j > 0 and std.mem.lessThan(u8, rows[j].path orelse last, rows[j - 1].path orelse last)) : (j -= 1) { const t = rows[j]; rows[j] = rows[j - 1]; rows[j - 1] = t; @@ -1819,11 +1898,13 @@ pub const Pardes = struct { p.leader_keys[p.leader_n] = c; p.leader_n += 1; const pfx = p.leader_keys[0..p.leader_n]; - for (leader_rows) |row| { - if (std.mem.eql(u8, row.path, pfx)) return p.runBuiltin(row.cmd, p.active, "", null); + // a path-less builtin is a row here too (it is the same index Help + // reads), and SPC cannot reach one — so both scans skip it + for (builtin_rows) |row| { + if (std.mem.eql(u8, row.path orelse continue, pfx)) return p.runBuiltin(row.cmd, p.active, "", null); } - for (leader_rows) |row| { - if (std.mem.startsWith(u8, row.path, pfx)) { + for (builtin_rows) |row| { + if (std.mem.startsWith(u8, row.path orelse continue, pfx)) { p.leader_on = true; return; } diff --git a/test/snapshots/builtins.golden b/test/snapshots/builtins.golden new file mode 100644 index 00000000..40152d5b --- /dev/null +++ b/test/snapshots/builtins.golden @@ -0,0 +1,366 @@ +== snap boot grid=120x60 cursor=7,2 +|Kill Newcol Tutor Debug NextColor Dump Find Grep Help +| NOR /tmp/pardes-snap/builtins/cwd/notes.txt Save Del NOR /tmp/pardes-snap/builtins/cwd Del +| 1 line 1 +| 2 line 2 notes.txt +| 3 line 3 +| 4 line 4 +| 5 line 5 +| 6 line 6 +| 7 +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +== snap index grid=120x60 cursor=7,32 +|Kill Newcol Tutor Debug NextColor Dump Find Grep Help +| NOR /tmp/pardes-snap/builtins/cwd/notes.txt Save Del NOR /tmp/pardes-snap/builtins/cwd Del +| 1 line 1 +| 2 line 2 notes.txt +| 3 line 3 +| 4 line 4 +| 5 line 5 +| 6 line 6 +| 7 +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| NOR /tmp/pardes-snap/builtins/cwd/+Help Del +| 1 pardes builtins, and how to run each: +| 2 SPC and its keys, a chord, a button, the +| 3 topbar - or the name, executed anywhere. +| 4 +| 5 SPC ? Help topbar +| 6 SPC c d Delcol +| 7 SPC c n Newcol topbar +| 8 SPC d Del +| 9 SPC f f Find topbar +| 10 SPC f g Grep topbar +| 11 SPC f s Save +| 12 SPC h t Tutor topbar +| 13 SPC j i Forward C-i +| 14 SPC j j Last +| 15 SPC j l Jumplist +| 16 SPC j o Back C-o +| 17 SPC k Kill topbar +| 18 SPC l D WsDiagnostics +| 19 SPC l S WsSymbols +| 20 SPC l a CodeAction +| 21 SPC l d Diagnostics +| 22 SPC l h SelectRefs +| 23 SPC l i Lspinfo +| 24 SPC l k Hover +| 25 SPC l r Rename +| 26 SPC l s Symbols +| 27 SPC l w Lspwhy +| 28 SPC s d Dump topbar +== snap index-tail grid=120x60 cursor=7,58 +|Kill Newcol Tutor Debug NextColor Dump Find Grep Help +| NOR /tmp/pardes-snap/builtins/cwd/notes.txt Save Del NOR /tmp/pardes-snap/builtins/cwd Del +| 1 line 1 +| 2 line 2 notes.txt +| 3 line 3 +| 4 line 4 +| 5 line 5 +| 6 line 6 +| 7 +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| NOR /tmp/pardes-snap/builtins/cwd/+Help Del +| 19 SPC l S WsSymbols +| 20 SPC l a CodeAction +| 21 SPC l d Diagnostics +| 22 SPC l h SelectRefs +| 23 SPC l i Lspinfo +| 24 SPC l k Hover +| 25 SPC l r Rename +| 26 SPC l s Symbols +| 27 SPC l w Lspwhy +| 28 SPC s d Dump topbar +| 29 SPC s r Restore +| 30 SPC t a Ascii +| 31 SPC t c Colors +| 32 SPC t d Debug topbar +| 33 SPC t l Palette +| 34 SPC t n NextColor topbar +| 35 SPC t p Petscii +| 36 SPC t r Crt +| 37 SPC t t ThemeSel +| 38 SPC w h Left C-w h, C-w left +| 39 SPC w j Down C-w j, C-w down +| 40 SPC w k Up C-w k, C-w up +| 41 SPC w l Right C-w l, C-w right +| 42 SPC w t Toggleterm +| 43 Look enter, right-click +| 44 Exec tab, middle-click +| 45 Theme +| 46 +== snap not-a-picker grid=120x60 cursor=7,58 +|Kill Newcol Tutor Debug NextColor Dump Find Grep Help +| NOR /tmp/pardes-snap/builtins/cwd/notes.txt Save Del NOR /tmp/pardes-snap/builtins/cwd Del +| 1 line 1 +| 2 line 2 notes.txt +| 3 line 3 +| 4 line 4 +| 5 line 5 +| 6 line 6 +| 7 +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| NOR /tmp/pardes-snap/builtins/cwd/+Help Del +| 19 SPC l S WsSymbols +| 20 SPC l a CodeAction +| 21 SPC l d Diagnostics +| 22 SPC l h SelectRefs +| 23 SPC l i Lspinfo +| 24 SPC l k Hover +| 25 SPC l r Rename +| 26 SPC l s Symbols +| 27 SPC l w Lspwhy +| 28 SPC s d Dump topbar +| 29 SPC s r Restore +| 30 SPC t a Ascii +| 31 SPC t c Colors +| 32 SPC t d Debug topbar +| 33 SPC t l Palette +| 34 SPC t n NextColor topbar +| 35 SPC t p Petscii +| 36 SPC t r Crt +| 37 SPC t t ThemeSel +| 38 SPC w h Left C-w h, C-w left +| 39 SPC w j Down C-w j, C-w down +| 40 SPC w k Up C-w k, C-w up +| 41 SPC w l Right C-w l, C-w right +| 42 SPC w t Toggleterm +| 43 Look enter, right-click +| 44 Exec tab, middle-click +| 45 Theme +| 46 +== snap window-group grid=120x60 cursor=7,32 +|Kill Newcol Tutor Debug NextColor Dump Find Grep Help +| NOR /tmp/pardes-snap/builtins/cwd/notes.txt Save Del NOR /tmp/pardes-snap/builtins/cwd Del +| 1 line 1 +| 2 line 2 notes.txt +| 3 line 3 +| 4 line 4 +| 5 line 5 +| 6 line 6 +| 7 +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| NOR /tmp/pardes-snap/builtins/cwd/+Help Del +| 1 pardes builtins under SPC w +| 2 +| 3 SPC w h Left C-w h, C-w left +| 4 SPC w j Down C-w j, C-w down +| 5 SPC w k Up C-w k, C-w up +| 6 SPC w l Right C-w l, C-w right +| 7 SPC w t Toggleterm +| 8 +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +== snap tutor-from-index grid=120x60 cursor=7,17 +|Kill Newcol Tutor Debug NextColor Dump Find Grep Help +| NOR /tmp/pardes-snap/builtins/cwd/notes.txt Save Del NOR /tmp/pardes-snap/builtins/cwd Del +| 1 line 1 +| 2 line 2 notes.txt +| 3 line 3 +| 4 line 4 +| 5 line 5 +| 6 line 6 +| 7 +| +| +| +| +| +| +| +| NOR /Tutor Save Del +| 1 +| 2 PARDES TUTOR +| 3 tmux + vi + acme, from scratch. +| 4 +| 5 The model is acme's: EVERYTHING is text, edit +| 6 the same way. Modal editing (helix-style) liv +| 7 Press j until you reach the introduction. +| 8 +| 9 +| 10 ===================================================== +| 11 = INTRODUCTION +| 12 ===================================================== +| 13 +| 14 Pardes is tmux + vi + acme, made from scratch. The f +| NOR /tmp/pardes-snap/builtins/cwd/+Help Del +| 1 pardes builtins, and how to run each: +| 2 SPC and its keys, a chord, a button, the +| 3 topbar - or the name, executed anywhere. +| 4 +| 5 SPC ? Help topbar +| 6 SPC c d Delcol +| 7 SPC c n Newcol topbar +| 8 SPC d Del +| 9 SPC f f Find topbar +| 10 SPC f g Grep topbar +| 11 SPC f s Save +| 12 SPC h t Tutor topbar +| 13 SPC j i Forward C-i +| 14 SPC j j Last +| 15 SPC j l Jumplist +| 16 SPC j o Back C-o +| 17 SPC k Kill topbar +| 18 SPC l D WsDiagnostics +| 19 SPC l S WsSymbols +| 20 SPC l a CodeAction +| 21 SPC l d Diagnostics +| 22 SPC l h SelectRefs +| 23 SPC l i Lspinfo +| 24 SPC l k Hover +| 25 SPC l r Rename +| 26 SPC l s Symbols +| 27 SPC l w Lspwhy +| 28 SPC s d Dump topbar diff --git a/test/snapshots/builtins.snap b/test/snapshots/builtins.snap new file mode 100644 index 00000000..b2c4f752 --- /dev/null +++ b/test/snapshots/builtins.snap @@ -0,0 +1,60 @@ +# RULE: Help is THE INDEX of the builtins — every one of them, and every way +# to run it — not a listing of leader paths. Three columns, all derived at +# comptime from config.zig's own tables: the SPC path (leader_path), the name, +# and every other shortcut bound to that name (window_keys and jump_keys' `cmd` +# columns, look_cmd/exec_cmd with their keys and mouse buttons, a word in +# topbar_str). A builtin added tomorrow is a row here with nothing to edit. +# +# The cases this exists for are the ones a leader listing could not show: +# Look and Exec have NO SPC path — their shortcuts are Enter/Tab and the two +# mouse buttons — and Theme has no shortcut at all, because a key path can +# never carry the name of a theme. All three are rows, and their blank columns +# are the information. +# +# `SPC ?` mid-chord is the SAME array read with a non-empty prefix, which is +# why there is one builtin here and not two: the group filter drops the +# path-less rows by itself, and the reference page is the filter's empty case. +lines notes.txt 6 +start 60 120 notes.txt +wait 8000 notes.txt +stable 700 20000 +snap boot +# SPC ? at the ROOT. Focus follows the listing — you asked to read it. +key space ? +wait 10000 SPC c n +stable 700 15000 +snap index +# The tail of the same listing: the window group carries BOTH spellings of +# each Ctrl-w chord (the table carries both), and past the last path come the +# three builtins SPC cannot reach. `ge` walks the buffer's own body to the end. +key g e +stable 700 15000 +snap index-tail +# n/N here must NOT run the rows. ThemeSel's buffer executes what it steps +# onto, and that is safe because wearing a theme is free; this list holds Kill, +# Del and Delcol, so stepping it would end the session. Three presses, and the +# panes and the listing are all where they were. +key n +key n +key n +stable 700 15000 +snap not-a-picker +# and the mid-chord filter is untouched: `SPC w ?` still answers "what can w +# still reach", rewriting the same +Help buffer with just that group — five +# rows, each now also showing the Ctrl-w chord that is the other way in, and +# none of the three path-less builtins, which `w` cannot reach. +key space w ? +wait 10000 Toggleterm +stable 700 15000 +snap window-group +# back to the whole index, and a NAME in it is live text like anywhere else: +# middle-click `Tutor` and the tutor opens. That is the picking a stepping +# picker would have done, minus running the thirty-nine rows you passed. +key space ? +wait 10000 SPC c n +stable 700 15000 +press middle 20 44 +release middle 20 44 +wait 10000 PARDES TUTOR +stable 700 15000 +snap tutor-from-index diff --git a/test/snapshots/leader.golden b/test/snapshots/leader.golden index 0ed14a68..5e2aaba7 100644 --- a/test/snapshots/leader.golden +++ b/test/snapshots/leader.golden @@ -185,24 +185,24 @@ | | | NOR /tmp/pardes-snap/leader/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 j i Forward -| 13 SPC j j Last -| 14 SPC j l Jumplist -| 15 SPC j o Back -| 16 SPC k Kill -| 17 SPC l D WsDiagnostics -| 18 SPC l S WsSymbols +| 1 pardes builtins, and how to run each: +| 2 SPC and its keys, a chord, a button, the +| 3 topbar - or the name, executed anywhere. +| 4 +| 5 SPC ? Help topbar +| 6 SPC c d Delcol +| 7 SPC c n Newcol topbar +| 8 SPC d Del +| 9 SPC f f Find topbar +| 10 SPC f g Grep topbar +| 11 SPC f s Save +| 12 SPC h t Tutor topbar +| 13 SPC j i Forward C-i +| 14 SPC j j Last +| 15 SPC j l Jumplist +| 16 SPC j o Back C-o +| 17 SPC k Kill topbar +| 18 SPC l D WsDiagnostics == snap help-group 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 @@ -228,7 +228,7 @@ | NOR /tmp/pardes-snap/leader/cwd/+Help Del | 1 pardes builtins under SPC h | 2 -| 3 SPC h t Tutor +| 3 SPC h t Tutor topbar | 4 | | @@ -269,7 +269,7 @@ | NOR /tmp/pardes-snap/leader/cwd/+Help Del | 1 pardes builtins under SPC h | 2 -| 3 SPC h t Tutor +| 3 SPC h t Tutor topbar | 4 | | @@ -310,7 +310,7 @@ | NOR /tmp/pardes-snap/leader/cwd/+Help Del | 1 pardes builtins under SPC h | 2 -| 3 SPC h t Tutor +| 3 SPC h t Tutor topbar | 4 | | @@ -349,24 +349,24 @@ | | | NOR /tmp/pardes-snap/leader/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 j i Forward -| 13 SPC j j Last -| 14 SPC j l Jumplist -| 15 SPC j o Back -| 16 SPC k Kill -| 17 SPC l D WsDiagnostics -| 18 SPC l S WsSymbols +| 1 pardes builtins, and how to run each: +| 2 SPC and its keys, a chord, a button, the +| 3 topbar - or the name, executed anywhere. +| 4 +| 5 SPC ? Help topbar +| 6 SPC c d Delcol +| 7 SPC c n Newcol topbar +| 8 SPC d Del +| 9 SPC f f Find topbar +| 10 SPC f g Grep topbar +| 11 SPC f s Save +| 12 SPC h t Tutor topbar +| 13 SPC j i Forward C-i +| 14 SPC j j Last +| 15 SPC j l Jumplist +| 16 SPC j o Back C-o +| 17 SPC k Kill topbar +| 18 SPC l D WsDiagnostics == snap help-toggles 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 @@ -394,9 +394,9 @@ | 2 | 3 SPC t a Ascii | 4 SPC t c Colors -| 5 SPC t d Debug +| 5 SPC t d Debug topbar | 6 SPC t l Palette -| 7 SPC t n NextColor +| 7 SPC t n NextColor topbar | 8 SPC t p Petscii | 9 SPC t r Crt | 10 SPC t t ThemeSel @@ -433,10 +433,10 @@ | NOR /tmp/pardes-snap/leader/cwd/+Help Del | 1 pardes builtins under SPC w | 2 -| 3 SPC w h Left -| 4 SPC w j Down -| 5 SPC w k Up -| 6 SPC w l Right +| 3 SPC w h Left C-w h, C-w left +| 4 SPC w j Down C-w j, C-w down +| 5 SPC w k Up C-w k, C-w up +| 6 SPC w l Right C-w l, C-w right | 7 SPC w t Toggleterm | 8 | diff --git a/test/snapshots/tagnav.golden b/test/snapshots/tagnav.golden index e1bc7643..a28e8177 100644 --- a/test/snapshots/tagnav.golden +++ b/test/snapshots/tagnav.golden @@ -505,12 +505,12 @@ | | | 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 +| 1 pardes builtins, and how to run each: +| 2 SPC and its keys, a chord, a button, the +| 3 topbar - or the name, executed anywhere. +| 4 +| 5 SPC ? Help topbar +| 6 SPC c d Delcol | NOR /tmp/pardes-snap/tagnav/cwd Del | | w.txt @@ -536,12 +536,12 @@ | | | 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 +| 1 pardes builtins, and how to run each: +| 2 SPC and its keys, a chord, a button, the +| 3 topbar - or the name, executed anywhere. +| 4 +| 5 SPC ? Help topbar +| 6 SPC c d Delcol | NOR /tmp/pardes-snap/tagnav/cwd Del | | w.txt @@ -567,12 +567,12 @@ | 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 +| 1 pardes builtins, and how to run each: +| 2 SPC and its keys, a chord, a button, the +| 3 topbar - or the name, executed anywhere. +| 4 +| 5 SPC ? Help topbar +| 6 SPC c d Delcol | NOR /tmp/pardes-snap/tagnav/cwd Del | | w.txt diff --git a/test/snapshots/ttyhelp.golden b/test/snapshots/ttyhelp.golden index ec3a4fd6..318f471b 100644 --- a/test/snapshots/ttyhelp.golden +++ b/test/snapshots/ttyhelp.golden @@ -34,60 +34,60 @@ | 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 j i Forward -| 13 SPC j j Last -| 14 SPC j l Jumplist -| 15 SPC j o Back -| 16 SPC k Kill -| 17 SPC l D WsDiagnostics -| 18 SPC l S WsSymbols -| 19 SPC l a CodeAction -| 20 SPC l d Diagnostics -| 21 SPC l h SelectRefs -| 22 SPC l i Lspinfo -| 23 SPC l k Hover -| 24 SPC l r Rename -| 25 SPC l s Symbols -| 26 SPC l w Lspwhy +| 1 pardes builtins, and how to run each: +| 2 SPC and its keys, a chord, a button, the +| 3 topbar - or the name, executed anywhere. +| 4 +| 5 SPC ? Help topbar +| 6 SPC c d Delcol +| 7 SPC c n Newcol topbar +| 8 SPC d Del +| 9 SPC f f Find topbar +| 10 SPC f g Grep topbar +| 11 SPC f s Save +| 12 SPC h t Tutor topbar +| 13 SPC j i Forward C-i +| 14 SPC j j Last +| 15 SPC j l Jumplist +| 16 SPC j o Back C-o +| 17 SPC k Kill topbar +| 18 SPC l D WsDiagnostics +| 19 SPC l S WsSymbols +| 20 SPC l a CodeAction +| 21 SPC l d Diagnostics +| 22 SPC l h SelectRefs +| 23 SPC l i Lspinfo +| 24 SPC l k Hover +| 25 SPC l r Rename +| 26 SPC l s Symbols == 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 j i Forward -| 13 SPC j j Last -| 14 SPC j l Jumplist -| 15 SPC j o Back -| 16 SPC k Kill -| 17 SPC l D WsDiagnostics -| 18 SPC l S WsSymbols -| 19 SPC l a CodeAction -| 20 SPC l d Diagnostics -| 21 SPC l h SelectRefs -| 22 SPC l i Lspinfo -| 23 SPC l k Hover -| 24 SPC l r Rename -| 25 SPC l s Symbols -| 26 SPC l w Lspwhy +| 1 pardes builtins, and how to run each: +| 2 SPC and its keys, a chord, a button, the +| 3 topbar - or the name, executed anywhere. +| 4 +| 5 SPC ? Help topbar +| 6 SPC c d Delcol +| 7 SPC c n Newcol topbar +| 8 SPC d Del +| 9 SPC f f Find topbar +| 10 SPC f g Grep topbar +| 11 SPC f s Save +| 12 SPC h t Tutor topbar +| 13 SPC j i Forward C-i +| 14 SPC j j Last +| 15 SPC j l Jumplist +| 16 SPC j o Back C-o +| 17 SPC k Kill topbar +| 18 SPC l D WsDiagnostics +| 19 SPC l S WsSymbols +| 20 SPC l a CodeAction +| 21 SPC l d Diagnostics +| 22 SPC l h SelectRefs +| 23 SPC l i Lspinfo +| 24 SPC l k Hover +| 25 SPC l r Rename +| 26 SPC l s Symbols |
