diff options
| author | Gabriel Schneider <[email protected]> | 2026-09-29 02:17:14 -0300 |
|---|---|---|
| committer | Gabriel Schneider <[email protected]> | 2026-10-01 00:12:15 -0300 |
| commit | 964709e115126aafa6fd5d8c984d511cf68cecaf (patch) | |
| tree | a4367627d3c912116bc59b2c0577cb116ebc2c9c | |
| parent | 9fa0969549108bcdf05201e846226470e278a798 (diff) | |
| download | pardes-964709e115126aafa6fd5d8c984d511cf68cecaf.tar.gz pardes-964709e115126aafa6fd5d8c984d511cf68cecaf.zip | |
Undo and Redo with nothing left say so, and the write succeeds
A pane's Undo or Redo with no step left did nothing and said nothing. It
now says "Undo: nothing to undo" (or Redo's) as a message, not a failure,
so a ctl write of it still succeeds as acme's silent Undo does. The docs
give the 256-step history.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
| -rw-r--r-- | .agents/skills/pardes-9p/SKILL.md | 3 | ||||
| -rw-r--r-- | docs/fs.md | 4 | ||||
| -rw-r--r-- | src/builtins.zig | 5 | ||||
| -rw-r--r-- | src/ninep/ctl.zig | 6 |
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, @@ -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" { |
