diff options
Diffstat (limited to 'src/ninep/ctl.zig')
| -rw-r--r-- | src/ninep/ctl.zig | 56 |
1 files changed, 55 insertions, 1 deletions
diff --git a/src/ninep/ctl.zig b/src/ninep/ctl.zig index 188795de..537ac4d0 100644 --- a/src/ninep/ctl.zig +++ b/src/ninep/ctl.zig @@ -1829,6 +1829,60 @@ test "Putall saves every pane with unsaved edits to a file, one each, and leaves try testing.expectEqual(@as(usize, 1), saves); } +test "Zerox makes a second pane on one buffer: one text, undo and dirty state, its own cursor; Save cleans both, Del of one asks nothing" { + var tmp = testing.tmpDir(.{}); + defer tmp.cleanup(); + var dir_buf: [4096]u8 = undefined; + const dir = dir_buf[0..try tmp.dir.realPath(testing.io, &dir_buf)]; + const p = try withFile(testing.allocator, "one\ntwo\nthree\n"); + defer p.deinit(); + const first = serialOf(p); + var name: [std.fs.max_path_bytes + 8]u8 = undefined; + _ = wr(p, Node.of(first, .name), try std.fmt.bufPrint(&name, "{s}/z.txt\n", .{dir})); + try testing.expect(p.executeBuiltinLine(0, "Zerox")); + const twin_id = for (p.panes, 0..) |slot, id| { + if (id != 0) if (slot) |pane| if (pane.file != null) break id; + } else return error.NoTwin; + const a = p.panes[0].?; + const b = p.panes[twin_id].?; + // Both in the index, each its serial, one name. + const index = rd(p, @intFromEnum(tree.TopFile.index), 0, 4096).bytes; + try testing.expectEqual(@as(usize, 2), std.mem.count(u8, index, "/z.txt")); + // b's cursor on `three`; a line written above it in a moves it down. + b.body.cur_row = 2; + b.body.cur_col = 1; + _ = wr(p, Node.of(first, .addr), "0"); + try testing.expectEqual(Status.ok, wr(p, Node.of(first, .data), "zero\n").reply.status); + try testing.expectEqualStrings("zero\none\ntwo\nthree\n", b.file.?.content); + try testing.expectEqual(a.file.?.content.ptr, b.file.?.content.ptr); + try testing.expectEqual(@as(i32, 3), b.body.cur_row); + try testing.expectEqual(@as(i32, 1), b.body.cur_col); + try testing.expect(pane_files.dirtyOf(a) and pane_files.dirtyOf(b)); + // A write through b is a's too; Undo in a takes it back from both. + try testing.expectEqual(Status.ok, wr(p, Node.of(b.serial, .body), "four\n").reply.status); + try testing.expectEqualStrings("zero\none\ntwo\nthree\nfour\n", a.file.?.content); + try testing.expect(p.executeBuiltinLine(0, "Undo")); + try testing.expectEqualStrings("zero\none\ntwo\nthree\n", b.file.?.content); + // Saved from b: both come clean. + try testing.expect(p.executeBuiltinLine(twin_id, "Save")); + while (p.nextEffect()) |e| p.perform(e); + try testing.expect(!pane_files.dirtyOf(a) and !pane_files.dirtyOf(b)); + try testing.expectEqualStrings("zero\none\ntwo\nthree\n", p.fallback.get(b.file.?.path).?); + // Edited again, Del of a asks nothing: b holds the text. + try testing.expectEqual(Status.ok, wr(p, Node.of(b.serial, .body), "five\n").reply.status); + const failures = p.fs.failures; + try testing.expect(p.executeBuiltinLine(0, "Del")); + p.sync(); + try testing.expectEqual(failures, p.fs.failures); + try testing.expect(p.paneBySerial(first) == null); + try testing.expect(pane_files.dirtyOf(b)); + try testing.expectEqualStrings("zero\none\ntwo\nthree\nfive\n", b.file.?.content); + // Alone now, it is no twin; Del asks about it as about any pane. + try testing.expectEqual(@as(u32, 0), b.file.?.twin); + try testing.expect(p.executeBuiltinLine(p.paneBySerial(b.serial).?, "Del")); + try testing.expect(p.fs.failures != failures); +} + test "a body write to a terminal is typed input, not a paste, even to a program that asked for bracketed paste" { const p = try Pardes.init(testing.allocator, .{ .cols = 90, .rows = 30 }); defer p.deinit(); @@ -3211,7 +3265,7 @@ test "acme's words run as pardes's (Put is Save, Delete a Del that does not ask) const p = try withFile(testing.allocator, "x\n"); defer p.deinit(); const serial = serialOf(p); - for ([_][]const u8{ "Snarf\n", "Zerox\n", "Indent\n", "Local\n", "Abort\n" }) |line| { + for ([_][]const u8{ "Snarf\n", "Indent\n", "Local\n", "Abort\n" }) |line| { for ([_]u64{ Node.of(serial, .ctl), Node.of(serial, .exec) }) |node| { const r = wr(p, node, line); try testing.expectEqual(E.INVAL, r.errno()); |
