summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.agents/skills/pardes-9p/SKILL.md3
-rw-r--r--docs/fs.md4
-rw-r--r--src/builtins.zig5
-rw-r--r--src/ninep/ctl.zig6
4 files changed, 16 insertions, 2 deletions
diff --git a/.agents/skills/pardes-9p/SKILL.md b/.agents/skills/pardes-9p/SKILL.md
index feb4f703..5e79a470 100644
--- a/.agents/skills/pardes-9p/SKILL.md
+++ b/.agents/skills/pardes-9p/SKILL.md
@@ -257,7 +257,8 @@ the address comes back to where it began, or set `limit`.
a reserved zero, the dirty flag, the width in cells, the font and the tab
width, then `current` or `notcurrent` — and takes `get` (reload from disk),
`lock`/`unlock`, and any builtin that acts on a pane (`Del`, `Save f`,
-`Collapse`). A `lock` another open holds fails at once with `file in use`
+`Collapse`, `Undo`/`Redo`: 256 steps; with none left they say so, and the
+write succeeds). A `lock` another open holds fails at once with `file in use`
(EBUSY): retry it. Session builtins and settings go to the root `ctl`, which reads
back every setting in the syntax it takes. A ctl write is checked whole
first and refused as `unknown control message "X"` (EINVAL) and the like,
diff --git a/docs/fs.md b/docs/fs.md
index fc5a8586..d2ab3919 100644
--- a/docs/fs.md
+++ b/docs/fs.md
@@ -197,7 +197,9 @@ back changes nothing; a setting the frontend cannot show (`Lift`,
Config window's, not settings. A pane's `ctl` takes the builtins that act on
a pane (`Del`, or `Del k`/`Del j` to give its rows to the pane above or
below, `Save f`, `Collapse`, which folds that pane, `Undo` and
-`Redo`, which step its body through its edits, `Find pat`)
+`Redo`, which step its body through its last 256 edits -- with none left
+they say `Undo: nothing to undo` and the write still succeeds, as acme's
+Undo is silent --, `Find pat`)
beside acme's `get`, `lock` and `unlock`. The column words are pane words
too, acting on the column that pane is in: `Delcol`, `DelAbove`, `DelBelow`
and the focus moves `Left`/`Right`/`Up`/`Down` from it. `Joincol` and
diff --git a/src/builtins.zig b/src/builtins.zig
index 51771c8f..8c6228c0 100644
--- a/src/builtins.zig
+++ b/src/builtins.zig
@@ -959,14 +959,19 @@ pub const Edit = struct {
/// acme's Undo and Redo (exec.c `undo`): step the pane's body back or
/// forward through its edits, from a tag, a pane ctl or exec.
+/// With no step left, Undo and Redo say so and change nothing; a ctl write
+/// of them still succeeds, as acme's Undo is silent there. A file keeps
+/// limits.undo_max steps (256).
pub const Undo = struct {
pub fn run(c: Ctx) void {
+ if (c.pane.file) |f| if (f.history.undo_len == 0) return c.p.setMessage(c.id, "Undo: nothing to undo");
edit.doUndo(c.p, &c.pane.body);
}
};
pub const Redo = struct {
pub fn run(c: Ctx) void {
+ if (c.pane.file) |f| if (f.history.redo_len == 0) return c.p.setMessage(c.id, "Redo: nothing to redo");
edit.doRedo(c.p, &c.pane.body);
}
};
diff --git a/src/ninep/ctl.zig b/src/ninep/ctl.zig
index 0f22614c..d6922390 100644
--- a/src/ninep/ctl.zig
+++ b/src/ninep/ctl.zig
@@ -724,6 +724,12 @@ test "Undo and Redo on a pane's ctl step its body through its edits" {
try testing.expectEqualStrings("one\n", rd(p, body, 0, 64).bytes);
try testing.expectEqual(Status.ok, wr(p, Node.of(serial, .ctl), "Redo").reply.status);
try testing.expectEqualStrings("one\ntwo\n", rd(p, body, 0, 64).bytes);
+ // Nothing left: said, and the write still succeeds, as acme's is silent.
+ try testing.expectEqual(Status.ok, wr(p, Node.of(serial, .ctl), "Redo").reply.status);
+ try testing.expect(th.logHas(p, "Redo: nothing to redo"));
+ _ = wr(p, Node.of(serial, .ctl), "Undo");
+ try testing.expectEqual(Status.ok, wr(p, Node.of(serial, .ctl), "Undo").reply.status);
+ try testing.expect(th.logHas(p, "Undo: nothing to undo"));
}
test "focus reads the pane with the keyboard, and a serial written to it moves the keyboard there" {