summaryrefslogtreecommitdiff
path: root/src/ninep/ctl.zig
Commit message (Collapse)AuthorAge
* The default Shell is $SHELL, else /bin/shGabriel Schneider4 days
| | | | | | | | | | With no Shell set, pardes ran fish, which a box may not have and a user may not use. The default is now the user's login shell ($SHELL), else /bin/sh; an explicit Shell still overrides it. The tests pin their own shell (snapshots bash, the python suites /bin/sh or bash) and pass with SHELL unset; the Config report and docs say where the default comes from. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* A msg said again word for word is that line counted in the logGabriel Schneider4 days
| | | | | | | | | | 1000 Undos with nothing left made 2000 log lines: the Verbose announcement and the answer each time. A msg repeating the newest record is now that record counted, (xN), as err's already were (shared as pushCounting), unless a follower has read it; and a builtin's own words that start with its name take the place of its announcement just before them. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Undo and Redo with nothing left say so, and the write succeedsGabriel Schneider4 days
| | | | | | | | | A pane's Undo or Redo with no step left did nothing and said nothing. It now says "Undo: nothing to undo" (or Redo's) as a message, not a failure, so a ctl write of it still succeeds as acme's silent Undo does. The docs give the 256-step history. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* A command line cut across writes runs once whole, and look/exec answer per openGabriel Schneider4 days
| | | | | | | | | | | | | | | | A mount cuts a write at its message size, and each piece ran on its own: a line cut at the boundary ran as shell commands and a 50 KB Edit block broke. An open of look, exec, tagexec, any ctl or a column's exec now keeps an unfinished last line, or an Edit block still open, until its next write or its release, and never runs a fragment. The same open record holds what its last write touched, which a read on it answers (as /net/tcp/clone does); an open that never wrote reads the session's last as of its open. A release that runs a held line waits for quiet and counts as a change; a clicked line with a control character is still refused at its write. Tested in unit tests, fs.py (python client, 8 KiB) and selfmount.py (the kernel mount, a 1000-line seq burst and a 50 KB Edit block). Co-Authored-By: Claude Opus 5.5 <[email protected]>
* The workspace tag has /tagexec, every exec file reads back what it touched, ↵Gabriel Schneider4 days
| | | | | | | | | | | | | | and a tag's words log as the session's /tagexec runs a word as a click in the workspace tag, as col/<serial>/exec does in a column's. A column's exec was write-only; it and /tagexec now read back the serials the last write touched, as /exec does. A click in a tag no longer goes to the focused pane's event reader, and what a word run from a column's ctl or exec or /tagexec says is logged msg -, not against the focused pane. The README, fs.md and the skill say so, and document the answer record. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* A look's miss repeats the path whole, up to 256 bytesGabriel Schneider4 days
| | | | | | | | | The miss message clipped what was looked at to 48 bytes, mid-word, and a path past 160 bytes turned the has-no-line message into a bare no match. Both now carry up to 256 bytes, cut on a character boundary with an ellipsis past that. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* A look at file:/re/ on an open pane goes on from its dot, and a miss leaves itGabriel Schneider4 days
| | | | | | | | | Look's clean start cleared the active pane's selection before the address read the dot, so the root look's file:/re/ always found the same match, a miss collapsed the dot to a caret, and dumps kept the collapsed dot. A pane already open on the path is now addressed where it stands. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Edit's refusals name the pattern, not the line, and say when dot is emptyGabriel Schneider4 days
| | | | | | | | | | | A ctl Edit that missed answered `Edit: no match for regexp "Edit /nomatch/d"`, quoting the whole program; it now names the address that missed (`no match for regexp /nomatch/`) and quotes no line after. An s on an empty dot says `no substitution: dot is empty`. A \\1 is blamed only once its pattern has matched, as before. tags.md says & is special in s and not in c, a or i, as in sam. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* A column has a ctl, an exec and an rmdir over 9P, and Restore maps its serialGabriel Schneider4 days
| | | | | | | | | | | | | | A script could read and write a column's tag but not act on the column. col/<serial>/ctl takes Delcol, Joincol, New and Tty, each acting on that column as from its tag; col/<serial>/exec runs a word as a middle click in the tag; rmdir col/<serial> closes an empty column and refuses one with panes (ENOTEMPTY, an err record saying why). The root ctl's refusal of Delcol and Joincol points at col/<serial>/ctl. A dump keeps each column's serial and Restore logs restoredcol <old> <new>; the dump golden gains them. Documented: Joincol's survivor, the column on the right, keeps its serial and tag. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* A focus write makes its pane's column the active one, and layout's active is itGabriel Schneider4 days
| | | | | | | | | | | Writing a serial to /focus gave that pane the keyboard but left the active column where it was, so pane/new under Placement acme went elsewhere, and /layout's active named the keyboard's column rather than where a new pane would go. A focus write now sets the active column as the user's click there would, under either Placement, and /layout's active names the active column, which pane/new and a look place into. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* A desktop session holds 64 panes, and every route that finds none free says soGabriel Schneider4 days
| | | | | | | | | | | | | Sixteen panes was far too few for a real session. MAX_PANES is now 64 on a desktop and stays 16 on the board; the 48 more slots cost about 3.7 KB each in fixed tables (the core 1.33 to 1.45 MB, its surface 19 to 72 KB), and a pane itself (84 KB and its terminal) is allocated only when it opens. At the cap, pane/new fails with `pane/new: no pane slots: 64 max` and an err record rather than a bare ENFILE, a 9P look or exec that would open a pane fails its write with the same words and reads back empty, and New, Tty, Tutor and Alt-n say it on the message row (their ctl writes fail with it). Co-Authored-By: Claude Opus 5.5 <[email protected]>
* A dump keeps the settings changed from a fresh session's, and Restore sets themGabriel Schneider4 days
| | | | | | | | | | | A session running with Placement pardes came back from Restore as acme: a dump kept the layout and the theme but no setting. It now keeps every setting line that differs from a fresh session's, as the root ctl reads it, and a Restore applies them; the theme stays where it was kept, the font the frontend's, and REPL bindings are still dropped. The dump golden gains the three the snapshot harness sets. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* A GUI-only setting says so on a terminal, and DumpDir reads back its directoryGabriel Schneider4 days
| | | | | | | | | | `Lift on` over ctl on a terminal answered "unknown control message" while Config listed Lift as unsupported, and the ctl's DumpDir line read bare while Config showed the path in effect. A setting word this frontend lacks is now refused as `Lift is GUI-only` (GripWidth too), and DumpDir reads back the directory in effect, as Config does. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* A failed Dump or a Restore of no dump fails its write, before any warningGabriel Schneider4 days
| | | | | | | | | | | | A Dump into a DumpDir it could not write, or a Restore of a file that is not a dump, answered a ctl write with rc 0 and only a message, and the Restore warned about unsaved panes before it ever looked at the file. The hosts' dump write now fails the waiting 9P write with EIO (the late failure a Save uses), naming the path and the reason in the log, and Restore parses the file before its unsaved-panes refusal, failing with `not a pardes dump`. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* A choice setting's refusal names what it takes, and /commands lists themGabriel Schneider4 days
| | | | | | | | | | | | Bare Placement and BootShell flip, which is pardes's convention for a word that chooses (Crt does too), but nothing said so, and "bad value in control message" never said what would do. A refused value now says `takes acme, pardes` (every switch and choice setting), /commands lists each such setting's values in a fourth field, and config.md and fs.md say that bare steps to the next. Motion and ShaderAnimation stepped nowhere bare and now step like the rest. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* An answer the question does not offer is refused, and the question standsGabriel Schneider4 days
| | | | | | | | | `answer z` to a question offering a and b succeeded, sent nothing and dropped the question; so did Del's `answer x`. The ctl now takes only an offered choice or -, refuses anything else with the choices it takes (`answer takes k j or -`), and leaves the question asked. Co-Authored-By: Claude Opus 5.5 <[email protected]>
*-. Merge: 9P round 6 + empty columns + render (acme theme, grips, Lift, Motion)Gabriel Schneider4 days
|\ \
| | * acme looks like acme; every theme gets acme's button, scroll column and 2px ↵Gabriel Schneider4 days
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | rules acme takes plan9port's own colours (acme.c iconinit, draw.h): selections #eeee9e in the body and #9eeeee in the tag, black ink; exec and look sweeps #aa0000 and #006600, white ink; a #99994c scrollbar under a #ffffea thumb; black rules; a #8888cc tag/body rule and column button. Every theme: the grip is acme's button, its tag row's full height, in one scroll column with the scrollbar (rail_px, 12 at a 17px tagline, scaled, times GripWidth, a percent, default 150; same x0/x1 to the pixel): focused clean = solid box; focused dirty = box_dirty filled to a box ring (acme's modbutton); unfocused clean = a box_border ring round the tag's ground; unfocused dirty = box_dirty a pixel inside that ring. The grid, which has no ring, marks dirty with a bold * on box_dirty in the grip's second cell and fills an unfocused grip halfway to its ring. Regions carry a dirty flag. Column buttons are the same shape, solid. 2px rules between columns and stacked panes (inside the tag band's slack), none at the window edge; a 1px tag/body rule halfway between tag and page. Theme data: tag_sel_bg, sweep_bg/fg, tag_rule, rule_px, rail_px, box_border, box_dirty. Chrome: rule_px, tag_rule, rail_px, grip_border, grip_focus_ring; a comptime guard on Chrome's layout forces a wire bump once v8 ships. Structural rules are exempt from the focus-indicator rule (docs/effects.md). Tests: acme widths; stacked rule in the slack at two tagline sizes; every grip-column pixel is band, button, ring or rule, and the button shares the scrollbar's x0/x1 (4 metrics x top/bottom x focus x dirty); the four grip states distinct in every native theme with a non-colour dirty cue in the grid; wire round-trip of the new fields. Shared files: src/colors.zig, src/surface.zig, src/body_layer.zig, src/tagline.zig, src/detached/wire.zig, docs/themes.md, docs/config.md, docs/effects.md, 21 snapshot goldens (the grip cells only), test/gui-goldens.txt. Motion flavours differ by design, and drive notice drops and pane moves
| | * Motion flavours, and Lift is shadow, rim or auto: auto on a dark page ↵Gabriel Schneider4 days
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | recedes the other panes (InactiveDim) Motion off|crisp|smooth|bouncy|playful is one parameter set (animation.Motion) every fx animation reads. One focus spring per pane drives both the lift and the dim, at the flavour's pace; a grid snaps. Lift drops glow and surface. A shadow falls on pane bodies and rails only, capped so text and the selection keep min(contrast, 4.5); rim is a hairline along the focused tag's top. auto is a shadow on a light page; on a dark page the core recedes the unfocused panes' text (InactiveDim, ported from 2e4d97f, default 30 under auto) with the same floor. Tests: focused text contrast is never below unfocused in any style, dim or theme; the focused pane's cells and tag are untouched by a dim. Shared files: src/config.zig, src/builtins.zig, src/ninep/ctl.zig, src/surface.zig, src/detached/wire.zig, docs/config.md, test/snapshots/builtins.snap (one more wheel for the longer help).
| | * Lift takes a style: shadow, surface, rim, glow or autoGabriel Schneider4 days
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The user wants Lift to read on dark themes, where a shadow has nothing to darken. `Lift shadow|surface|rim|glow|auto` (`on` is auto, bare flips auto and off): surface lightens the lifted part's ground about 5.5% (Material-dark), rim is a thin soft light off its top and left edges, glow a faint halo in the theme's accent (Chrome.accent, the focused box colour), auto a shadow on a light page and surface with half a rim on a dark one (by the page's luminance). Rim and glow are the soft kernel in a light colour (no pre-warp: coloured light is laid on as is, within §8.2's budget); each style is capped per theme so text keeps min(its contrast, 4.5) (tests: darkening and lightening over the native themes). The style travels in the palette (Chrome.lift_style, one byte on the wire). Config reports and ctl reads `Lift <style>`. Shared files touched: config.zig, builtins.zig, ninep/ctl.zig, detached/wire.zig (palette byte), gui.zig. Not touched: pardes.zig, Messages.zig, mouse.zig.
| * | A document dragged beside the boot shell leaves it; BootShell replace closes ↵Gabriel Schneider4 days
| | | | | | | | | | | | | | | | | | | | | | | | | | | it as before Placement and BootShell are one kind of setting now, a word from an enum, set, flipped bare, and reported by one arm. Co-Authored-By: Claude Opus 5.5 <[email protected]>
| * | A column can be empty, as acme's can; new panes go where acme's ↵Gabriel Schneider4 days
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | makenewwindow puts them Newcol makes an empty column; closing a column's last pane leaves it empty with the keyboard on its tag; Delcol and Joincol alone take a column away; the session's last pane closing quits. The +New stand-in and replaceStillborn / stillborn_joiner are gone. Every new pane goes through exec.placeNew, which follows acme's makenewwindow (active column, empty column whole, blank space, halving the biggest) or, with Placement pardes, the old rules. ColumnTags is gone: column tags are always shown. A grip drag shows acme's box cursor. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* | | A pane's question is logged as ask, and answer on its ctl answers itGabriel Schneider4 days
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | A script could not answer the several-REPLs question, which only a key could. Every question a pane asks on its notice band (which REPL takes an exec, Del's side from the keyboard) is now logged as `ask <serial> <what> <choices>`, and `answer <choice>` on the pane's ctl answers it as that key would, `answer -` taking it back as Esc does. One function answers for a key and for the ctl. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* | | A look with a blank in its pattern addresses, file:N selects the line, and a ↵Gabriel Schneider4 days
| | | | | | | | | | | | | | | | | | | | | | | | miss is said, logged and reads back empty Round 6: look calc.py:/return a/ was a word search, since a blank ended the address; calc.py:99 past the end focused the file and said nothing; and /look still read back the pane before a miss. A pattern after the colon may now hold blanks; file:N selects the line, newline included, as acme's does; a line past the end opens and focuses nothing; and every miss (no match, a bad address, a line past the end) says so, logs err <serial> look: why, keeps the selection, and leaves look reading back empty. Documented, with file:0/re/ for the first match, since acme evaluates the address from the file's dot. Five goldens change: a look at file:N now selects the line. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* | | A write of an Edit block reaches Edit whole, on a pane's ctl, the root's and ↵Gabriel Schneider4 days
|/ / | | | | | | | | | | | | | | exec Every write was split into lines, so a { group or an a/c/i text block written to ctl or exec became lines of their own: i/.../ and } ran as shell command panes that exited 127. An Edit line now takes the lines after it while its group is open or its text block waits for its . line (sam_edit.needsMore, asking sam's parser), on all three; the root ctl takes Edit at the active pane. s/re/text/N counts as sN/re/text/ does. The docs and the skill show a block written by heredoc or env printf, since bash's printf writes line by line, and take round 5's doc list: get refusing once, the (xN) on a repeated err, limit bounding only a forward search's end, line:col's clamping, and $NINE_MOUNT under 9ns --unix. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* | Edit runs sam's command language on a pane's body, as acme's Edit does, in ↵Gabriel Schneider4 days
| | | | | | | | | | | | | | | | one undo step Over 9P a rename everywhere was a loop of addr and data writes. Edit, from a tag, a pane ctl or exec, parses sam's commands as acme's edit.c does and runs them as ecmd.c does against the text as it was, collecting the changes in order as elog.c logs them and applying them at once: addresses (the addr file's, line:col included), x y g v c a i d s p = m t, u alone, and { }. One undo step; any error, in acme's words, changes nothing, fails a ctl write and is logged. p and = print to the directory's +Errors. Left out, and said: the file commands, the pipes, \1-\9 (mvzr keeps no submatches), and changes out of sequence, which acme applies with a warning. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* | The docs say how a --detach=NAME session is posted, what > does to tag, ↵Gabriel Schneider4 days
| | | | | | | | | | | | | | | | where #n inside a character lands, and what tag click offsets count; a refusal says which ctl takes the word, and a lock refusal who holds it Dogfood round 4's doc list: the recipe assumed pardes/<pid>; the README said tag writes append, though > replaces the editable text; #n inside a multibyte rune or grapheme snaps to its start, unsaid; a tag click's offsets count the path. A word written to the other ctl now says write it to pane/<n>/ctl or /ctl, and a held lock says another open of that ctl holds it. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* | get on a pane with unsaved edits refuses once, as acme's doesGabriel Schneider4 days
| | | | | | | | | | | | A ctl get threw unsaved text away at once. acme's get asks winclean first (exec.c:513): warned once, the same get again discards. A pane dirty only because it was renamed has no text to lose, and is not asked about. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* | Text brought back to what was saved is clean againGabriel Schneider4 days
| | | | | | | | | | | | dirty compared revisions only, so undoing to the save point, or typing the text back, left the pane dirty. The saved text's hash is kept from the first edit after a save or load, and an edit that makes the text equal to it marks the pane saved again, as undo to the save point does in acme. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* | What a root ctl write says is the session's in the log, msg -, not the ↵Gabriel Schneider4 days
| | | | | | | | | | | | | | | | active pane's A session builtin written to /ctl runs at the active pane, so its messages were logged under that pane's serial, as if the pane had said them. They are now `msg -`, and still shown on the active pane. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* | A look takes acme's file:addr and :addr, and one that finds nothing changes ↵Gabriel Schneider4 days
| | | | | | | | | | | | | | | | nothing A look at `file:/re/` or `:/re/` searched for the words instead of addressing, and a miss left an empty +Search pane and a cleared selection, while a hit answered the +Search pane on /look. Now an address after a colon (acme look.c:450) is evaluated in the file from its dot; a miss says no match and leaves the panes and the selection alone; a hit reads back as the pane the text is selected in. Both live in lookAt's one flow, so they are one change. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* | Undo and Redo are builtins, as in acme's tags, so a pane's ctl and exec can ↵Gabriel Schneider4 days
|/ | | | | | | | step its body Over 9P there was no way to take back an edit: acme's Undo and Redo were keys only. They are now pane builtins, reached from a tag, a pane ctl and exec, and listed in /commands. They are not added to the default tags, which would change every tag. Co-Authored-By: Claude Opus 5.5 <[email protected]>
*-. Trial merge: 9P + helix + renderGabriel Schneider4 days
|\ \
| | * Crt, Ripple and Glitch take a level, 0 to 3, tunable at run timeGabriel Schneider4 days
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Coordinator's request: `Crt 0..3` (likewise Ripple, Glitch), 0 off, `on` the default level 2 (the polished rewrite), `off` and a bare word as before. The level is one uniform (pardesLevel, beside pardesOpaque in the prefix's own block); each pass picks its constants by it. Level 3 is at least as strong as the old effects, measured as pixels changed by more than 8 in a channel against a plain frame: Crt 18.3% (old 17.4%), Ripple 11.1% (9.5%), Glitch 9.3% a frame (8.1%); Glitch's level raises how often it bursts as well as how hard. Config and ctl report `Crt 2` / `Crt off`. Shared files touched: ninep/ctl.zig (the report line). Not touched: pardes.zig, Messages.zig, mouse.zig, gui.zig, detached/*.
| | * Post chain: Shadertoy passes compiled by glslc; Crt, Ripple and Glitch ↵Gabriel Schneider4 days
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | rewritten as Shadertoy files Stage 9 of docs/render-pipeline.md. src/gui/Post.zig runs the chain over the finished frame: each pass reads the one before, ping-pong textures between, the last writes the window; an empty chain is the direct path. The prefix (shaders/post/prefix.glsl) is ghostty's uniform block, name for name and offset for offset (tested against a copy of its Uniforms, the selection colours by their GLSL names), at SDL GPU's bindings, y down. A user's file (Shader <path>) is compiled by glslc with compileGlsl's own flags on a thread of its own, taken in at the next loop step; errors name the file's own lines; a failed compile keeps the last good pipeline; glslc missing is said once. The bundled passes compile with the build, through the same prefix. Crt, Ripple and Glitch are Shadertoy files, rewritten: no barrel (input is identity, tested), everything in linear light and dithered, keyed to iTime. scene_effects, crt.zig and crt.frag.glsl are gone; the core keeps no clock for the chain. ShaderAnimation off|on|always drives redraw level A: the chain alone over the retained frame (34 us CPU a redraw, measured). Shared files touched: pardes.zig (nextWake loses the scene line, disableSceneEffects empties the chain, two tests), builtins.zig (one switch arm), ninep/ctl.zig (two switch arms), macos.zig (flags from the chain), gui.zig. Not touched: Messages.zig, mouse.zig, detached/*, host_io, tty.
* | | Errors are said in words, and a refusal names what it takesGabriel Schneider4 days
| | | | | | | | | | | | | | | | | | A failure read `Del k|j: InvalidArgument`, `Kill: NoSuchCommand`, `ill-formed control message`, or nothing at all. reportError now spells an error's name as words, and the refusals name their accepted forms: pty/ctl lists its verbs, a flag file takes 1 or 0, a setting word takes on or off, Del takes k, j or nothing, Repl takes - or a language. Kill with nothing to stop says so, /focus says pane, a Look that found nothing says no match, and pty/run on a command pane says it is not a shell. A ctl write's failure has room for the Repl list and is cut between words, the Repl word at a character. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* | | A click written back to event is done as the click, REPL and all; a REPL's ↵Gabriel Schneider4 days
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | ctl line names it Writing an M record back from a .py body with a REPL bound ran the text as a shell command (exit 127), where the click itself went to the REPL. acme does what the click would have done (xfideventwrite, xfid.c:842-844), so a body X record written back now goes the way a middle click goes: to a bound REPL, bracketed or line by line, the several-REPLs question included. An F record, a line written to exec, was never a click and still runs as a command. For a readable list of bindings, the smallest place: a bound terminal's ctl line ends with its id after current/notcurrent. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* | | A 9P request that fills a stillborn scratch's column replaces the scratch ↵Gabriel Schneider4 days
|/ / | | | | | | | | | | | | | | | | | | | | before it is answered A pane that joins a column holding only an empty +New takes the column, but that replacement ran at the end of the editor's next update, not of a 9P request: a look answered 19 while index still listed the +New 18, whose del came later. serveFs, a step of its own, now runs it too before answering. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* | A command line runs as its own command pane unless it is clicked at a ↵Gabriel Schneider4 days
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | shell's prompt A middle click, an exec write or a tag word that no builtin knows was typed into some terminal for the pane's directory, sharing whatever state that shell was in and answering nothing, so a misspelling vanished into a shell. Now only a line clicked at an interactive terminal's prompt is typed there. From anywhere else it runs as a command pane: a terminal whose child is $SHELL -c the line in the pane's directory, full emulation, which shows its output and then exit N from the host's reaping of the child, and stays. A finished command pane is the next command's for its directory, which runs below what it showed after a '% line' line (acme appends to +Errors and never clears it, util.c:213); a running one gets a second pane. Kill ends a command pane's whole process group, the log records run and exit, exec reads back the command pane's serial, and a line is at most 1 KB, read off the pane as the host forks rather than carried in every spawn effect. ttyForDir's search for a free shell is gone. The goldens of chordcut, cmdword and layout-open change where a file's exec now opens a command pane, and ttytaken is rewritten to exec from the terminal itself; docs/open-questions.md records the decision. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* | The root exec is a click at the keyboard's pane, and goes to its event ↵Gabriel Schneider4 days
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | reader too A line written to the root's look or exec is a click at the pane with the keyboard, and in acme every click on a window whose event file is open goes to its reader; the root's acted at once. It now goes to the reader as the pane's own does. The docs say what that means for a helper holding event (its own exec comes back as a record: run it through ctl, or write the record back), and why an event record counts bytes where acme counts runes: every offset pardes serves is in bytes, #n and q0/q1 too, so the count follows them rather than switch alone, and an acme library reads it right for ASCII text. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* | Joincol with no column to the right and Theme with no such theme say soGabriel Schneider4 days
| | | | | | | | | | | | | | | | | | | | | | Both did nothing without a word, from a click or a ctl write alike, and a script could not tell a no-op from success. Joincol in the rightmost column now fails 'Joincol: no column to the right'. A Theme name that is none says so and names the themes sharing its first letter, since all of them (ThemeSel lists them) are too many for a message or a refused write; a startup config line still fails quietly, as its other bad lines do. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* | docs: through a mount a malformed write is EINVAL and one that fails is EIO, ↵Gabriel Schneider4 days
| | | | | | | | | | | | | | | | | | | | | | | | | | | | and the error words keep it so The served README said every refused write reads as EINVAL, but a mount's errno is 9ns's reading of the error's words, so a no-match or out-of-range address and a refused Exit came back EIO, as the dogfood run saw. That split is the useful one, malformed against failed, so the docs now state it rather than the words being bent to EINVAL; a test pins each error's words to its side of it. It caught one: 'regular expression search took too long' read as ENAMETOOLONG, and now says it gave up past its step budget. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* | The root look and exec read back what a ctl write touched tooGabriel Schneider4 days
| | | | | | | | | | | | | | | | | | After a pane made by Tty or Newcol written to a ctl, /look and /exec still read the serials of the last look or exec, and a script took the old pane for the new one. A ctl write now resets them and records what each line made, or else the pane it ran at, as a look or exec does. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* | A line written to a pane's own look or exec goes to the event reader holding ↵Gabriel Schneider4 days
|/ | | | | | | | | | | | | | the pane A script writing to pane/N/exec bypassed the client holding that pane's event file, which a middle click on it would not: acme sends a window's clicks to its event reader (look.c:53, exec.c:173). Such a line is now an F record at 0 0 carrying its text; the root's look and exec still act at once. acme takes back only origin, action and range, which a record with no place in the text cannot use, so the whole record as read is taken too, and for an empty range acts on its text. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* A terminal's new directory is a rename in the log, and its ctl counts its bodyGabriel Schneider4 days
| | | | | | | | | | The log said new N / and later del N <cwd> for a terminal, with no rename in between, though a terminal is named by its directory. setCwd now logs the rename once the pane has been announced. A terminal's ctl line gave body length 0 while its body reads its history; it now counts that history (without keeping a copy). Co-Authored-By: Claude Opus 5.5 <[email protected]>
* A lock another open holds fails at once with file in use instead of parkingGabriel Schneider4 days
| | | | | | | | | | | A contended lock parked until the holder unlocked, but through a kernel or FUSE mount the kernel serialises writes to one file, so the parked lock held up the holder's own unlock and close on that ctl, and the two deadlocked. acme's qlock blocks; here the second lock is refused at once with file in use (EBUSY) and the client retries, and nothing parks on the lock any more. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Focus gives the keyboard only, reads empty while a header has it, and sits ↵Gabriel Schneider4 days
| | | | | | | | | | | | | in the root listing's natural place A write to /focus leaves a folded pane folded, as rio keeps current apart from unhide; while a column or workspace tag has the keyboard no pane does, so /focus reads empty and every pane's ctl says notcurrent (an empty read also no longer answers stale staged bytes). focus, ctl and commands now list after status, and the discovery test checks the root as a set rather than by position. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* A ctl write fails when a builtin it runs fails, and a missing required ↵Gabriel Schneider4 days
| | | | | | | | | | | | | | | | argument is refused before anything runs A ctl write failed only on a malformed line: Mount x reported its error in the editor while the write succeeded, and a bare Mount failed only as it ran, after earlier lines of the write. acme's ctl answers a command's error (editors/acme/xfid.c:700). Builtins now declare requires_arg beside takes_arg (settings: those with a value to set), and the check refuses a bare one as wrong #args before any line runs; while a ctl runs, the first error a builtin reports fails the write, quoted with its line, and the prompt refusal quotes its line too. Docs say what a failure mid-write leaves done. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Inline the one-line helpers in src/ninep at their call sitesGabriel Schneider4 days
| | | | | | | | | | | | reads, paneFileNamed, topFileNamed, serialNamed, attrReply, makePane, events.pending, mtimeOf, versionOf, dirOf, cellOf, shiftBy, flagOf, stageIndexLine, ctlLen, listenersLen, activeSerial, fontName and Serials.has each wrapped a line or two used once or twice; the logic now reads where it is used. Helpers that do several things or are shared widely (bodyOf, fileOf, dirtyOf, nameOf, kindOf, clip, readRange, readFlag, pty's answer and waitingRun, nextSerialAfter) stay. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* A root commands file lists every builtin, its argument and which ctl takes itGabriel Schneider4 days
| | | | | | | | | A script could learn the builtin words only from source or the Help window. /commands is generated from the registry: one line per builtin, Word or Word arg, then root or pane for the ctl that takes it, so it is always this build's own list. Co-Authored-By: Claude Opus 5.5 <[email protected]>