summaryrefslogtreecommitdiff
path: root/src/ninep/ctl.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/ninep/ctl.zig')
-rw-r--r--src/ninep/ctl.zig20
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");