From 406f483288c7689bdd2e1f3f68b276c61ca9412a Mon Sep 17 00:00:00 2001 From: Gabriel Schneider Date: Thu, 1 Oct 2026 20:50:48 -0300 Subject: An Edit's held write: < | > commands no longer block their 9P connection (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 --- src/pardes.zig | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) (limited to 'src/pardes.zig') diff --git a/src/pardes.zig b/src/pardes.zig index cf3d5128..e92f9623 100644 --- a/src/pardes.zig +++ b/src/pardes.zig @@ -123,9 +123,6 @@ pub const Turn = struct { /// Bumped each time a language server's answer (or its lack) is taken /// in (`lspResponse`): a write that asked one waits for this. lsp_answers: u64 = 0, - /// Bumped each time an Edit's commands (`< | >`) have answered and the - /// Edit is done, or failed (edit_cmd.zig): a write that ran one waits. - edit_answers: u64 = 0, /// All of the above, and `out` reaching zero. settled: std.Io.Condition = .init, @@ -223,15 +220,6 @@ pub const Turn = struct { while (t.lsp_answers == answers) t.settled.wait(t.io.?, &t.mutex) catch return; } - pub fn editAnswered(t: *Turn) void { - t.edit_answers +%= 1; - const io = t.io orelse return; - t.settled.broadcast(io); - } - - pub fn awaitEdit(t: *Turn, answers: u64) void { - while (t.edit_answers == answers) t.settled.wait(t.io.?, &t.mutex) catch return; - } pub fn awaitRestored(t: *Turn, restores: u64) void { while (t.restores == restores) t.settled.wait(t.io.?, &t.mutex) catch return; @@ -5918,6 +5906,12 @@ pub const Pardes = struct { /// that changes a pane costs a frame, which is why a round trip on a /// local socket costs microseconds and not a vsync. pub fn serveFs(p: *Pardes, req: ctlfs.Req) ctlfs.Reply { + // The held write of an Edit whose commands run, asked again by a + // retry of its park: still waiting, or its answer, never run twice. + if (p.fs.edit_hold) |*h| if (h.names(req)) { + if (!h.done) return .{ .tag = req.tag, .status = .again }; + return filesystem.EditHold.answer(&p.fs); + }; defer panes.File.syncTwins(p); if (!ctlfs.changesPane(p, req)) return ctlfs.handle(p, req); // An address, a limit or the mark flag is nothing drawn: a script's @@ -5928,7 +5922,7 @@ pub const Pardes = struct { look.cancelLookHover(p); p.fs.serving = true; p.fs.lsp_answer_at = null; - p.fs.edit_answer_at = null; + p.fs.edit_started = false; const reply = ctlfs.handle(p, req); p.fs.serving = false; // The one-failure rule is a write's: a refused open (its OTRUNC's -- cgit v1.3