summaryrefslogtreecommitdiff
path: root/src/ninep
diff options
context:
space:
mode:
Diffstat (limited to 'src/ninep')
-rw-r--r--src/ninep/pane.zig23
1 files changed, 21 insertions, 2 deletions
diff --git a/src/ninep/pane.zig b/src/ninep/pane.zig
index d276b771..14877f0f 100644
--- a/src/ninep/pane.zig
+++ b/src/ninep/pane.zig
@@ -304,6 +304,21 @@ pub fn spliceBody(p: *Pardes, pane: *Pane, q0: usize, q1: usize, bytes: []const
return take;
}
+test "a shell's > into an empty pane's body is one undo step, as into any other" {
+ const p = try withFile(testing.allocator, "");
+ defer p.deinit();
+ const pane = p.panes[0].?;
+ const f = &pane.file.?;
+ const body = Node.of(pane.serial, .body);
+ const steps = f.history.undo_len;
+ const h = call(p, .{ .tag = 1, .op = .open, .node = body, .omode = 1 }).reply.handle;
+ _ = call(p, .{ .tag = 2, .op = .setattr, .node = body, .truncate = true });
+ try testing.expectEqual(tree.Status.ok, call(p, .{ .tag = 3, .op = .write, .node = body, .handle = h, .data = "fresh\n" }).reply.status);
+ _ = call(p, .{ .tag = 4, .op = .release, .node = body, .handle = h, .opened = true });
+ try testing.expectEqualStrings("fresh\n", f.content);
+ try testing.expectEqual(steps + 1, f.history.undo_len);
+}
+
test "a write that changes nothing, an empty range deleted or a range replaced by itself, makes no undo step" {
const p = try withFile(testing.allocator, "abc\ndef\n");
defer p.deinit();
@@ -1017,8 +1032,11 @@ pub fn truncate(p: *Pardes, pane: *Pane, file: PaneFile) tree.Status {
switch (file) {
.body => if (fileOf(pane) != null) {
pf.joined = null;
+ const was = fileOf(pane).?.revision;
_ = spliceBody(p, pane, 0, bodyOf(pane).len, "") orelse return .err;
- pf.joined = fileOf(pane).?.revision;
+ // An empty body truncated is no edit: the write after it makes
+ // the step, rather than join one that was never pushed.
+ pf.joined = if (fileOf(pane).?.revision != was) fileOf(pane).?.revision else null;
pf.joined_by = 0;
pf.addr = .{};
setDot(pane, .{});
@@ -1029,8 +1047,9 @@ pub fn truncate(p: *Pardes, pane: *Pane, file: PaneFile) tree.Status {
const q1 = @max(q0, pf.addr.q1);
const before = dotOf(pane);
pf.joined = null;
+ const was = fileOf(pane).?.revision;
_ = spliceBody(p, pane, q0, q1, "") orelse return .err;
- pf.joined = fileOf(pane).?.revision;
+ pf.joined = if (fileOf(pane).?.revision != was) fileOf(pane).?.revision else null;
pf.joined_by = 0;
setDot(pane, .{ .q0 = shiftOne(before.q0, q0, q1 - q0, 0), .q1 = shiftOne(before.q1, q0, q1 - q0, 0) });
pf.addr = .{ .q0 = q0, .q1 = q0 };