summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-09-28 01:09:59 -0300
committerGabriel Schneider <[email protected]>2026-10-01 00:12:14 -0300
commit590e98bc3a198b86aaeca2168c4ac65d5cd777d0 (patch)
tree0aed512448245b453cfe5d7acd2d3ce5ec8e57a8
parentbb380c6b44b649a2e9192311478ee52d69c702dc (diff)
downloadpardes-590e98bc3a198b86aaeca2168c4ac65d5cd777d0.tar.gz
pardes-590e98bc3a198b86aaeca2168c4ac65d5cd777d0.zip
Let the tag's undo bring back what a 9P truncate cleared
Truncating the tag file replaced its text without an undo point, so the cleared text was gone for good. It is recorded now like a typed edit, the history is kept, and docs/fs.md says so. Co-Authored-By: Claude Opus 5.5 <[email protected]>
-rw-r--r--docs/fs.md4
-rw-r--r--src/ninep/pane.zig7
2 files changed, 10 insertions, 1 deletions
diff --git a/docs/fs.md b/docs/fs.md
index c43034f6..589f4287 100644
--- a/docs/fs.md
+++ b/docs/fs.md
@@ -185,7 +185,9 @@ pane.
`tag` reads the whole tag as the pane shows it: the computed path, dirty
marker or PDF page, then the text you may edit. A write appends to that text,
newlines included, and a tag with more than one line takes a row per line on
-screen; truncating `tag` clears it, as acme's `cleartag` does.
+screen; truncating `tag` clears it, as acme's `cleartag` does. The clearing
+is an edit of the tag like a typed one and its undo history is kept: `u` in
+the tag brings back the text it cleared.
Stats report real lengths for `index`, `status`, `look`, `exec`, `listeners`,
`name`, `body`, `tag`, `sel`, `ctl`, the range files and the flag files, and
diff --git a/src/ninep/pane.zig b/src/ninep/pane.zig
index 245e0bb4..80dd97cd 100644
--- a/src/ninep/pane.zig
+++ b/src/ninep/pane.zig
@@ -609,6 +609,8 @@ pub fn truncate(p: *Pardes, pane: *Pane, file: PaneFile) tree.Status {
},
.tag => {
const empty = p.gpa.alloc(u8, 0) catch return .err;
+ // An edit like a keyboard one: `u` in the tag brings it back.
+ pane.tag.remember(p.gpa, if (pane.tag.own) |own| .{ .text = own } else null);
if (pane.tag.own) |own| p.gpa.free(own);
pane.tag.own = empty;
pane.tag.cur_row = 0;
@@ -893,6 +895,11 @@ test "truncating the tag clears its editable tail" {
try testing.expectEqual(Status.ok, cleared.reply.status);
try testing.expectEqualStrings("", pane.tag.own.?);
try testing.expect(std.mem.indexOf(u8, rd(p, tag, 0, 4096).bytes, " Mine") == null);
+ // The tag keeps its undo: undoing in it brings back what was cleared.
+ pardes.edit.doUndo(p, &pane.tag);
+ try testing.expect(std.mem.endsWith(u8, tagline.curTail(pane), " Mine"));
+ _ = call(p, .{ .tag = 2, .op = .setattr, .node = tag, .truncate = true });
+ try testing.expectEqualStrings("", pane.tag.own.?);
// Written back without a leading space, the text still stands apart
// from the path: the computed prefix brings the separator, so Look and