summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/fs.md3
-rw-r--r--docs/tags.md4
-rw-r--r--src/builtins.zig14
-rw-r--r--src/config.zig2
-rw-r--r--src/ninep/ctl.zig15
-rw-r--r--test/snapshots/builtins.snap2
6 files changed, 38 insertions, 2 deletions
diff --git a/docs/fs.md b/docs/fs.md
index 445aa725..95c1871e 100644
--- a/docs/fs.md
+++ b/docs/fs.md
@@ -144,7 +144,8 @@ takes (`Verbose on`, `WindowOpacity 70`, `PanelSlide off`, `DumpDir` bare
for the default directory, `LocationsConfig ...`), so writing what it reads
back changes nothing; platform and startup facts are `/status`'s and the
Config window's, not settings. A pane's `ctl` takes the builtins that act on
-a pane (`Del`, `Save f`, `Collapse`, which folds that pane, `Find pat`)
+a pane (`Del`, `Save f`, `Collapse`, which folds that pane, `Undo` and
+`Redo`, which step its body through its edits, `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/docs/tags.md b/docs/tags.md
index f1e4a420..de540c91 100644
--- a/docs/tags.md
+++ b/docs/tags.md
@@ -43,6 +43,10 @@ Its text and terminal process are kept;
the command stays available in the visible tag. Every default pane tag includes
`Collapse`, including file, terminal, image, and PDF panes.
+`Undo` and `Redo` are acme's: typed or clicked in a pane's tag, or written
+to its `ctl`, they step the body back and forward through its edits, as the
+`u` and `U` keys do. They are not in the default tags.
+
`Del` closes a pane and gives its rows to one neighbor; the rest of the
column keeps its heights. `Del k` (or `DelAbove`) gives them to the nearest
expanded pane above, `Del j` (or `DelBelow`) to the one below, each falling
diff --git a/src/builtins.zig b/src/builtins.zig
index 23d853c8..a755969b 100644
--- a/src/builtins.zig
+++ b/src/builtins.zig
@@ -850,6 +850,20 @@ pub const Togglettymode = 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.
+pub const Undo = struct {
+ pub fn run(c: Ctx) void {
+ edit.doUndo(c.p, &c.pane.body);
+ }
+};
+
+pub const Redo = struct {
+ pub fn run(c: Ctx) void {
+ edit.doRedo(c.p, &c.pane.body);
+ }
+};
+
/// Fold a pane to its tag, or restore its share of the column.
pub const Collapse = struct {
pub fn run(c: Ctx) void {
diff --git a/src/config.zig b/src/config.zig
index 186b29a1..416754a6 100644
--- a/src/config.zig
+++ b/src/config.zig
@@ -49,6 +49,8 @@ pub const leader_path = paths: {
.Mode = null,
.Togglettymode = null,
.Collapse = null,
+ .Undo = null,
+ .Redo = null,
.Repl = null,
.Kill = null,
.Exit = null,
diff --git a/src/ninep/ctl.zig b/src/ninep/ctl.zig
index a64521e7..e4e983a8 100644
--- a/src/ninep/ctl.zig
+++ b/src/ninep/ctl.zig
@@ -542,10 +542,23 @@ test "commands lists every builtin with its argument and the ctl that takes it"
try testing.expect(words.next() == null);
}
try testing.expectEqual(std.enums.values(Builtin).len, lines);
- for ([_][]const u8{ "\nDel arg pane\n", "\nNewcol root\n", "\nSave arg pane\n", "\nVerbose arg root\n" }) |row|
+ for ([_][]const u8{ "\nDel arg pane\n", "\nNewcol root\n", "\nSave arg pane\n", "\nVerbose arg root\n", "\nUndo pane\n", "\nRedo pane\n" }) |row|
try testing.expect(std.mem.indexOf(u8, listed.bytes, row) != null);
}
+test "Undo and Redo on a pane's ctl step its body through its edits" {
+ const p = try withFile(testing.allocator, "one\n");
+ defer p.deinit();
+ const serial = serialOf(p);
+ const body = Node.of(serial, .body);
+ try testing.expectEqual(Status.ok, wr(p, body, "two\n").reply.status);
+ try testing.expectEqualStrings("one\ntwo\n", rd(p, body, 0, 64).bytes);
+ try testing.expectEqual(Status.ok, wr(p, Node.of(serial, .ctl), "Undo").reply.status);
+ 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);
+}
+
test "focus reads the pane with the keyboard, and a serial written to it moves the keyboard there" {
const p = try withFile(testing.allocator, "x\n");
defer p.deinit();
diff --git a/test/snapshots/builtins.snap b/test/snapshots/builtins.snap
index 84de680f..c9bbd2a1 100644
--- a/test/snapshots/builtins.snap
+++ b/test/snapshots/builtins.snap
@@ -27,6 +27,8 @@ wheel up 110 50
wheel up 110 50
wheel up 110 50
wheel up 110 50
+wheel up 110 50
+wheel up 110 50
wait 10000 Look enter, right-click
wait 10000 Exec tab, middle-click
wait 10000 Filter