summaryrefslogtreecommitdiff
Commit message (Collapse)AuthorAge
* The documentation site's landing page has four short silent clips in ↵Gabriel Schneider44 hours
| | | | | | | | | | | | | docs/site/media, recorded from a hidden test window by test/record_demos.py text-is-the-interface, terminals-are-panes, scripting-over-9p and diff-review: each a webm (VP9), an mp4 (H.264, faststart) and a poster PNG at 960 px, with captions.txt. The script drives a PARDES_TEST session on the virtual clock through stdin mouse events, keys and 9P, keeps the settled frame after each step, draws the pointer and loops each clip with a dissolve back to its first frame. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* The docs become a website: a page per chapter, a landing page with ↵Gabriel Schneider44 hours
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | recordings, one Typst bundle run docs/site/site.typ writes every page in one bundle compile: the landing page (the tagline, the recordings listed in media/clips.toml, links to start from), a page per entry of `chapters` in style.typ, and the tutor. Every page shares a tag-line header with the chapter words; #doc links resolve to the right page and anchor; a chapter with four or more sections gets an "On this page" list. Links are relative and pages flat, so it reads from file:// or any static server. `zig build site` installs it to <prefix>/share/doc/pardes/site and fails plainly without typst. The look is 0x4200.cafe's lapis layout (framed panels, hard shadows, a tag-line trail, Departure Mono headings over Crimson Pro) in orchard's greens and amber, forestbones_light when the reader prefers light; both fonts are OFL and shipped. In HTML a key is one pill with its + and ›, and a mouse button is an inline SVG in currentColor. The tagline lives once in style.typ for the sheet, the book and the site, and the single page html.typ gives way to the site. The landing leads with one plain sentence (columns of panes, click to run or open, helix keys, scripts through files), then the tagline and a line on where it runs; a hero image is the first ready clip's poster; "Start: the guide" leads the links, "Hands on: the tutor" next, the rest a plain row; the captions use no undefined words. docs/typ/install.typ holds the install lines once: setup.typ has an Install section that includes it, and the landing includes it too. Building says up front it is for contributors and points at setup to install. In HTML the guide's glossary is a closed <details> (#glossary, the same heading and table on paper), each drawn mouse carries hidden text (left-click, hold left, click middle) for screen readers, w3m and copying, and the footer takes a source link and a licence from `project` in style.typ once decided. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* The docs give back the day-one lines the trim cut, the tutor becomes ↵Gabriel Schneider44 hours
| | | | | | exercises on a +Tutor copy, the README builds the GUI and says what a terminal needs, and Shift-Esc says it needs the kitty keyboard protocol Co-Authored-By: Claude Opus 5.5 <[email protected]>
* The docs trimmed to their path: a guide with Words you'll see and one Where ↵Gabriel Schneider44 hours
| | | | | | commands run and panes go table, scripting's first tag word Fmt and eight traps, setup as the one home of the pager and the servers, a scannable cheatsheet, an honest README, the edge cases moved to the reference, and the pager's colours Co-Authored-By: Claude Opus 5.5 <[email protected]>
* A name held for its newline that no newline could make good (a terminal's, a ↵Gabriel Schneider45 hours
| | | | | | component over 255 bytes, a path too long) is refused by the write that held it, not at the close (monkey9p's close_runs_only_line_files; follows sswkwwvv) Co-Authored-By: Claude Opus 5.5 <[email protected]>
* The web build compiles again: a dump asks whether a picture is on disk only ↵Gabriel Schneider45 hours
| | | | | | where there is a disk (fixes zkmtpmmq) 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 Schneider45 hours
| | | | | | +New's does, never writing a file named +Tutor Co-Authored-By: Claude Opus 5.5 <[email protected]>
* SPC q runs Exit, refused once over unsaved panes as the tag word is, as ↵Gabriel Schneider45 hours
| | | | | | helix's :q Co-Authored-By: Claude Opus 5.5 <[email protected]>
* A setting only the other frontend has (Font, GripWidth in a terminal) is ↵Gabriel Schneider45 hours
| | | | | | passed over in the init file, not failed: one init file serves the window and the terminal Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Every pane pardes spawns gets $PARDES_MOUNT, the session's own directory ↵Gabriel Schneider45 hours
| | | | | | | | | | | | under 9ns --mntgen ($NINE_MOUNT/pardes/<name>), unset when it is not known 9ns says --mntgen with NINE_MNTGEN=1 (cloud9). Under `9ns --unix` the mount is the server it dialled, never this session (its socket does not exist until it starts), so it stays unset there; scripts fall back to `9p -a "unix!$PARDES_9P"`. Nothing is statted: the name comes from the session's socket and the environment. selfmount checks both modes. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* `> exec` through a mount no longer hangs the editor, and a close holding a ↵Gabriel Schneider45 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]>
* `pardes --wait` whose $PARDES_9P no longer answers says the session is gone, ↵Gabriel Schneider46 hours
| | | | | | exit 1, instead of drawing a screen of its own in the asker's terminal Co-Authored-By: Claude Opus 5.5 <[email protected]>
* A dump no longer embeds a picture or a PDF that is on disk: Restore reads it ↵Gabriel Schneider46 hours
| | | | | | | | | | | from there, as a clean file's text is Every Dump carried each image's and PDF's bytes in base64 (a 900 KB PDF made a 1.3 MB dump), and a Restore showed that copy however the file had changed. One on disk now goes by its path alone; one not on disk (no file behind it) still has its bytes kept. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* A +Pager keeps its program's colours: the session parses what /pager is ↵Gabriel Schneider46 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
* Saving the init file in a pane (Config) applies its settings at once; its ↵Gabriel Schneider46 hours
| | | | | | | | | | | | commands are not run a second time A setting changed in the init file took effect only at the next start. The host's Save now hands a written init file's text back to the core, which applies its setting lines again (each idempotent), with the same notice and err for one that fails; a command line in it (`Newcol`) belongs to the start and is left alone. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* The init file reads past a UTF-8 BOM, and every line it fails is said and ↵Gabriel Schneider46 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 Schneider46 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 rename preview's rows are one format whichever file they are in: ↵Gabriel Schneider46 hours
| | | | | | | | | `file:L:C-E`, the range's end too, for the asked-about file as for the others The asked-about file's rows said `file:L:C` while other files' said `file:L:C-E`. lsp-rename-files is re-recorded for the one row it shows. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* A look at a path not there under a peer's mount is a miss, the write ↵Gabriel Schneider46 hours
| | | | | | | | | answered, as any path to no file is It failed the write with the peer's "file does not exist". A file not found, here or through a mount, is now said and logged as a miss. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Mount dials: a relative socket path is a bad dial address, a socket path not ↵Gabriel Schneider46 hours
| | | | | | | | | | there says no such socket (ENOENT), and the hint says tcp! takes a numeric address `Mount peer rel/x.sock` dialled relative to wherever the editor ran; `Mount peer unix!/nonexistent` said `dial failed: no answer` (EIO); and the hint offered `tcp!host!port` where only a numeric address is taken. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* /pager takes one directory an open, as pty/run takes one line: a second ↵Gabriel Schneider46 hours
| | | | | | | | | | line, in the same write or the next, is refused EINVAL Through a mount `printf 'a\nb\n' > pager` arrives a line a write, so the second asked for another +Pager on the same open, its answer replacing the first. An open that asked already refuses another. 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 Schneider46 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]>
* An exec or Tty from a pane whose directory is a peer's path refuses before ↵Gabriel Schneider46 hours
| | | | | | | | | | | making any pane: `exec: <dir>: no such directory`, no `exit 127` pane left A peer's directory (`/n/peer/x`) is no directory on this host, where the shell starts, so a command there ran in a pane that could only say `(pwd) exit 127`, and a Tty made a new/del pair. missingDir now counts such a path missing, as it does a local directory that is not there. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* An unsaved pane restored from a dump that says nothing of its disk (no ↵Gabriel Schneider46 hours
| | | | | | | | | disk_hash, an older dump) asks at its first Save, as for a file changed on disk What its text was read against is unknown, so a Save could write over a newer file without a word; it now asks once first. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* A command or terminal pane refused for room is refused before anything is ↵Gabriel Schneider46 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]>
* A command line runs when its newline comes, or at its open's close, never ↵Gabriel Schneider46 hours
| | | | | | | | | | | | | | | | because a write was short: a long line cut by a mount is one line A write shorter than its message, and not a multiple of 4096, was taken as whole, its tail a line. 9ns cuts a FUSE write of up to 512 KiB into 65512-byte Twrites, the last one short, so a 600 KiB `Edit ,c/.../` arrived cut and its tail ran as an unknown control message; the 1 MiB refusal failed the same way. Each open now holds a partial line until its newline, or its release, which ends the last line; an Edit block is whole when it closes, as before. A name write with a NUL still fails its write at once. selfmount writes a 600 KiB Edit line and a 1.1 MiB line through a real 9ns mount; building.typ says how lines are cut. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Grep's miss says `Grep: text not found`: it is a literal search, and ↵Gabriel Schneider47 hours
| | | | | | | | | "pattern" suggested a regular expression Still ENOENT through a mount ("not found" is in 9ns's table, and the unit tests' errno-words check holds it so). The guide's quote follows. 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 Schneider47 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]>
* Release Pardes 0.23Gabriel Schneider47 hours
| | | | Co-Authored-By: Claude Opus 5.5 <[email protected]>
* The docs take round 36: empty names, get as an undo step, what a Dump keeps ↵Gabriel Schneider47 hours
| | | | | | and Restore reads, Find and Grep caps and notes, the ctl read's collapsed and fit/tint, PDF search hits, ./x misses, 1 MiB lines, DumpDir, bad dials, /pager files, rename previews, Lspinfo, and --wait from an agent Co-Authored-By: Claude Opus 5.5 <[email protected]>
* A language server goes with its children when reaped, and every server's ↵Gabriel Schneider48 hours
| | | | | | | | | | | | | | process group is killed as pardes exits: no zls or `zig build --build-runner` outlives the editor The server is spawned with setsid, its own group's leader, but reap() signalled only its pid, and nothing reaped the servers at exit: the socket closing was left to tell them. zls busy in its build runner at a cold start did not notice, and lived on with its `zig build` for as long as no one killed it (found as three orphans 40 minutes after their sessions had gone). reap() now signals the group, and an atexit hook, registered at the first spawn, kills every server's group. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* `pardes --wait FILE` with $PARDES_9P set but no pane of its own (an agent's ↵Gabriel Schneider48 hours
| | | | | | | | | | | | or a script's EDITOR) asks that session and waits there, not a screen of its own Forwarding asked for $PARDES_PID and $PARDES_PANE, which only a pane's shell has, so a client that talks to a session from outside its panes got a full editor drawn in its terminal. With --wait and $PARDES_9P alone, the file is looked at through the session's root look and the wait is for that pane's del. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* A Mount dial with a network pardes does not dial (`nowhere!x`) is a bad dial ↵Gabriel Schneider48 hours
| | | | | | | | | | | address, EINVAL, not a session name that does not answer A dial with a `!` and no `/` that was neither tcp!, quic! nor unix! was taken for a session's name, failing as `dial failed: no answer`, EIO. It is now refused as the malformed address it is, before any dial. A path with a `!` in it still dials. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* DumpDir refuses a relative directory and one that may not be written, up ↵Gabriel Schneider48 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]>
* A ctl, exec or look line over 1 MiB is refused once, EINVAL in words a mount ↵Gabriel Schneider48 hours
| | | | | | | | | | | | | maps, and the rest of it is dropped through its newline, not run as a second line Past the 1 MiB a line may hold, the write that crossed it was refused and the pending text dropped, but what followed of the same line was taken as a new line and ran when its newline came: a second refusal, `unknown control message "zzz…"`, and a second err. The open now drops the rest through the newline, and the refusal says `invalid write: a line or Edit block over 1 MiB`. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* A look of `./x` that is not there is a miss, as `x` and `/abs/x` are: the ↵Gabriel Schneider48 hours
| | | | | | | | | | | write answered, the err logged, not ENOENT `./x` and `../x` failed their write with ENOENT while every other name that opens nothing was a miss the write was still answered with. They are misses now too, said and logged `look: ./x: no such file`. A pane's own directory gone stays a failure. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* A pane's ctl read says Collapse and a PDF's PdfFit and PdfTint (`collapsed`, ↵Gabriel Schneider48 hours
| | | | | | | | | | | | `fit:height tint:full`), and a Dump keeps the PDF's two Neither showed in the tag or the ctl, and a Restore brought a PDF back at width fit and the default tint. The ctl read ends with `collapsed` when it is, and a PDF's `fit:` and `tint:` in the words PdfFit and PdfTint take; the dump's image record carries pdf_fit and pdf_tint (empty in older dumps: the defaults). Co-Authored-By: Claude Opus 5.5 <[email protected]>
* A PDF place `:P:H` whose search hit H is not on page P, or with no search, ↵Gabriel Schneider48 hours
| | | | | | | | | | | | | is a miss with an err, as a page past the last is The second number of a PDF place is a hit of the pane's search (its search rows are `file.pdf:P:H`), and one that named no hit turned to page P silently. pdf State.hitExists asks the pane's search for page P: a hit it does not have, or any hit with no search, is now `<file> has no search hit H on page P`, on the pane itself (`:P:H`) and from anywhere (`file.pdf:P:H`); a search row's hit is always there. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* /pager given a file that is not a directory says so, ENOTDIR, not `no such ↵Gabriel Schneider48 hours
| | | | | | directory` Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Lspinfo's exec answer is the +Lsp pane it fills: any language answer that ↵Gabriel Schneider48 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]>
* Find's notes stay at the end, under the names it found, as Grep's do: `1 ↵Gabriel Schneider48 hours
| | | | | | | | | | directory skipped` no longer sorts first Find's rows are sorted by path as they are filled in, and the note line was sorted with them, so it led the list. The rows above the first note are sorted, the notes left where they are. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Grep and Find say when a cap hid what they might have found: `cut at 512 ↵Gabriel Schneider48 hours
| | | | | | | | | | | | | | | | hits`, `N files read only in part (first 256 KiB)`, `walk cut at N entries`; one that finds nothing leaves the +Search as it was Grep reads 256 KiB of a file and stops at 512 hits, and its walk at 20000 files or 100000 entries; Find stops at 512 names. A cap hit was silent, so a match past one read as `pattern not found`. The walk now notes each cap it hit (fs.WalkNotes) and the +Search says it in a line under the hits, as it says directories skipped; a search that found nothing but hit a cap opens the +Search with those lines, not a miss. A Find or Grep that finds nothing and passed nothing over leaves the directory's +Search with the last search's rows, its failure saying so, where it used to empty it. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* A language server that failed a moment ago is said to have failed, with when ↵Gabriel Schneider48 hours
| | | | | | | | | | it is tried again, not `language server for .zig not found` During the backoff after a failed spawn or handshake, ensure() answered NoServer, which the client turned into "not found" for a server that is installed. It is now Backoff, said `zls failed recently; retry in Ns`. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* A Rename the server answers for this file alone, while other open files of ↵Gabriel Schneider48 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]>
* Restore reads a clean file from disk, and an unsaved one whose file changed ↵Gabriel Schneider48 hours
| | | | | | | | | | | | | | | | | | | | | since the Dump is said changed, its first Save asking before overwriting it A Restore put back the dump's copy of every file pane and armed the watch with the disk as it now was, so a file changed on disk after the Dump came back as its old text, marked clean, and the next Save wrote the old text over the new without a word. A clean file pane's text is now not in the dump: Restore reads its file (an older dump's copy is read past too, and used only when the file is gone). An unsaved pane keeps its text once, base64, the plain copy beside it dropped, with the hash of the file it was read against (`disk_hash`); a Restore that finds another there says the file changed on disk, and Save asks once before overwriting it, as for a change seen while it was open. file_watch.zig's own tests were never collected (no test root imported it): main.zig's test block does now, and the restored watch test says what a clean restore now reads. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Release Pardes 0.22Gabriel Schneider2 days
| | | | Co-Authored-By: Claude Opus 5.5 <[email protected]>
* The docs take round 35: cloud9's errno table, Restore's parser words, insert ↵Gabriel Schneider2 days
| | | | | | after a match, LookWord list rows, the last-run awk without exit, command pane directories, rename previews, listings that keep the keyboard, set-value toggles, pty/run one line a write, /pager resolving, PDF :N:H, skipped directories and Lspinfo Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Petscii, Palette, Ascii, PdfFit and PdfTint take the state their tag word ↵Gabriel Schneider2 days
| | | | | | | | | | | | | names, set rather than flipped: `Petscii on`, `Palette terminal`, `PdfFit width` Each could only flip, so a script had to read the tag to know which way a write would go. Each now takes an optional argument, the value its tag word shows (on|off for Petscii and Ascii, commodore|terminal for Palette, width|height for PdfFit, disabled|filtered|full for PdfTint), and sets it; bare, it flips as before. Anything else is refused with what it takes. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* A file name with a newline is refused naming it once: `pardes: ↵Gabriel Schneider2 days
| | | | | | | | | | two\nlines.txt: a file name is one line...`, not `a file name: a file name ...` The refusal's subject was the words "a file name", and its reason began with them again. It now names the name given, its newline shown `\n`, as /log and /index show one. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* A second LookWord list look in a directory refills its +Search, as a ↵Gabriel Schneider2 days
| | | | | | | | | | terminal's word looks already did, rather than stacking another Each word looked at with LookWord list opened a +Search of its own in the same directory. Word looks now share the directory's one, the next word refilling it; a `/` search still keeps a +Search each. Co-Authored-By: Claude Opus 5.5 <[email protected]>