summaryrefslogtreecommitdiff
path: root/src/pardes.zig
Commit message (Collapse)AuthorAge
* A name typed into the tag's path survives Esc, pending, as any edit does: ↵Gabriel Schneider68 min.
| | | | | | the next Enter renames the buffer, a second Esc drops the draft, and a stray key meanwhile changes nothing but says so Co-Authored-By: Claude Opus 5.5 <[email protected]>
* An Edit's held write: < | > commands no longer block their 9P connection ↵Gabriel Schneider5 hours
| | | | | | (answered like a held read, so a status read or a filter reading the session's own mount runs beside it), a Tflush or hang-up of the write kills the commands' process groups and changes nothing; e loads by Get's way (asked once, clean after, undo puts the name back); ~ in e r w f B; B checks every name first; an Edit that runs commands is a write of its own, refused up front with other lines; Edit's +Errors output keeps the keyboard where it was; X goes in pane order; a refused write open says its errno; the reference's Coming from acme rows say what Get file's undo, failure and directory refusal, Putall's answer, Zerox across Dump and Incl's directories now do Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Edit runs acme's file and shell commands: < | > through the session's Shell ↵Gabriel Schneider7 hours
| | | | | | off the loop (one undo step, a failure changes nothing, its stderr in +Errors, a 9P write answered when done), X and Y over the open text panes, b B D e r f w and the "file" address; checked against sam -d, and the reference's Edit section and Coming from acme row say so Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Zerox opens a second pane on a file pane's buffer: one text, undo and ↵Gabriel Schneider7 hours
| | | | | | | | | | | | | | | | unsaved state, a scroll and a cursor each; an edit in either is spliced into both at File.setContentSpan, O(the edit) more, and what a Save, a get, the disk watch or a rename changes on one is copied to the rest after each step Twins share the content buffer, the History and, while it is one, the line index; the other twin's cursor and scroll move past the splice as acme moves a clone's q0. Del of one twin asks nothing while another holds the text, Exit lists the text once, and a closed twin keeps a copy of its own until it is torn down. Both are in the index, each its serial, one name. An event reader on one hears no edit made through another (first cut). A dump keeps the twins as two panes on the file, not linked again. perf: edit-twin, typing beside a twin of the 50k-line file, gated within 3x of edit-char in the same run; the three baselines re-recorded for it. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Tab N sets a tab's width in cells, 1 through 16, in every pane, drawn and ↵Gabriel Schneider7 hours
| | | | | | | | | | | counted (wrapping, clicks, the cursor); bare Tab says it; the ctl read and a Dump keep it A session setting, not acme's per window: the width is read by File's pure width functions (~130 callers that are given no pane), so it is one value, config.tab_now, that Runtime.apply sets and a new session resets. A file:L:C column counts runes, as compilers do, and never depended on it. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Incl dir ... adds directories a look at a name found nowhere else is tried ↵Gabriel Schneider7 hours
| | | | | | in, as acme's includename, <stdio.h> too; bare Incl lists them and Incl - empties them; the session's, seeded with /usr/include and /usr/local/include, kept in a dump; Indent's refusal says Enter keeps the indent always Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Enter and Tab on a tag word tell an event reader as a click on it does, at ↵Gabriel Schneider9 hours
| | | | | | its place in the tag; only a look takes a diff line's address, an exec there takes the word (follows vpmzwuzk) Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Back and Forward keep to the focused file: Ctrl-o, Ctrl-i, the mouse's side ↵Gabriel Schneider9 hours
| | | | buttons (now the tty's 8 and 9 too), the builtins and 9P go to the nearest place that way in this pane, else in this file in another pane, else of any file; JumpScope all takes every place in order as before
* A look at a directory opens a pane listing it, as acme's directory window: ↵Gabriel Schneider9 hours
| | | | | | named dir/, its entries in acme's columns (bytewise, dotfiles kept, a directory's marked /), a look at an entry from there, Get or a look again reads it again, never dirty, Save refused; DirLook terminal keeps ls in a terminal Co-Authored-By: Claude Opus 5.5 <[email protected]>
* One Look path: Enter, Tab and a bare Look take what a click at the cursor ↵Gabriel Schneider9 hours
| | | | | | | | | | | | | | | | | takes, a diff line's address included, and an event reader is told of them as of a click The keyboard expanded the cursor's word on its own (look.expandedSel), so a diff line's address (and a hunk line's code word, without its +/-) was the mouse's alone: Enter on `+line` looked for the text in the diff. Now exec.operandAt is the one expansion: pointerOperand is it with a gesture's selection borrowed, the Enter/Tab path and a bare Look (exec.currentOperand) are it from the cursor, and both dispatch through mouse.dispatchPointerBuiltin, so a pane with an event reader hears a key's look or exec as a click's. A test runs one diff line and one file:12:5: line through a B3 click, a B3 sweep, Enter, a bare Look, the look file and an event write-back, and asserts each lands in the same file, line and column. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* An image's or a terminal's tag says petscii:on when it is drawn as glyph ↵Gabriel Schneider13 hours
| | | | | | | | art, as it always is with no graphics; Petscii on|off still chooses for when there are The images and tagbottomimage goldens are re-recorded for the word. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Builtins are chips that link to a glossary generated from the registry, and ↵Gabriel Schneider13 hours
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | the virtual filesystem is drawn as a tree #word draws a builtin as a chip on the tag's ground over a rule (Look and Exec in acme's look green and exec red), a <code class="word"> in HTML, and links it to its entry in a new Builtins chapter wherever that chapter is in the same output (the book, the site). The chapter is drawn from docs/typ/builtins-tty.json and builtins-gui.json, which `zig build builtins-json -Dplatform=tty|gui` writes from the registry and the Help rows (src/builtins_json.zig, tools/gen_builtins_json.zig; summaryOf in ninep/ctl.zig is now pub); style.typ merges them, marking the window-only words. The doc steps refresh their build's file first, and each build's unit-test fails when its file is stale. Everyday words first (`everyday` in style.typ), then groups by leader prefix as Help has them, then settings, the words with no path, debugging and internals, and last an A-Z index of every word. `zig build book` joins the doc steps. #fstree draws a directory tree with its connectors, a description column and links to the sections that document each file; reference.typ draws the served tree with it, each pane, pty and column file on its own line, and a test in config.zig checks it against ninep/tree.zig's files both ways. The cheatsheet has a two-level version. On the site the tree reads as `tree` text in w3m and wraps descriptions under the names on a phone. The site's tutor draws its B1, B2, B3 and 1-2 chords as mouse glyphs; the landing credits Plan 9 and acme, as does the book's title page; install.typ no longer lists the mirrors (the footer does). Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Alt/Option-click is B2 and Super/Cmd-click is B3, sweeps included, as in ↵Gabriel Schneider14 hours
| | | | | | | | | | | | | plan9port: a one-button trackpad can execute and look The core decides it at the press (mouse.emulateButton) and keeps it to the release, whatever keys are let go between. Ctrl-click stays a definition, and a program tracking the mouse still gets the plain click (Alt as its meta, Super as nothing). The SDL, macOS and web shells now pass Super; the macOS and web shells pass Alt on a click too. A terminal's mouse report has no Super bit, so in a terminal only Alt-click is B2. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* A bare Save on a +-named pane that is no output (+Tutor) asks for a path, as ↵Gabriel Schneider15 hours
| | | | | | +New's does, never writing a file named +Tutor Co-Authored-By: Claude Opus 5.5 <[email protected]>
* `> exec` through a mount no longer hangs the editor, and a close holding a ↵Gabriel Schneider16 hours
| | | | | | | | | | | | | | | | | | last line is answered at once: the line runs at the editor's next step A shell's truncating open of exec (or look, ctl, log, pager) sends a setattr that changes nothing; it waited for the editor to be quiet, and through a 9ns mount that quiet could never come: 9ns answers nothing else on the mount while the setattr is out, and the editor's step may be out reading a pane's file through it. This was the "truncating open of exec hangs, only in selfmount" mystery. Only a truncate of a pane's file or a tag waits now. A close holding a last line with no newline hands it to the editor's step (tree.runClosedLines, beside fillClosedPagers), as a /pager close does, and is answered at once; a refusal is the log's err. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* A +Pager keeps its program's colours: the session parses what /pager is ↵Gabriel Schneider16 hours
| | | | written after its directory with ghostty-vt, SGR becomes spans drawn over the plain text, every other escape is dropped, and PagerColor off pages it plain
* The init file reads past a UTF-8 BOM, and every line it fails is said and ↵Gabriel Schneider16 hours
| | | | | | | | | | | | logged with its line number, never silent A BOM made the first word unknown, a word no builtin has was skipped without a word, and a setting that refused its value said nothing (the init file ran with announcing off). Each failing line now leaves a notice and an `err - init file line N: <why>` record; `#` still starts a comment only at a line's start, so `#ff0000` stays a value. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* `answer z` quotes `z`, a bare `name` says it names nothing, and `Repl ↵Gabriel Schneider16 hours
| | | | | | | | | | | | | klingon` is invalid (EINVAL), its message citing no doc path A refused answer quoted the word `answer`, not the choice refused. A `name` with nothing after it was an unknown control message. A Repl of no such language failed EIO with a pointer into the reference; it now says `invalid language` (EINVAL, here and through a mount) and how many more there are. A builtin's failure that says invalid anywhere is EINVAL, as 9ns reads it. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* A bound REPL whose program exited is skipped, as the docs say: out of the ↵Gabriel Schneider16 hours
| | | | | | | | | | | | question, the running one taking the text, and a done command REPL's tag says no id Two bound REPLs always asked, an exited one offered and, chosen, sent nothing. Now an exited one is left out: one still running takes the text with no question, none running is said (`no program running`), and nothing runs as a command. A command pane bound as a REPL whose command is done no longer shows its id in the tag. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* A command or terminal pane refused for room is refused before anything is ↵Gabriel Schneider16 hours
| | | | | | | | | | | | | | | logged or answered of it, and a serial is never handed out twice A command pane with no room logged `new N` and `run N ls`, was answered to its exec, then went with `del N` and no `exit N`; and sync gave N back (`next_serial -= 1`) to the next pane made, so a script holding N found another pane under it. Tty did the same. Both now take a refused placement back at once, before the run is logged or the serial answered (the pane was never announced, so it leaves no record), and fail the write with no room. The decrement is gone: gaps are fine, and a serial once said names one pane for good. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Shift-Esc always backs out: in every mode and pane it goes to the previous ↵Gabriel Schneider17 hours
| | | | | | | | | | | | | | | pane, as Esc does from normal, and a raw program never sees it; Ctrl-b alone toggles raw Shift-Esc switched a terminal in normal or insert mode into raw, so the one key meant to get out of anything got a script or a person into a program instead. It is now handled before any mode: an open prompt is closed, insert mode left, a pending count dropped, and Last runs, the pane keeping its mode (a raw terminal stays raw). Ctrl-b is the only switch between raw and normal. The keymap's two chords become one, back_out; the cheatsheet row, the guide's mode table and the tutor say so, and the tty and builtins goldens are re-recorded. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* DumpDir refuses a relative directory and one that may not be written, up ↵Gabriel Schneider18 hours
| | | | | | | | | | | | | front, and a Dump that could not make its directory says permission denied A relative DumpDir was resolved from wherever pardes started, and one under a directory that may not be written was taken, the Dump failing later as `no such directory`. DumpDir now takes an absolute or `~` path whose nearest directory there may be written, and refuses any other with what it takes; a Dump refused by a directory above says permission denied (fs.deniedAbove), as a Save does. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Lspinfo's exec answer is the +Lsp pane it fills: any language answer that ↵Gabriel Schneider18 hours
| | | | | | | | | | | fills a pane answers that pane, made or filled again The answer was taken from the asking pane's search pane, which a listing like +Lsp never sets, so Lspinfo answered the file pane. The pane the answer filled is now known from what fillResults made or refilled, whatever kind of listing it is. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* A Rename the server answers for this file alone, while other open files of ↵Gabriel Schneider18 hours
| | | | | | | | | | | | | | | | | its language say the name, is previewed, never applied; Lspwhy shows the files synced first zls renaming at a declaration answers with that file's edits only, cold or warm, whatever it was told of (checked against zls directly: from a call site in main.zig it renames both files, from the declaration in util.zig it never does), so the first Rename applied in util.zig and left main.zig broken. The client now looks for the old name in the other open files of the language; when one says it and the answer left it alone, the edits are a preview with a row naming each such file, and the message row says the server renamed in this file only. Lspwhy carries the open files too, so its trace shows `synced X first` for the query it explains. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* A Rename that previews other files answers its preview pane to the 9P write ↵Gabriel Schneider19 hours
| | | | | | | | | | | | | that asked it, and says on the message row that it previewed and applied nothing A multi-file Rename filled a +Search preview but the waiting exec write answered the pane it was asked from, and nothing was said. lspResponse now notes the pane it filled (fs.lsp_result); the write that waited for the answer reads that pane back, as a look or an exec answers the pane it went to, and the message row says `Rename: N edit(s) across files, previewed, not applied`. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* A name under a directory that may not be searched or written is refused, ↵Gabriel Schneider21 hours
| | | | | | | | | | | | | | permission denied, and a Save there says so, not no such directory `pardes noperm/a/b/c` and `pardes /proc/1/root/x` took the missing directory for one Save would make, opened a pane and exited 0; its Save then said "no such directory". fs.deniedAbove finds the nearest directory there and asks whether it may be searched and written: forwarding refuses such a name, exit 1, "permission denied", and a failed Save says "permission denied", which the writer's 9P error carries as EPERM (9ns: EACCES). Co-Authored-By: Claude Opus 5.5 <[email protected]>
* A ThemeFile that fails to load changes nothing: /ctl and DumpConfig keep ↵Gabriel Schneider24 hours
| | | | | | | | | | | | naming the file last loaded, or none, so they always replay The request's path was taken as the theme file before the host had read it, so a file not found or not ZON left /ctl saying ThemeFile <that path>, and writing the report back failed again. The path a load succeeds with is now kept apart; a failure puts the request back to it (and watches it again), or to none. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* A +Pager pane whose text is a diff is drawn and looked at as a diff, as a ↵Gabriel Schneider25 hours
| | | | | | | | | | | | diff command pane is: git diff, show and log -p page into review With git paging into +Pager, a diff arrived as plain text: no colour for its sides and a right click on a hunk line searched the word. A +Pager pane now notes, as its text is set, whether its first 64 KiB holds a diff header or a unified hunk, and such a pane takes the diff highlighting and the diff look every diff pane has. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* A terminal's kitty graphics draw as glyph art where pixels cannot, and by ↵Gabriel Schneider26 hours
| | | | | | | | | | | | | | | | | | | | choice: Petscii on the pane, TermImages for new ones Under an outer terminal without kitty graphics a tty pardes cannot pass a terminal pane's images on, so it draws them itself as an image pane's Petscii does: each row of an image is matched to C64-palette glyph art over the cells it covers (GlyphArt.renderRect, the exact-grid half of GlyphArt.render), cached while it is on screen. yazi is still told the kitty protocol works, so it keeps sending its previews. The same art is a choice anywhere: the Petscii builtin now takes a terminal pane too (PaneKind.picture), flipping its images between pixels and glyphs, and a terminal holding images, or drawing them as glyphs by choice, says petscii:on|off in its tag as an image pane does. TermImages real|petscii (default real) is what a new terminal starts with; it is in DumpConfig, /ctl and the reference. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* pardes - reads stdin into a +Pager pane, and is a terminal's PAGER and ↵Gabriel Schneider26 hours
| | | | | | | | | | | | | | | | | GIT_PAGER, Pager pardes|off to opt out; command panes page through cat A paging command in a terminal, or run through its pty/run, sat in less, and a pty/run never answered. `pardes -` now reads stdin to its end, strips terminal escapes (colour, OSC, overstrike), and shows it: inside a session as a clean <cwd>/+Pager pane made through pane/new and back at once, outside one as a new editor whose first pane it is, as `vim -` does. A terminal's shell gets PAGER and GIT_PAGER set to this pardes's own path and `-` where the user's environment sets neither; `Pager off`, a setting in /ctl, init and DumpConfig, leaves terminals started after it to the environment. A command pane's one-shot shell keeps cat, its output being a pane already. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Callers, Callees, Refs and the type hierarchy words with one answer say ↵Gabriel Schneider26 hours
| | | | | | | | | | | where they jumped, "Callers: the one, <place>" A word that asks for a list jumps straight to a lone answer, with no list to show it was the only one, so the jump read as a definition jump or a miss. It now leaves a message naming the place. A definition's jump, which is its answer, says nothing new. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* With several REPLs bound for a language the pane always asks which, as ↵Gabriel Schneider26 hours
| | | | | | | | | | | | documented, whether or not a program runs in each Only REPLs with a program running were counted, so with two bound and one at its shell prompt the text went to the other without a word, and which REPL got it depended on what happened to be running. All bound REPLs are offered now; one chosen with no program running is sent nothing and says so. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Attach in a detached session is refused with words: bare is wrong #args, a ↵Gabriel Schneider26 hours
| | | | | | | | | | | | | name no session has is "no such session" A detached session's core has no frontend loop to take an Attach, so the word was asked and never answered: a ctl write of it succeeded and nothing happened. The core now knows it is a detached session's, and Attach there says why: bare names no session but itself, a name with no session behind it is said so, and one that is a session is told to be attached from a frontend. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* A diff line looks up the path and line it names, as any look doesGabriel Schneider26 hours
| | | | | | | | | | | | | | | | | | | | | | | | The look on a diff line was its own resolver: a walk up to .git/.jj from the diff's directory, its own "no such file here" and "deleted by this diff". A review tool's cached patch, in no repository, missed every file though the session's terminals sat in the checkout. Now a diff line only expands and transforms. Its expansion (what the hover shows) is the whole line for a header, a `@@` line, or a hunk line pointed at on its prefix, and its text is the look address the line names (look.diffAddress): `path` for `diff --git`/`---`/`+++`, `path:c` for `@@ -a,b +c,d @@`, `path:N` for a hunk line's new line (a removed line's, the new line now where it was). That text goes through the regular look exactly as if selected by hand: same resolution, placement and errors. A 9P look of a whole diff line takes the same transform. Kept: the line classification, hunk arithmetic, git prefix stripping and timestamp cutting (diff.zig). Gone: the repo-root walk, its messages, Target.old_side and deletesAhead, and the click's row stash (Pardes.diff_look). A test compares a B3 on a cached patch's line with a look of the hand-selected `entry/src/entry.rs:2` in the same session. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Recent and /recent keep PDFs and images as they keep files, and an open ↵Gabriel Schneider26 hours
| | | | | | | | | | | | file's row is where its dot is now Only text files were recorded, so a PDF read yesterday was not there to find again, and an open file's row showed the place it last closed at, stale by however far it had moved since. A PDF is kept at its page and reopened there from its row; an image by its path; an open one's row reads its pane's place at the time of the listing. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* A look at a PDF's page past its last is a miss, "has no page N", never the ↵Gabriel Schneider26 hours
| | | | | | | | | | | | last page in its place manual.pdf:999 on a twelve-page PDF showed page 12 and said nothing, so a stale or mistyped page number looked like a place found. It is now the miss a line past a file's end is, whether the PDF is open (it stays on its page) or not (nothing opens). A restore or a start-up page past the end still lands on the last. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* A Rename the language server finds nothing for says so, "Rename: nothing ↵Gabriel Schneider26 hours
| | | | | | | | | | here to rename", and fails the write that asked it An empty answer to a rename returned without a word, so Rename on a place with no symbol looked like a rename that worked. It is now the not-found failure every other query gives. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* The jump list never holds two entries in a row the same: when the one ↵Gabriel Schneider26 hours
| | | | | | | | | | | | between them goes, they are one A closed pane's entry dropped from between two visits to the same place, or a closed file's entry reopened beside its own, left twin entries, and Back spent a press going nowhere while Jumplist listed the place twice. The compaction that drops dead entries now folds a twin into the one before it, keeping the current entry on the one kept. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Save path logs a save record naming the path it wroteGabriel Schneider26 hours
| | | | | | | | | | | Save of a pane's own file logged `save <serial> <name>`, and so did a scratch's `Save path` (the pane takes that name). A `Save path` that writes a copy of a file pane, or a terminal's scrollback, elsewhere logged nothing, so a follower could not tell the file was written. It now logs `save <serial> <path>` with the path written, once the host has written it (events.noteLogAs). fs.md's log table says so. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* A terminal's word looks refill the directory's one +Search, as +Lsp is ↵Gabriel Schneider26 hours
| | | | | | | | | | | | | | shared, rather than stacking one per word Each word looked for in a terminal (clicked, or written to look), where no file of that name was, opened another +Search in the same directory, one per word, until the column filled. Such a search now refills the directory's +Search, as the file searches and the +Lsp answers already share theirs. A `/` search keeps a +Search per pattern, which n and N walk across (psearch.snap), so the sharing is marked on the word look alone (Pardes.word_look). Co-Authored-By: Claude Opus 5.5 <[email protected]>
* A pane refused for want of room spends no pane serial, as a refused Newcol ↵Gabriel Schneider26 hours
| | | | | | | | | | | spends no column serial A pane/new, look or exec refused ENOSPC made its pane before placing it. The refusal closed the pane unannounced, but its serial was gone, so the next pane skipped one. When sync removes a refused pane that holds the newest serial, it now puts the counter back. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* A focus moved over 9P tells the programs that asked for focus reports, as a ↵Gabriel Schneider26 hours
| | | | | | | | | | | | click does A program that set DECSET 1004 heard `CSI O` and `CSI I` when the keyboard moved by a click, a key or the window's focus, because update() checks after each event. A /focus write went through serveFs, which never did, so the program kept believing it had focus until the next input event. serveFs now runs the same check once a request has settled. Co-Authored-By: Claude Opus 5.5 <[email protected]>
*-. Release Pardes 0.9Gabriel Schneider26 hours
|\ \ | | | | | | | | | Co-Authored-By: Claude Opus 5.5 <[email protected]>
| | * A program that asked for focus reports (1004) hears CSI I when its pane ↵Gabriel Schneider26 hours
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | takes the keyboard and CSI O when it gives it up, to another pane, a tag or another window The core has a window-focus event now, from SDL's window focus and from the tty's own focus reports (vaxis turns 1004 on outside); the detached wire carries it: version 10. The test shell's ESC]777;mouse;focus;<1|0> fakes the window's. Co-Authored-By: Claude Opus 5.5 <[email protected]>
| | * A program that tracks the mouse gets its clicks, drags and moves over its ↵Gabriel Schneider26 hours
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | grid, in the format it chose; Shift keeps pardes's select, execute and look, and chrome is never the program's Presses and releases under 1000, drags with a button down under 1002, every move once per cell under 1003, X10 presses under 9, in raw terminal input only. A press the program took keeps its drag and release, reported clamped to the grid's edge wherever the pointer goes. The press also makes the pane the active one. docs/tags.md says so. Co-Authored-By: Claude Opus 5.5 <[email protected]>
| | * A mouse event carries Shift and Alt as well as Ctrl, from SDL and from the ↵Gabriel Schneider26 hours
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | tty's input; a program's wheel report carries them as xterm counts them, and Shift keeps the wheel pardes's own scroll The reports are ghostty's encoder now (shift+4, meta+8, ctrl+16), with the mode and format ghostty tracks. The detached wire carries the two new bits: version 9. The test shell's ESC]777;mouse takes an optional fifth field of modifiers. Co-Authored-By: Claude Opus 5.5 <[email protected]>
| * | A right click on a diff line opens the place it names: its file, the hunk's ↵Gabriel Schneider26 hours
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | new line, the line itself In a diff pane (a .diff/.patch file, or a command pane's diff output), the look's own expansion, which its hover shows, takes a whole line for a `diff --git`, `---`, `+++` or `@@` line wherever the pointer is on it, markers included, and for a hunk line when the pointer is on its `+`, `-` or space. Then the look opens the file (a/ b/ dropped, timestamps cut) at the line from the hunk header and the lines above it: `@@` the hunk's first new line, context and added lines their own, a removed line the new line now where it was. `diff --git` and `+++` open the new file; `---` the old one, unless the `+++` under it names another. On a hunk line's code the expansion is its words, the prefix never one of them, and looks as ever. Other panes are untouched. Paths resolve in the repository (walking up to `.git` or `.jj` from the diff's directory, or a command pane's), then that directory. A file not here opens nothing and says `Look: b/x: no such file here`, or `deleted by this diff`. A 9P look writing a whole line of the diff does the same. Co-Authored-By: Claude Opus 5.5 <[email protected]>
| * | A diff reads as the code it changes: hunks in their file's language, added ↵Gabriel Schneider26 hours
|/ / | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | and removed rows tinted A .diff or .patch pane, and a command pane whose output is a diff (`git diff`, `git show`, `diff -u`; told by a `diff --git` line, or `---`/`+++` with a `@@` under them, in its first rows), colour each hunk's code in the language of the file its section names (`+++ b/<path>`, `--- a/<path>` for a deleted file), with tree-sitter, as highlightLocations does for results. src/diff.zig walks a unified diff by its `@@` counts, so a removed line that reads `--- x` is no header. Each side of a hunk is parsed as one text (context and removed lines the old side, context and added lines the new), so a string or comment across lines colours as it does in the file; a side no line takes its colours from is not parsed. A section's hunks share a parse, in pieces of about 40 lines (a hunk past 80 is cut), only those in view, and each piece's colours are kept by its bytes, so scrolling back and a terminal's every repaint parse nothing again. Added and removed lines carry a flag in their style byte; the painter tints their rows to the pane's edge, a little way from the page toward the theme's ANSI green or red, and draws the prefix in that hue pushed to read on it. A file in no known language keeps the old line colours. A command pane is read once its command has finished: its rows are copied once (File.DiffOutput, dropped when the pane runs again), so no frame dumps the scrollback, and painted over what git printed. A running command is shown as it prints. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* | A detached session no client watches draws no frames: yes | head -c 50M ↵Gabriel Schneider26 hours
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | through pty/run goes from over 30 s to 11 s Profiling the 50 MB run showed 70% of its time in draw.render, recolorAnsi alone 43%, walking cells through PageList.pin. The detached session drew a frame after every pty read, with no client attached to see it. A host now says whether anyone watches (Host.VTable.watched). The detached server answers whether a client is attached, and while none is the core keeps the frame owed instead of drawing it. A /screen read draws its own, and a client attaching gets one (hello sets needs_frame). Debug, 80x24: 10 MB went from 7.36 s to 2.10 s, and 50 MB from over the 30 s client timeout (about 37 s by rate) to 11.08 s. What is left is the terminal's own parsing and scrollback growth. A session a frontend shows still draws after every read. Pacing those frames is the next step if that case matters. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* | Save makes the directories its file goes in, always: for the pane's own name ↵Gabriel Schneider26 hours
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | and Save path alike Whether a Save made missing directories depended on how the name had come about. Config's pane did, a name written into a missing directory did (since kkrqxtsp), and `Save path` and every other name did not, failing ENOENT instead. There is now one rule: a Save makes the parent directories of the file it writes, a pane's own or a terminal's scrollback included, and the make_dirs flag is gone. A directory it cannot make still fails the write with why, as fs.py's /nonexistent-pardes-dir case shows. fs.py now also saves into missing directories by Save path and by a written name. Co-Authored-By: Claude Opus 5.5 <[email protected]>