summaryrefslogtreecommitdiff
path: root/next-steps.txt
Commit message (Collapse)AuthorAge
* a new file splits the doc column you were last working inGabriel Schneider2026-08-01
| | | | | | | | | | | | | | | | | | placeDoc picked its source by SLOT INDEX — it scanned panes from 0 and took the first doc it found — so which column your file landed in depended on internal id allocation, not on where you had been. It now walks the jump stack backwards to the newest live doc pane. No new state: jumps already IS the record of where the keyboard has been, and Pane.serial is already the "this slot was reused" test. The slot-order scan stays as the fallback, deliberately: a restored dump has one jump entry, and if that pane is a shell the stack knows no doc — without the fallback the next file would claim a second column with docs already open. lookpanes moved: a file now lands under the doc that was actually last read rather than under whichever doc happened to hold the lowest pane id. New golden doccol pins the case the line exists for, and it fails at exactly one capture with the walk disabled.
* Help lists every builtin and every way to reach itGabriel Schneider2026-08-01
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Not a second builtin: Help already rendered "every builtin with a leader path and the key that runs it", and the ask is "every builtin and every shortcut" — the same listing with three more rows and one more column. A new builtin would have been a second renderer over a superset of the same rows, and the two would drift the first time a column moved. The prefix filter is now the degenerate case of the index rather than a separate mode: SPC h ? reads the same array with prefix "h", and the path-less builtins fall out on their own because an empty path starts with nothing. The shortcut column is folded, never typed: chordName spells a chord from Key's OWN declarations, so a new special key names itself and an unnamed non-printable codepoint is a compile error instead of garbage; shortcuts() walks the cmd columns of window_keys and jump_keys, look_cmd/exec_cmd with their keys and buttons, and topbar_str. Retarget a binding in config.zig and this re-renders. So Look reads `enter, right-click`, Back reads `C-o`, Kill reads `topbar`, and Theme reads nothing at all — which is the information. Not a picker, deliberately: n/N stepping a list holding Kill, Del and Delcol would end the session. The names are live text, so middle-click the one you want. Alt-n, Alt-c, the tty toggle and the cut/paste chords cannot appear — they are inline handlers that reach no builtin, so there is no row to put them on. Make one a struct with a cmd column beside its binding and it appears for free. Three goldens moved, all of them the +Help buffer's contents.
* themes: one file each, generated from helix and zed, picked by stepping a listGabriel Schneider2026-08-01
| | | | | | | | | | | | | | | | | | | | | | | | | Each theme is a .zig file of pure data and nothing enumerates them by hand — fold() walks the container's declarations, so a theme is a file and that is the whole registration. Field by field rather than a wholesale coercion, which makes a missing field a compile error that names it. tools/gen_themes.zig reads helix .toml and zed .json out of vendor/themes and emits one .zig each; build.zig reads that directory, so adding a theme is dropping a file in. Output goes to the build cache rather than the tree, so zig owns the freshness check and a deleted source cannot leave a stale theme behind. Vendored, not read from the genizah: the build stays offline. A source it cannot map is a hard error naming the file and the key, never a silently black-on-black theme. ThemeSel is the clever half. Traits gained an `executes` column, so n/N over that buffer hands the whole line to Exec instead of the leading word to Look — both arms the ordinary builtin, so a stepped row does exactly what the matching mouse button on it would. Stepping the list previews each theme live. The trait is a pane property, not an output-pane branch, so any pane whose lines are commands can opt in. Goldens: leader gains SPC t t; theme's fourth NextColor no longer wraps to helix because the ring is fifteen long. New: themesel.
* focus history is a stack of locations, and the Jumplist is that same stackGabriel Schneider2026-08-01
| | | | | | | | | | | | | | | | | | | | | | | One container, not two: focus_hist (a stack of pane ids rebuilt every sync) is now jumps[] + a current pointer, and the +Jumps buffer is a RENDERING of that array — nothing copies it, nothing shadows it. prevFocus, Toggleterm, Look's directory order, Back/Forward, Last and Jumplist all walk the one list. A pane id is reused, so a location that only remembered an id would retarget after a respawn: panes now carry a monotonic serial and an entry whose slot holds a different serial is dead. trackJump compacts those out and fixes the pointer in the same pass. The push rule lives in ONE place and says: a location is worth remembering when you cannot see it any more — a different pane, or more than a bodyful of rows away in the same one. So hjkl never grows the list and 100G, a search hit and a goto-definition do. Ctrl-o/Ctrl-i walk it, SPC j j toggles the last two, SPC j l lists them. Ctrl-i IS Tab on a legacy host, where the binding simply never fires and Tab-executes is untouched; kitty reports them apart. SPC j o/i work anywhere. Two goldens moved, both the SPC ? Help listing gaining four rows.
* Look and Exec are builtins like any otherGabriel Schneider2026-08-01
| | | | | | | | | | | | | | | | | | | | | | Their only special feature is now the keys they are assigned. `Look main.zig` typed in a tag is the same look a right click is; config.look_cmd/exec_cmd point the two buttons and Enter/Tab at them, so retargeting Enter to Grep is one line. actOnSelection — a hand-written cascade with the builtin dispatch nested inside it — is gone, and the `button` parameter it threaded through five KEYBOARD call sites went with it. New syntax, spelled once in config.zig: @`ls -la` names a command to run rather than a file to open. Word expansion takes the quoted run whole, the way acme does for its own </|/> words, so a click inside one does not hand Look the fragment `ls`. And it nests: @`Look .` unwraps, re-enters the dispatcher, and looks at the directory. Guarded at depth 8, which is unreachable today (every re-entry strips a word or a delimiter pair, so the string strictly shrinks) and exists for a future syntax that does not shrink. leader_path is now optional: a builtin may have no SPC path when its shortcut is a key and a mouse button. New golden cmdword; the other 59 unmoved.
* output panes remember the command that opened themGabriel Schneider2026-08-01
| | | | | | | | | | | | | | | | An output buffer was a file pane with a flag, and everything special about it was re-derived from outside by asking the wrong question: the buffer NAME ("+Search", "+Help"), a parallel search_kind field, and f.output predicates sprinkled through kind-agnostic code. Now it carries its Origin — the Builtin, or the lsp.Kind for the five gotos helix binds as motions rather than words — plus that command's argument, and one Traits table answers every question the scattered code used to ask: what it is called, whether n/N steps it, whether it is a doc for layout, whether Esc dismisses it, whether it saves. The name is derived FROM the command instead of being the thing that identifies it. Adding a kind of output pane is adding a row. No golden moved.
* config.zig: every binding and every piece of Look syntax in one fileGabriel Schneider2026-08-01
| | | | | | | | | | | | | | | | | | | Retargeting a key, a mouse chord or a spelling is now an edit to src/config.zig and nothing else. Three parts in reading order: pardes's own bindings (where a reader lands), the Look/Exec syntax, then the helix keymap under a banner saying hxdiff/hxparity are differential suites against real helix, so a key moved there is a divergence and not a tweak. The bindings are data a comptime loop can walk, because the builtin index is going to walk them. Duplication this cut: is/isC/isA became one hit(key, chords) over ~132 call sites, and a binding being a LIST collapses the letter-or-arrow chains; swap_enter_tab is gone, replaced by look_key/exec_key that can point anywhere; the four focus builtins' h/j/k/l lived hardcoded in two places and is now one table. No golden moved.
* structure: backends into src/{tty,gui,lsp}, pane kinds and builtins into ↵Gabriel Schneider2026-08-01
| | | | | | | | | | | | | | | | their own files The core now lies FLAT at src/ and every subdirectory is one backend, so a file being in no directory at all is what says it is core. Pane-kind bodies leave pardes.zig for term_pane.zig / file_pane.zig / output_pane.zig, leaving it the layout, the event/effect machine and the generic render loop. Builtins are one struct each in builtins.zig, and the enum is folded out of the file's own declaration list at comptime — a zig file IS a struct, so the list of builtins and the builtins themselves are the same text. Adding one is writing a struct. Key paths deliberately stay one table for the config pass. Pure refactor: no golden moved.
* next-steps: the roadmapGabriel Schneider2026-08-01
|
* adding better search to tty modeGabriel Schneider2026-08-01
|
* fix: every external-scanner grammar crashed pardes on parse ↵Gabriel Schneider2026-08-01
| | | | (rust/cpp/python/...; e.g. opening agave cpi.rs or any tracy .cpp), Debug AND ReleaseSafe. Root cause: clang -fsanitize=function (in zig's default C UBSan set) traps at the runtime's indirect call of the scanner because grammars declare external_scanner_create() with EMPTY PARENS — a K&R non-prototype whose type hash differs from the void*(*)(void) pointer type. The ud1 trap lands on a bogus inlined line (stack.c:746), which cost the diagnosis a detour through rr (its gdbserver dies replaying past the task exit — core dump + coredumpctl worked; ud1 0x6(%eax) = SanitizerHandler kind 6 = function_type_mismatch; scanner-less c/zig grammars never crashed). Fix per review direction: -fno-sanitize=function on the grammar TUs in build.zig — uninstrumented callees make the runtime's call-site checks skip; the rest of UBSan stays live. Second half: fatal signals (SIGILL/SEGV/BUS/FPE) never run defers and bypassed the panic hook, leaving the terminal raw after a crash — root.debug.handleSegfault override now runs vaxis.recover() before std.debug.defaultHandleSegfault, verified in a raw pty (kill -ILL $PPID: rmcup + mouse resets precede the trace). Verified: rust/cpp/python opens work with real highlighting (snapstyle: keywords/strings/comments colored), agave cpi.js 2.7k-line open fine, suite 30/30, ReleaseSafe build opens rust identically.
* dumps: per-user data dir + timestamped names; Restore builtin loads a dump ↵Gabriel Schneider2026-08-01
| | | | into the live session. dump.outPath resolves $PARDES_DUMP verbatim (the snapshot harness pins /tmp/pardes-dump.zon so dump/load/restore goldens stay deterministic), else $XDG_DATA_HOME|~/.local/share /pardes/pardes-YYYYMMDD-HHMMSS.zon (dir mkdir-ed; wall clock via libc clock_gettime — std.time.timestamp is gone in 0.16). After write_dump the shell reports the written path back (core.setLastDump) and the topbar grows "Restore <path>": middle-clicking Restore reloads the last dump, and "Restore <path>" executed anywhere takes the path as its first argument (onSelect prefix match). Core stays sans-IO: the builtin stashes restore_req; each shell consumes takeRestore() after drainEffects and swaps in initFromDump at the current screen size (pre-sized: dump panes never greet), tearing down the live ptys (tty: cancel reader + close + gen bump; gui: SIGKILL, the gen-guarded eof closes the old fds). Web ignores it. New restore.snap golden: KEEPME survives the restore, GONESOON echoed after Dump does not, the topbar word appears then resets. 29/29.
* merge: twelve parallel changes — bug fixes, features, posix port — plus ↵Gabriel Schneider2026-08-01
| | | | | | | | | | three merge-state fixes born of branch interactions. Branch work merged: tty exit cleanup (krluslzz), drag-select effect-queue crash (zopqvlll), single-pane layout rule (tutmotnl), tty input coalescing + -Dtracy (olnvomwz), / file search (syqzvmkl) + generalized n/N look motion (nmzypsto), ghostty middle-click diagnosis (sqonpmsz), NOR/INS/TTY mode indicators (opmrortk), cursor-row gutter highlight (nymrwpwq), look path:NN centering (oktvtuss), scrolloff (wlqqyvvo), posix portability (pzwluyuw). Merge-state fixes: (1) splitBelow caps keep at body-(BOX_H+3) so a content-full source still leaves the new pane a tag + a few body rows — Alt-n from a full shell was born 0 rows tall (caught by ttylook: OVER marker had no rows to render in). (2) spawn-effect pane-id reuse crash (user-reported panic at drainEffects assert): no close effect exists, so a deleted pane pty lingers in its slot until a respawn lands on it — both shells now reap the stale pty at spawn (tty: cancel reader + close; gui: SIGKILL, reader delivers the old fd through the eof event) and per-slot generations drop the dead shell late output/eof, which otherwise nuked the NEW pty on the reused id. New respawn.snap golden; fails on the pre-fix assert. (3) dedup re-look now lands the modal cursor on the target line (cur_row/cur_col/cur_pinned) — scrolloff cursor-anchored reconcile otherwise yanked the recentered view back to the stale cursor (caught auditing look-center: center-dedup stayed at 97-102 instead of 146-154); this is also the requested focus-moves-cursor behavior. look-center dedup/clamp clicks re-aimed for the merged layout geometry (typed row moved from 18 to 15). Goldens reconciled by regenerating from the merged binary and auditing every diff against its origin branch; deltas are exactly: indicator text/width shift, layout-split pane sizing, cursor-row gutter styling, centering shifts, and the pane-edge hover dash now coinciding with new pane boundaries. Suite: 28/28 (27 + respawn).
* roadmap: the first next-steps.txtGabriel Schneider2026-08-01