diff options
Diffstat (limited to 'src/ninep')
| -rw-r--r-- | src/ninep/pane.zig | 23 |
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 }; |
