| Commit message (Collapse) | Author | Age |
| |
|
|
|
|
| |
rename that ends it, and a step its generation, so typing allocates a snapshot and nothing more (follows prwqwwxt); a rename of one Zerox twin is logged for each twin
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
| |
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]>
|
| |
|
|
|
|
|
|
| |
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]>
|
| |
|
|
|
|
| |
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]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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]>
|
| |
|
|
|
|
|
|
|
|
|
| |
refused EINVAL, in words a mount maps so: `invalid rename: ...` and the data write's own refusal
`rename not allowed: ...` went out EPERM, and `Edit ,d` on a PDF ran
and failed late, EIO, while a data write there was EINVAL. The rename
refusal now says `invalid rename` with EINVAL, and Edit on a pane with
no text is refused before anything runs with the data write's words.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
|
| |
this pane has no text to address`, which a mount reads as EINVAL, not EIO
9ns maps a refusal back to its errno by its words; "this pane has no
text to address" held none it knows. The reference quotes the new words.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
| |
the pane has no text "(a terminal, ...)"
A terminal's body takes writes (its keys), so the old words named the
one kind that does. data, sel and dirty keep "this pane has no text",
which is true of all three.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
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]>
|
| |
|
|
|
|
|
|
|
|
| |
terminal by kind no longer picks a pane with no shell
A command pane runs one line and takes no typing; a script choosing
`$2=="term"` to type into got one. Its kind is now cmd; a shell's stays
term.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
| |
are refused alike: "this pane has no text to address"
A terminal took an addr write and evaluated it over nothing, saying
"bad address syntax" or "address out of range" by the expression, while
dot refused it as no text at all. A range file of a pane with no text
now refuses every write the same way, before the expression is read.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
| |
cat sel reads it back; one open's writes run on from the last
The selection collapsed to a point after the write, so sel read back
nothing. What is written is now dot, and the next write of the same
open goes at its end and grows it (acme's wrselrange), so a shell's
several writes make one selection; another open's write replaces it.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
| |
not UTF-8 included, so what name reads writes back as it was
A pane opened on a file whose name held a tab, a control byte or bytes
not UTF-8 read that name from its name file, and the same bytes written
back were refused. Only what no file name holds is refused now: a second
line and a NUL. The ctl word name still refuses a second blank after the
word, as a line's words are split at blanks.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
| |
layout, recent and listeners; fs.md says which files have real lengths
A stat of index, layout, recent or listeners built the whole view to
count it, and data and xdata reported the body's length though a read
answers what addr selects. Those now stat 0, as screen and pane/new
already did, and fs.md lists the files whose length is real and says to
read the rest to the end.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
| |
The truncation of an empty body is no edit and pushes no step, but it
still marked the open's writes as joining the step it would have
pushed, so the text written after it had no undo step at all. A
truncation that changed nothing (of body, data or xdata) now leaves the
step to the write that follows.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
| |
as acme's tag clicks do, not run past it
A real click in a held pane's tag was already told to the reader, but
the same click written to the pane's tagexec ran at once, so a script
holding the pane could not intercept it. The line is now an x record
(l for a look), done when the reader writes it back. A column's or the
workspace's tag is still no pane's and runs as before.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
| |
what it holds, makes no undo step
A shell's : > data on an empty address, echo abc > data over abc, or
Edit s/d/d/ each pushed an undo step and a new revision, so Undo spent
a press on nothing and the pane read as edited. The splice of the 9P
writes and the Edit builtin now see the text is unchanged and stop.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
| |
truncation waits for the write, as limit's does
echo /nomatch/ > dot truncated dot to an empty range at the top before
the write was refused, so a failed address still moved the selection
and scrolled. The truncation is now held until the write that follows
it: that write sets dot, or, refused, leaves it as it was. A truncation
with no write after it (: > dot) empties it when its open goes.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
| |
only fail
`name ~`, `name /` or `name foo/` renamed the pane to a directory, and
only its Save failed later. A name ending in `/`, the root, or one naming
a directory that is there is now refused at once, with words a mount
reads as EISDIR (`name: <path> is a directory, not a file`). The ctl word
name and a forwarded `pardes ~` go through the same check. fs.md says so.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
| |
address form is, not clamped
`#5,#2` and `#2,#99` were refused (addresses out of order, address out of
range), but the pair form `5 2` became 5..5 and `2 99` became 2..end,
silently a different range from the one asked for. A pair is now checked
the same way: past the text is out of range, and an end before its start
is out of order. fs.md says so.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
| |
4096 bytes fits
`echo <4096 bytes> > tag` wrote 4097 bytes and was refused "over 4096
bytes", although a rewrite drops that one trailing newline and would have
held exactly 4096. The limit now counts a truncating write's text without
the newline it drops, for a pane's, a column's and the workspace's tag. An
append still counts its newline, which it keeps.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
never to the end of the write
writeData, flushBatch and writeBody showed what they wrote with
showOffset, which put the cursor at the write's end. The cursor is dot's
head, so a data write or a body append moved dot there, and a `sel` write
after it replaced the wrong text. showOffset now scrolls the view to the
offset and leaves the cursor, pinned, where it was. Dot shifts only by
the rule it already followed, acme's: an insert before dot shifts it, one
at its start or inside it grows it, one at its end or after it leaves it.
The test covers each case, then a body append followed by a sel write.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
that takes one, through one helper
Only DumpDir (dump.zig) and ShaderBuild expanded `~/`, each its own way.
So a look at `~/notes.txt`, `name ~/x`, `Save ~/x`, ThemeFile, Restore and
a quoted `pardes '~/x'` all took `~` as a directory of that name under the
pane's. There is now one rule, filesystem.expandHome. A leading `~`,
alone or before `/` or `:`, is $HOME, else the passwd entry's home;
`~user` is that user's (getpwnam). As in a shell, it applies even beside a
file named `~`, and `./~` names that file. Every entry point runs its
typed path through it:
- look, B3 and 9P, before any parsing, so `~/x:12`, `~/x:12:3` and
`~/x:/re/` all work;
- name, and a tag's rename;
- Save <path>;
- ThemeFile, DumpDir, Restore and ShaderBuild's shader files;
- the forwarding launch.
Recent rows are not shown with `~` and need nothing. How names are shown
is unchanged.
Tests: expandHome's cases, and HOME unset (passwd), with HOME passed in
rather than set, since setenv moves the environ a spawned child reads.
fs.py covers Save into missing directories under `~`, `name ~/x`, a look
at `~/x:3`, and a forwarded `pardes '~/x'`.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
| |
err record says tag: once
The refusal's text began with "tag: ", and the log's err record puts the
file's name before the reason. So the record read `err - col/1/tag: tag:
no space: over 4096 bytes`. The text is now the reason alone, as the
control-character refusal's is, and the record names the file once.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Save makes the directories
fs.md said FILE must already exist, while `pardes new.txt` in fact
forwarded, making a pane named for it that Save creates. With a missing
directory (`pardes notes/new.txt`) the launch gave up forwarding and started
a nested editor inside the pane. Now the name is made absolute as written
and forwarded the same way. A name written to a pane's name file that goes
into a directory not there has its Save make the directories, as Config's
pane does. A Save <path> into a missing directory still fails ENOENT. The
Forwarding section now says what a new FILE does. fs.py launches one into a
missing directory and saves it.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
over 255 bytes
A Save of a 3000-byte path failed with the record "err 2 ctl: Save…", which
lost the reason. The first cause was reportError, which formatted into 256
bytes, so the operation's path filled the buffer before the reason was
written. The second was the waiting write's late failure, which took the
first 256 bytes of the message row, never its end. Now reportError has room
for the longest path. reportFailure also keeps the words fitted as an err is
(fitErr: the path gives up its middle, the reason stays), and the late
failure of a Save, a Dump, a shell or a ThemeFile takes those words.
fs.md already said a name holds up to 255 bytes a component, but a longer
one was taken and only failed later at Save. Now it is refused when written.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
carries the session directory, not / and a rename
A pane named in the update that made it (Config's init file, a look
renamed on open) logged `rename N <name>` before `new N`, so a follower met
a serial it had never seen. The boot shell, started with no directory, was
announced as `new 1 /` and renamed once its shell spoke. Now noteLog drops
the rename of a pane not yet announced, since its new carries the name, and
announces a pane first for any other record about it. A terminal whose shell
has not said where it is is named by the session's directory, where it was
started, and the shell saying so is no rename.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
| |
`>` write leaves the tag as it was
A column's or the workspace's tag took any length, so a write past 4096 bytes went in and a later Dump failed on it (bad dump tag), and a truncating open wiped any tag before the write after it could be refused. The column and workspace tags now refuse what a pane tag refuses: the 4096-byte limit (ENOSPC, tag: no space: over 4096 bytes) as well as the control characters they already did. A truncation of any of the three is held until the write after it is known to fit, and done with it; a refused write drops it; a close or read with no write after it does it then (so `: > tag` still clears). A test runs a truncating write too long, a control character and a bare truncation at each kind, and Dumps after. docs/fs.md says so.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
| |
whole body: 60 KB appends go from 35.7 to 2.1 ms each
Round 25 measured bulk body writes at about 8 ms a write. There is no frame wait in it: a profile of open, write, clunk in a loop found the flush of each close walking the whole body five times. dotOf, setDot and showOffset turned the cursor between offsets and rows by counting every newline from the top; setContent found the line index's changed span by comparing old and new byte for byte, and hashed the new text to see whether it was back to the saved one. The rows now come from the file's line index by binary search (checked against the counting at every offset), a splice tells setContent the span it changed, and the text is hashed only when its length is the saved text's. Measured over 9P on a Debug build: 60 KB appends 35.7 to 2.1 ms, 8 KB 5.3 to 0.8 ms, 1 KB 1.3 to 0.9 ms. What is left is two copies of the text an edit (the splice's and the undo snapshot's). The perf gate gains body-appends, 64 appends of 8 KB on the 50k-line file, and its three baselines are recorded again.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
| |
namespace's lowercase name
The last of the deferred renames, now that the tty and theme agents have landed: panes.terminal at its importers, the alias lines in Text.zig and File.zig and panes.zig's own uses following. dump.zig's Terminal struct, a dump record, is not this. The served sources list and docs/design.typ name the new file. test/perf.zig's references change, so the three perf baselines take its new harness id with their numbers as recorded. No behaviour changes.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
| |
maps to ENOSPC as the docs say
The tree answers ENOSPC, but through a mount 9ns maps the words, and tag: over 4096 bytes carried none it knows, so a shell saw EIO. The words now hold no space; docs/fs.md says ENOSPC again.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
| |
first step
A 9P write served before a detached host's first pump holds its batch stamped at time 0, so nextWake said to wake at 20 ms while advance, seeing the clock for the first time, set stepped_ns days later and counted due - stepped_ns back past zero: an integer-overflow panic. It was what the 64 KiB msize trial hit in fs-test (restore detached space, the connection closing at the first write's clunk), a race any msize can lose. A batch's wake is now never before the next frame.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
| |
A write to tag longer than the room left was cut and applied in part. It now changes nothing and fails ENOSPC, tag: over 4096 bytes; the docs give the limit.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
| |
is linear
Each body or data write copied and hashed the whole buffer, so a write the mount cut in 8 KB pieces was quadratic: 10 MB took 50 s and a 1 MB insert into 10 MB 11 s, holding the editor's turn. An open's appends to body, or inserts going on at data's address, are now held and put in as one splice (one copy, one undo step, one line-starts pass) before any other request, the close, or the editor's step once the writes pause 20 ms. fs.py-driven: 2 MB 2.19 -> 0.16 s, 10 MB 50.17 -> 0.78 s, 1 MB data into 10 MB 11.49 -> 0.26 s. A body-2m case (2 MB in 256 KB writes on one open) joins the perf gate: 84023 -> 15785 us; baselines re-recorded.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
| |
it needs more
A last line with no newline was held to the close, so printf bogus > ctl answered 0 and failed only in the log, Edit ,s/zzz/y/ too. A write shorter than its Twrite is the whole of what was written (acme takes each write whole): its tail runs then and a failure is the write's. It is held only when the parser says it needs more -- an open { block, an a/c/i text -- or when the write filled its Twrite and may go on (the listener tells the core the room, msize less its header).
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
| |
is a real refusal or says why it cannot fire
A sweep for round 23's crash: a run's answer (pty/run) was bufPrint'd into 48 bytes with catch unreachable, so a foreground program's long name (macOS gives up to 32 bytes) panicked; it now cuts at the room, keeping its newline, in 96 bytes. The rest were numbers into buffers sized for them, a braille codepoint, pthread calls on the queue's own mutex, and pdf_view's resolved outline entries: each now carries a one-line comment saying why it cannot fire.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
| |
Both ends said a blank at its end.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
| |
open
bash writes printf 'a\nb\n' a line at a time, so each line arrived as a whole name on the held open and renamed the pane twice. An open that has named its pane now refuses a further line, as a two-line write already was.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
| |
A file deleted under an open buffer left dirty 0 and let Del, Exit and the rest throw the only copy of its text away unasked. It now counts as dirty, as acme's does, and the refusals ask about it.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
| |
addr kept the old address under a failed one, and an address written relative to it went from that old one. Such an address now fails with no address: the last one written to addr failed, until one that stands alone is written.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
| |
The body of a PDF pane read as empty. It now reads MuPDF's text extraction of the page shown, the text search and n/N already use, read-only (a write is refused, as round 22's body refusal made it).
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
| |
The join mark a write left was the pane's, so another open's write joined the first open's step. Writing opens of body, data and xdata now get an open record, the mark names the open that set it, and another open's write starts its own step (the pane's one history: each turn the opens take is a step).
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
| |
Each write to name was taken as a whole name, so a name a client wrote in two pieces renamed the pane twice, the first time to half a name. name's writes are now held per open, as exec's and ctl's lines are, until the newline or the close.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
| |
room fails, and so does a write to an image's or PDF's body
Callers or Callees with nothing found, Hover or Lspwhy with no room for its pane, and a question asked of no file's pane said nothing, the 9P write succeeding; a body write to an image or PDF pane went nowhere. A write that asks a language server now waits for its answer (turn.lsp_answers), and what fails there -- nothing found, no answer, a backend's @none why, a placement with no room (ENOSPC) -- fails the write and logs its err. No diagnostics is said, not failed.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
| |
A renamed scratch never saved and a /virtual/ pane were recorded as recent files, and at 200 the oldest entry went even when that file was open. Opens, renames and closes now record a path only when it is a file on this host, and the cap drops the oldest closed entry. A name with a newline is not written to the kept list, where it would read back as two.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
| |
bash line-buffers its stdout, so printf 'x\ny\nz\n' > data arrives as three writes and took three Undos. A write now leaves the join mark a truncation already left, so the next write on the file joins its step until the open is released; a truncation and any other edit start a step of their own.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
closed file reopens it
A file closed by accident, its path forgotten, could not be found again:
the jumplist dropped closed panes. Every file opened (a look, a Save of a
scratch, a Restore, a rename) goes first in a list of 200, kept once, its
dot noted when it closes, kept across sessions in $XDG_STATE_HOME/pardes/
recent. `Recent` (SPC f r) shows it in a reused +Recent, each row
`path:line:col open|closed` a look reopens; /recent reads `open|closed
<path>`. The jumplist keeps a closed file's entries, +Jumps marks them
`(closed)`, and Back to one opens the file at its place. acme has no
such thing; its dump and Load are the nearest.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
| |
says so
A NUL written into a tag went into the dump, which the host then could
not write, and Dump said nothing: a success that wrote nothing. Tag
writes, the workspace's, a column's and a pane's, refuse control
characters but tab and newline, DEL, C1 and bytes not UTF-8, EINVAL; and
Dump reports any failure of its own instead of swallowing it.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|