diff options
| author | Gabriel Schneider <[email protected]> | 2026-09-29 04:52:38 -0300 |
|---|---|---|
| committer | Gabriel Schneider <[email protected]> | 2026-10-01 00:12:16 -0300 |
| commit | 430d482c16101ce85b5c0f80f6bdd882c09a3272 (patch) | |
| tree | 10dad6a09f8fd8e0784dc83058c10103c35fba25 /src/ninep | |
| parent | 4e82c95653e1e8e03fde91e3cea2de04b3fabbc8 (diff) | |
| download | pardes-430d482c16101ce85b5c0f80f6bdd882c09a3272.tar.gz pardes-430d482c16101ce85b5c0f80f6bdd882c09a3272.zip | |
Refusals and records say more: get quotes its line, a bare answer lists the choices, a clean reload is logged
get's refusal now quotes the line as a builtin's (Save's) does; a bare
answer while a question stands says what it takes (answer takes k j or
-); and a clean buffer reloaded from disk logs changed <serial> reloaded,
as the kept dirty case logs changed <serial>. (A failed Save already says
why: Save <path>: <the error in words>.)
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Diffstat (limited to 'src/ninep')
| -rw-r--r-- | src/ninep/ctl.zig | 20 |
1 files changed, 18 insertions, 2 deletions
diff --git a/src/ninep/ctl.zig b/src/ninep/ctl.zig index f40825e3..eb8ed292 100644 --- a/src/ninep/ctl.zig +++ b/src/ninep/ctl.zig @@ -648,7 +648,15 @@ pub fn writePane(p: *Pardes, req: Req, pane: *Pane) Reply { if (apply and p.paneBySerial(serial) == null) return Reply.fail(req.tag, E.NOENT); if (std.mem.eql(u8, line, "get")) { if (!apply) continue; - if (getRefused(p, pane)) |said| return tree.failText(req.tag, E.IO, said); + // Quoting the line, as a builtin's refusal (Save's) does. + if (getRefused(p, pane)) |said_in_ename| { + // refuse writes ename, where the words are: copy them out. + var said_buf: [320]u8 = undefined; + const said = said_buf[0..said_in_ename.len]; + @memcpy(said, said_in_ename); + const r = refuse(p, req, said, line); + return .{ .tag = req.tag, .status = .err, .errno = E.IO, .ename = r.ename }; + } const errno = get(p, pane); if (errno != 0) return Reply.fail(req.tag, errno); } else if (std.mem.eql(u8, line, "lock")) { @@ -661,6 +669,12 @@ pub fn writePane(p: *Pardes, req: Req, pane: *Pane) Reply { held = false; if (apply) pane.fs.lock = null; } else if (std.mem.eql(u8, line, "answer")) { + // With a question up, what it offers. + var offered: [64]u8 = undefined; + if (p.questionChoices(p.paneBySerial(serial).?, &offered)) |choices| { + var why: [96]u8 = undefined; + return tree.failText(req.tag, E.INVAL, std.fmt.bufPrint(&p.fs.ename, "answer takes {s} or -", .{choices}) catch std.fmt.bufPrint(&why, "answer takes a choice or -", .{}) catch "answer takes a choice or -"); + } return tree.failText(req.tag, E.INVAL, "answer takes a choice or -"); } else if (std.mem.startsWith(u8, line, "answer ")) { // The pane's question (its `ask` in the log), answered. @@ -1280,7 +1294,7 @@ test "get reloads the pane from disk and reports a missing file without losing d // Unsaved text is asked about once, as acme's get asks winclean. const asked = wr(p, ctl_node, "get\n"); try testing.expectEqual(E.IO, asked.errno()); - try testing.expect(std.mem.endsWith(u8, asked.reply.ename, ": Modified (get again to discard)")); + try testing.expect(std.mem.endsWith(u8, asked.reply.ename, ": Modified (get again to discard) \"get\"")); try testing.expectEqual(E.NOENT, wr(p, ctl_node, "get\n").errno()); try testing.expect(p.paneBySerial(serial) != null); try testing.expectEqualStrings("from disk\nunsaved\n", pane.file.?.content); @@ -1571,6 +1585,8 @@ test "a file changed on disk under unsaved edits is not reloaded: it says so, ge // Clean, it takes the new text. pardes.panes.File.changed(p, 0, "two\n"); try testing.expectEqualStrings("two\n", f.content); + var reloaded: [32]u8 = undefined; + try testing.expect(th.logHas(p, try std.fmt.bufPrint(&reloaded, "changed {d} reloaded\n", .{serial}))); // Edited, it keeps its text and stays dirty. _ = wr(p, Node.of(serial, .body), "mine\n"); pardes.panes.File.changed(p, 0, "three\n"); |
