summaryrefslogtreecommitdiff
path: root/test/panes.zig
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-09-27 23:06:11 -0300
committerGabriel Schneider <[email protected]>2026-10-01 00:12:14 -0300
commit95a3a1bb822e583988bfe0f312d0ef219b27a454 (patch)
tree95306e8d3f36f8af05b3ea919f6cdef1e94a028b /test/panes.zig
parentc8f0c25a854b8e169db08a84d1fdcd915a70aaa0 (diff)
downloadpardes-95a3a1bb822e583988bfe0f312d0ef219b27a454.tar.gz
pardes-95a3a1bb822e583988bfe0f312d0ef219b27a454.zip
Give a pane's body its own Text holding the cursor, selections, mode and undo
acme keeps what edits a text in its Text (dat.h:171-190) and the window holds a body and a tag of that type. The cursor, the selections, the modal state and the edit-buffer undo move off Pane into Text.zig, Pane holds them as its body, and the edit and normal-mode operations take the Text they edit. Nothing changes in behaviour; this is the step that lets the tag become a second Text. Co-Authored-By: Claude Opus 5.5 <[email protected]>
Diffstat (limited to 'test/panes.zig')
-rw-r--r--test/panes.zig398
1 files changed, 199 insertions, 199 deletions
diff --git a/test/panes.zig b/test/panes.zig
index 60dabb8a..4c969ab5 100644
--- a/test/panes.zig
+++ b/test/panes.zig
@@ -327,14 +327,14 @@ const TagNavigationTests = struct {
key(p, 'i');
key(p, Key.end);
const before = pane.tag_tail_len;
- try std.testing.expect(pane.tag_edit and pane.mode == .insert);
+ try std.testing.expect(pane.tag_edit and pane.body.mode == .insert);
for ("hjklHJKL") |letter| {
const text = [_]u8{letter};
p.update(.{ .key = .{ .cp = letter, .text = &text } });
- try std.testing.expect(pane.tag_edit and pane.mode == .insert);
+ try std.testing.expect(pane.tag_edit and pane.body.mode == .insert);
}
try std.testing.expectEqualStrings("hjklHJKL", pane.tag_tail[before..pane.tag_tail_len]);
- try std.testing.expect(pane.tag_edit and pane.mode == .insert and p.topbar_col == null);
+ try std.testing.expect(pane.tag_edit and pane.body.mode == .insert and p.topbar_col == null);
try std.testing.expectEqual(@as(usize, 0), p.active);
}
}
@@ -370,7 +370,7 @@ const BodyHitTests = struct {
const expected = pane.wrapAt(row).line;
p.update(.{ .mouse = mouse(layer, row, 2, .press) });
p.update(.{ .mouse = mouse(layer, row, 2, .release) });
- try std.testing.expectEqual(expected, pane.cur_row);
+ try std.testing.expectEqual(expected, pane.body.cur_row);
try std.testing.expectEqual(top, pane.scroll());
}
const last = pane.body_visible_rows - 1;
@@ -383,11 +383,11 @@ const BodyHitTests = struct {
try std.testing.expectEqualStrings("body\nbody", pardes.test_api.heldSelection(p, 0).?);
p.update(.{ .mouse = mouse(layer, last, 10, .press) });
p.update(.{ .mouse = mouse(layer, last, 10, .release) });
- try std.testing.expectEqual(expected, pane.cur_row);
+ try std.testing.expectEqual(expected, pane.body.cur_row);
var stale = mouse(layer, 0, 2, .press);
stale.body_hit.?.serial +%= 1;
p.update(.{ .mouse = stale });
- try std.testing.expectEqual(expected, pane.cur_row);
+ try std.testing.expectEqual(expected, pane.body.cur_row);
p.update(.{ .key = .{ .cp = 'i' } });
p.update(.{ .key = .{ .cp = 'X', .text = "X" } });
try std.testing.expect(std.mem.indexOfScalar(u8, modal.lineSlice(pane.file.?.content, @intCast(expected)), 'X') != null);
@@ -425,7 +425,7 @@ const LineNumberLookTests = struct {
release.button = .right;
p.update(.{ .mouse = press });
p.update(.{ .mouse = release });
- try std.testing.expectEqual(expected, pane.cur_row);
+ try std.testing.expectEqual(expected, pane.body.cur_row);
}
}
};
@@ -496,9 +496,9 @@ const TreeContextTests = struct {
try std.testing.expectEqual(@as(i32, 0), pane.scroll());
pardes.look.lookAt(p, 0, "/tree-context.zig:60");
try std.testing.expectEqual(@as(usize, 0), p.active);
- try std.testing.expectEqual(@as(i32, 59), pane.cur_row);
+ try std.testing.expectEqual(@as(i32, 59), pane.body.cur_row);
const surface = try p.render(frame.allocator());
- const visible = pane.wrapRow(pane.cur_row, pane.cur_col);
+ const visible = pane.wrapRow(pane.body.cur_row, pane.body.cur_col);
try std.testing.expect(visible.row >= pane.context_rows);
try std.testing.expect(visible.row < pane.rows);
try std.testing.expectEqual(@as(i32, 59), pane.wrapAt(visible.row).line);
@@ -528,8 +528,8 @@ const TreeContextTests = struct {
const x = rect.x + config.GUTTER + panes.File.gutterWidth(pane);
const y = p.bodyTop(rect);
ClickCursorTests.click(p, .left, x + 6, y);
- try std.testing.expectEqual(@as(i32, 0), pane.cur_row);
- try std.testing.expectEqual(@as(i32, 6), pane.cur_col);
+ try std.testing.expectEqual(@as(i32, 0), pane.body.cur_row);
+ try std.testing.expectEqual(@as(i32, 6), pane.body.cur_col);
try std.testing.expectEqual(@as(i32, 7), pane.scroll());
const cursor = (try p.render(frame.allocator())).cursor orelse return error.MissingContextCursor;
try std.testing.expectEqual(x + 6, cursor.x);
@@ -552,7 +552,7 @@ const TreeContextTests = struct {
try std.testing.expectEqual(pane.scroll(), pane.wrapAt(pane.context_rows).line);
}
try std.testing.expectEqual(@as(u16, 0), pane.context_rows);
- try std.testing.expectEqual(@as(i32, 0), pane.wrapRow(0, pane.cur_col).row);
+ try std.testing.expectEqual(@as(i32, 0), pane.wrapRow(0, pane.body.cur_col).row);
try std.testing.expect(p.executeBuiltinLine(0, "TreeContext"));
pane.scrollBy(7);
_ = try p.render(frame.allocator());
@@ -581,8 +581,8 @@ const TreeContextTests = struct {
}
const x = glyph_x orelse return error.MissingContextUnicode;
ClickCursorTests.click(p, .left, x + 1, y);
- try std.testing.expectEqual(@as(i32, 0), pane.cur_row);
- try std.testing.expectEqual(@as(i32, 9), pane.cur_col);
+ try std.testing.expectEqual(@as(i32, 0), pane.body.cur_row);
+ try std.testing.expectEqual(@as(i32, 9), pane.body.cur_col);
try std.testing.expectEqual(@as(i32, 8), pane.scroll());
const cursor = (try p.render(frame.allocator())).cursor orelse return error.MissingContextCursor;
try std.testing.expectEqual(x, cursor.x);
@@ -617,8 +617,8 @@ const TreeContextTests = struct {
};
const glyph = target orelse return error.MissingWrappedContextBody;
ClickCursorTests.click(p, .left, glyph.x + 1, glyph.y);
- try std.testing.expectEqual(@as(i32, 2), pane.cur_row);
- try std.testing.expectEqual(@as(i32, @intCast(std.mem.indexOf(u8, body, "界").?)), pane.cur_col);
+ try std.testing.expectEqual(@as(i32, 2), pane.body.cur_row);
+ try std.testing.expectEqual(@as(i32, @intCast(std.mem.indexOf(u8, body, "界").?)), pane.body.cur_col);
const cursor = (try p.render(frame.allocator())).cursor orelse return error.MissingContextBodyCursor;
try std.testing.expectEqual(glyph.x, cursor.x);
try std.testing.expectEqual(glyph.y, cursor.y);
@@ -652,7 +652,7 @@ const TtySelectionTests = struct {
try std.testing.expectEqualStrings("lph", p.yank orelse return error.MissingAutomaticTtyYank);
p.update(.{ .key = .{ .cp = p.opts.tty_toggle, .ctrl = true } });
p.update(.{ .key = .{ .cp = 'l' } });
- try std.testing.expectEqual(@as(i32, 4), pane.cur_col);
+ try std.testing.expectEqual(@as(i32, 4), pane.body.cur_col);
p.update(.{ .key = .{ .cp = 'y' } });
try std.testing.expectEqualStrings("a", p.yank.?);
try noChildInput(p);
@@ -664,7 +664,7 @@ const TtySelectionTests = struct {
const p = try Pardes.init(std.testing.allocator, .{ .tty_only = true, .cols = 40, .rows = 12 });
defer p.deinit();
const pane = p.panes[0].?;
- pane.mode = .tty;
+ pane.body.mode = .tty;
pane.tty_filter = false;
p.presentation.enabled = false;
while (p.nextEffect()) |_| {}
@@ -680,7 +680,7 @@ const TtySelectionTests = struct {
const y = p.bodyTop(rect);
JumpSelectionTests.drag(p, x + @as(u16, if (prompt) 0 else 1), y, x + 3, y + @as(u16, if (prompt) 0 else 1));
const expected = if (prompt) "$ ab" else "lph\nrav";
- try std.testing.expectEqual(Pane.Mode.tty, pane.mode);
+ try std.testing.expectEqual(panes.Text.Mode.tty, pane.body.mode);
try std.testing.expectEqualStrings(expected, pardes.test_api.heldSelection(p, 0).?);
try std.testing.expectEqualStrings(expected, p.yank orelse return error.MissingAutomaticTtyYank);
try noChildInput(p);
@@ -689,7 +689,7 @@ const TtySelectionTests = struct {
try noChildInput(p);
try std.testing.expectEqualStrings(expected, p.fallback.clipboard.items);
p.update(.{ .key = .{ .cp = p.opts.tty_toggle, .ctrl = true } });
- try std.testing.expectEqual(Pane.Mode.normal, pane.mode);
+ try std.testing.expectEqual(panes.Text.Mode.normal, pane.body.mode);
const normal = try p.render(frame.allocator());
if (!prompt) {
const selection_bg: pardes.Color = .{ .rgb = p.theme().sel_bg };
@@ -701,13 +701,13 @@ const TtySelectionTests = struct {
try std.testing.expectEqualStrings(expected, p.yank.?);
try noChildInput(p);
p.update(.{ .key = .{ .cp = p.opts.tty_toggle, .ctrl = true } });
- try std.testing.expectEqual(Pane.Mode.tty, pane.mode);
+ try std.testing.expectEqual(panes.Text.Mode.tty, pane.body.mode);
try noChildInput(p);
_ = try p.render(frame.allocator());
try std.testing.expectEqualStrings(expected, pardes.test_api.heldSelection(p, 0).?);
p.update(.{ .output = .{ .pane = 0, .bytes = "\x1b]133;C\x07" ++ "\r\nnew output" ** 30 } });
_ = try p.render(frame.allocator());
- try std.testing.expectEqual(Pane.Mode.tty, pane.mode);
+ try std.testing.expectEqual(panes.Text.Mode.tty, pane.body.mode);
try std.testing.expectEqualStrings(expected, pardes.test_api.heldSelection(p, 0).?);
try std.testing.expectEqualStrings(expected, p.yank.?);
try noChildInput(p);
@@ -723,7 +723,7 @@ const TtySelectionTests = struct {
p.presentation.enabled = false;
pardes.exec.spawnTty(p, 0);
for (p.panes[0..2]) |slot| {
- slot.?.mode = .tty;
+ slot.?.body.mode = .tty;
slot.?.tty_filter = false;
slot.?.greet = false;
slot.?.vweight = 1;
@@ -765,8 +765,8 @@ const TtySelectionTests = struct {
});
defer p.gpa.free(expected);
try std.testing.expectEqualStrings(expected, written.written());
- try std.testing.expectEqual(Pane.Mode.tty, p.panes[0].?.mode);
- try std.testing.expectEqual(Pane.Mode.tty, p.panes[1].?.mode);
+ try std.testing.expectEqual(panes.Text.Mode.tty, p.panes[0].?.body.mode);
+ try std.testing.expectEqual(panes.Text.Mode.tty, p.panes[1].?.body.mode);
try std.testing.expectEqualStrings("lph\nrav", pardes.test_api.heldSelection(p, 0).?);
}
}
@@ -799,7 +799,7 @@ const TtySelectionTests = struct {
const p = try Pardes.init(std.testing.allocator, .{ .tty_only = true, .cols = 40, .rows = 12 });
defer p.deinit();
const pane = p.panes[0].?;
- try std.testing.expectEqual(Pane.Mode.tty, pane.mode);
+ try std.testing.expectEqual(panes.Text.Mode.tty, pane.body.mode);
if (bracketed) p.update(.{ .output = .{ .pane = 0, .bytes = "\x1b[?2004h" } });
try std.testing.expectEqual(bracketed, panes.Terminal.bracketedPaste(pane));
p.yank = try p.gpa.dupe(u8, "one\ntwo"); // what a `y` anywhere left behind
@@ -867,13 +867,13 @@ const ClickCursorTests = struct {
const x = rect.x + config.GUTTER + panes.File.gutterWidth(pane);
const y = if (bottom_tag) rect.y else rect.y + pardes.BOX_H;
click(p, .left, x + 15, y + case.click_row);
- try std.testing.expectEqual(case.row, pane.cur_row);
- try std.testing.expectEqual(case.col, pane.cur_col);
+ try std.testing.expectEqual(case.row, pane.body.cur_row);
+ try std.testing.expectEqual(case.col, pane.body.cur_col);
const clicked = (try p.render(frame.allocator())).cursor orelse return error.MissingClickCursor;
try std.testing.expectEqual(x + @as(u16, @intCast(case.col)), clicked.x);
try std.testing.expectEqual(y + @as(u16, @intCast(case.row)), clicked.y);
if (!already_insert) p.update(.{ .key = .{ .cp = 'i' } });
- try std.testing.expectEqual(Pane.Mode.insert, pane.mode);
+ try std.testing.expectEqual(panes.Text.Mode.insert, pane.body.mode);
const insert = (try p.render(frame.allocator())).cursor orelse return error.MissingInsertCursor;
try std.testing.expectEqual(clicked.x, insert.x);
try std.testing.expectEqual(clicked.y, insert.y);
@@ -906,12 +906,12 @@ const ClickCursorTests = struct {
if (wrap) try std.testing.expect(glyph.y > p.rects[0].y + pardes.BOX_H);
click(p, .left, glyph.x + 1, glyph.y);
const byte = std.mem.indexOf(u8, source, "界").?;
- try std.testing.expectEqual(@as(i32, @intCast(byte)), pane.cur_col);
+ try std.testing.expectEqual(@as(i32, @intCast(byte)), pane.body.cur_col);
const clicked = (try p.render(frame.allocator())).cursor orelse return error.MissingClickCursor;
try std.testing.expectEqual(glyph.x, clicked.x);
try std.testing.expectEqual(glyph.y, clicked.y);
if (!already_insert) p.update(.{ .key = .{ .cp = 'i' } });
- try std.testing.expectEqual(Pane.Mode.insert, pane.mode);
+ try std.testing.expectEqual(panes.Text.Mode.insert, pane.body.mode);
const insert = (try p.render(frame.allocator())).cursor orelse return error.MissingInsertCursor;
try std.testing.expectEqual(clicked.x, insert.x);
try std.testing.expectEqual(clicked.y, insert.y);
@@ -1016,10 +1016,10 @@ const JumpSelectionTests = struct {
try std.testing.expectEqual(@as(usize, 0), p.jcur);
try std.testing.expect(pane.file.?.scroll > 20);
try LookResetTests.cleared(pane);
- try std.testing.expect(!pane.vsel.active);
+ try std.testing.expect(!pane.body.vsel.active);
try std.testing.expect(pardes.test_api.heldSelection(p, 0) == null);
- try std.testing.expectEqual(@as(i32, 59), pane.cur_row);
- try std.testing.expectEqual(@as(i32, 0), pane.cur_col);
+ try std.testing.expectEqual(@as(i32, 59), pane.body.cur_row);
+ try std.testing.expectEqual(@as(i32, 0), pane.body.cur_col);
// A selection created after Back must also disappear on Forward.
// Back announces itself, so the body sits under a notice band now.
@@ -1032,10 +1032,10 @@ const JumpSelectionTests = struct {
try std.testing.expectEqual(@as(usize, 1), p.jcur);
try std.testing.expectEqual(@as(usize, 0), pane.file.?.scroll);
try LookResetTests.cleared(pane);
- try std.testing.expect(!pane.vsel.active);
+ try std.testing.expect(!pane.body.vsel.active);
try std.testing.expect(pardes.test_api.heldSelection(p, 0) == null);
- try std.testing.expectEqual(@as(i32, 0), pane.cur_row);
- try std.testing.expectEqual(@as(i32, 0), pane.cur_col);
+ try std.testing.expectEqual(@as(i32, 0), pane.body.cur_row);
+ try std.testing.expectEqual(@as(i32, 0), pane.body.cur_col);
}
test "jump selection clears copied rectangles in both history directions" {
@@ -1073,9 +1073,9 @@ const JumpSelectionTests = struct {
try std.testing.expectEqual(@as(usize, 0), p.jcur);
try LookResetTests.cleared(source);
try LookResetTests.cleared(destination);
- try std.testing.expect(!source.vsel.active and !destination.vsel.active);
- try std.testing.expectEqual(@as(i32, 2), destination.cur_row);
- try std.testing.expectEqual(@as(i32, 1), destination.cur_col);
+ try std.testing.expect(!source.body.vsel.active and !destination.body.vsel.active);
+ try std.testing.expectEqual(@as(i32, 2), destination.body.cur_row);
+ try std.testing.expectEqual(@as(i32, 1), destination.body.cur_col);
try LookResetTests.seed(source, "new source held text");
try LookResetTests.seed(destination, "new destination held text");
@@ -1084,9 +1084,9 @@ const JumpSelectionTests = struct {
try std.testing.expectEqual(@as(usize, 1), p.jcur);
try LookResetTests.cleared(source);
try LookResetTests.cleared(destination);
- try std.testing.expect(!source.vsel.active and !destination.vsel.active);
- try std.testing.expectEqual(@as(i32, 1), source.cur_row);
- try std.testing.expectEqual(@as(i32, 0), source.cur_col);
+ try std.testing.expect(!source.body.vsel.active and !destination.body.vsel.active);
+ try std.testing.expectEqual(@as(i32, 1), source.body.cur_row);
+ try std.testing.expectEqual(@as(i32, 0), source.body.cur_col);
}
};
@@ -1395,7 +1395,7 @@ test "terminal overlay recoloring never materializes unrelated history" {
const pane = p.panes[0].?;
pane.tty_filter = false;
for (0..1000) |_| p.update(.{ .output = .{ .pane = 0, .bytes = "\x1b[32mcaf\xc3\xa9 \xe7\x95\x8c\x1b[0m\r\n" } });
- pane.mode = .normal;
+ pane.body.mode = .normal;
pane.ovl = .{ .row = 0, .rows = 1, .text = try p.gpa.dupe(u8, "edited history") };
var frame = std.heap.ArenaAllocator.init(testing.allocator);
defer frame.deinit();
@@ -1422,7 +1422,7 @@ test "terminal output keeps following new rows after scrollback eviction" {
defer p.deinit();
while (p.nextEffect()) |_| {}
const pane = p.panes[0].?;
- pane.mode = .tty;
+ pane.body.mode = .tty;
pane.tty_filter = false;
const pages = &pane.terminal.?.vt.screens.active.pages;
pages.explicit_max_size = 64 * 1024;
@@ -1431,7 +1431,7 @@ test "terminal output keeps following new rows after scrollback eviction" {
var evictions: usize = 0;
for (0..3) |phase| {
if (phase > 0) {
- pane.mode = .normal;
+ pane.body.mode = .normal;
panes.Terminal.scrollGrid(pane, -30);
try std.testing.expect(pages.scrollbar().offset < pages.scrollbar().total - pane.rows);
panes.Terminal.enterTty(p, 0);
@@ -1483,7 +1483,7 @@ test "terminal edit stays on its surviving row when old scrollback is evicted" {
defer p.deinit();
while (p.nextEffect()) |_| {}
const pane = p.panes[0].?;
- pane.mode = .tty;
+ pane.body.mode = .tty;
const pages = &pane.terminal.?.vt.screens.active.pages;
pages.explicit_max_size = 64 * 1024;
var next: usize = 0;
@@ -1497,12 +1497,12 @@ test "terminal edit stays on its surviving row when old scrollback is evicted" {
try std.testing.expect(next < 3000);
var last_buf: [16]u8 = undefined;
const last = try std.fmt.bufPrint(&last_buf, "row-{d:0>5}", .{next - 1});
- pane.mode = .normal;
+ pane.body.mode = .normal;
const original_row: i32 = @intCast(pages.scrollbar().total - 2);
pane.ovl = .{ .row = original_row, .rows = 1, .text = try gpa.dupe(u8, "my unsent edit") };
- pane.cur_row = original_row;
- pane.cur_col = 3;
- pane.cur_pinned = true;
+ pane.body.cur_row = original_row;
+ pane.body.cur_col = 3;
+ pane.body.cur_pinned = true;
var removed: usize = 0;
for (next..next + 3000) |n| {
var buf: [32]u8 = undefined;
@@ -1520,7 +1520,7 @@ test "terminal edit stays on its surviving row when old scrollback is evicted" {
const row = original_row - @as(i32, @intCast(removed));
try std.testing.expectEqualStrings(last, modal.lineSlice(full, @intCast(row)));
try std.testing.expectEqual(row, pane.ovl.?.row);
- try std.testing.expectEqual(row, pane.cur_row);
+ try std.testing.expectEqual(row, pane.body.cur_row);
try std.testing.expectEqualStrings("my unsent edit", pane.ovl.?.text);
}
@@ -1533,7 +1533,7 @@ test "terminal edits and undo survive partial history clearing and whole-screen
defer p.deinit();
while (p.nextEffect()) |_| {}
const pane = p.panes[0].?;
- pane.mode = .tty;
+ pane.body.mode = .tty;
if (action == .reset_alternate)
p.update(.{ .output = .{ .pane = 0, .bytes = "\x1b[?1049h" } });
p.update(.{ .output = .{ .pane = 0, .bytes = "old row\r\n" ** 40 } });
@@ -1541,15 +1541,15 @@ test "terminal edits and undo survive partial history clearing and whole-screen
pages.explicit_max_size = 64 * 1024;
const row: i32 = @as(i32, @intCast(pages.total_rows - pane.rows)) +
@as(i32, if (action == .partial_clear_history) -1 else 2);
- pane.mode = .normal;
+ pane.body.mode = .normal;
pane.ovl = .{ .row = row, .rows = if (action == .partial_clear_history) 3 else 2, .text = try gpa.dupe(u8, "edit one\nedit two") };
- pane.cur_row = row + 1;
- pane.cur_col = 4;
- pane.cur_pinned = true;
- pane.vsel = .{ .active = true, .row = row, .col = 1 };
+ pane.body.cur_row = row + 1;
+ pane.body.cur_col = 4;
+ pane.body.cur_pinned = true;
+ pane.body.vsel = .{ .active = true, .row = row, .col = 1 };
panes.Terminal.pushUndo(p, pane);
- pane.ed_redo[0] = panes.Terminal.snap(p, pane) orelse return error.SnapshotFailed;
- pane.ed_redo_len = 1;
+ pane.body.ed_redo[0] = panes.Terminal.snap(p, pane) orelse return error.SnapshotFailed;
+ pane.body.ed_redo_len = 1;
if (action == .hidden_undo) {
gpa.free(pane.ovl.?.text);
pane.ovl = null;
@@ -1566,10 +1566,10 @@ test "terminal edits and undo survive partial history clearing and whole-screen
try std.testing.expectEqual(expected, edit.row);
try std.testing.expectEqual(@as(i32, if (action == .clear_history or action == .partial_clear_history) 2 else 1), edit.rows);
try std.testing.expectEqualStrings("edit one\nedit two", edit.text);
- try std.testing.expectEqual(expected + 1, pane.cur_row);
- try std.testing.expectEqual(expected, pane.vsel.row);
+ try std.testing.expectEqual(expected + 1, pane.body.cur_row);
+ try std.testing.expectEqual(expected, pane.body.vsel.row);
}
- for ([_]panes.Terminal.Snapshot{ pane.ed_undo[0], pane.ed_redo[0] }) |snapshot| {
+ for ([_]panes.Terminal.Snapshot{ pane.body.ed_undo[0], pane.body.ed_redo[0] }) |snapshot| {
try std.testing.expectEqual(expected, snapshot.ovl.?.row);
try std.testing.expectEqual(expected + 1, snapshot.cur_row);
try std.testing.expectEqualStrings("edit one\nedit two", snapshot.ovl.?.text);
@@ -1588,11 +1588,11 @@ test "terminal lower scroll regions do not move edits above them" {
defer p.deinit();
while (p.nextEffect()) |_| {}
const pane = p.panes[0].?;
- pane.mode = .normal;
+ pane.body.mode = .normal;
p.update(.{ .output = .{ .pane = 0, .bytes = "top\r\nsecond\r\nthird" } });
pane.ovl = .{ .row = 1, .rows = 1, .text = try gpa.dupe(u8, "unsent") };
- pane.cur_row = 1;
- pane.cur_pinned = true;
+ pane.body.cur_row = 1;
+ pane.body.cur_pinned = true;
panes.Terminal.pushUndo(p, pane);
const total = panes.Terminal.scrollbar(pane).total;
var setup: [64]u8 = undefined;
@@ -1601,8 +1601,8 @@ test "terminal lower scroll regions do not move edits above them" {
p.update(.{ .output = .{ .pane = 0, .bytes = "tail\r\n" ** 50 } });
try std.testing.expectEqual(total, panes.Terminal.scrollbar(pane).total);
try std.testing.expectEqual(@as(i32, 1), pane.ovl.?.row);
- try std.testing.expectEqual(@as(i32, 1), pane.cur_row);
- try std.testing.expectEqual(@as(i32, 1), pane.ed_undo[0].ovl.?.row);
+ try std.testing.expectEqual(@as(i32, 1), pane.body.cur_row);
+ try std.testing.expectEqual(@as(i32, 1), pane.body.ed_undo[0].ovl.?.row);
const full = try panes.Terminal.screenTextAlloc(pane, gpa);
defer gpa.free(full);
try std.testing.expect(std.mem.startsWith(u8, full, "top\nsecond\nthird\n"));
@@ -1615,7 +1615,7 @@ test "terminal eviction and lower-region scrolling in one read preserve a surviv
defer p.deinit();
while (p.nextEffect()) |_| {}
const pane = p.panes[0].?;
- pane.mode = .tty;
+ pane.body.mode = .tty;
const pages = &pane.terminal.?.vt.screens.active.pages;
pages.explicit_max_size = 64 * 1024;
var next: usize = 0;
@@ -1630,10 +1630,10 @@ test "terminal eviction and lower-region scrolling in one read preserve a surviv
try std.testing.expect(next < 3000);
const removed = pages.pages.first.?.rows();
const old_row: i32 = @intCast(removed + 2);
- pane.mode = .normal;
+ pane.body.mode = .normal;
pane.ovl = .{ .row = old_row, .rows = 1, .text = try gpa.dupe(u8, "kept edit") };
- pane.cur_row = old_row;
- pane.cur_pinned = true;
+ pane.body.cur_row = old_row;
+ pane.body.cur_pinned = true;
panes.Terminal.pushUndo(p, pane);
const old_total = pages.total_rows;
var buf: [128]u8 = undefined;
@@ -1641,8 +1641,8 @@ test "terminal eviction and lower-region scrolling in one read preserve a surviv
p.update(.{ .output = .{ .pane = 0, .bytes = bytes } });
try std.testing.expectEqual(old_total + 1 - removed, pages.total_rows);
try std.testing.expectEqual(@as(i32, 2), pane.ovl.?.row);
- try std.testing.expectEqual(@as(i32, 2), pane.cur_row);
- try std.testing.expectEqual(@as(i32, 2), pane.ed_undo[0].ovl.?.row);
+ try std.testing.expectEqual(@as(i32, 2), pane.body.cur_row);
+ try std.testing.expectEqual(@as(i32, 2), pane.body.ed_undo[0].ovl.?.row);
try std.testing.expectEqualStrings("kept edit", pane.ovl.?.text);
}
@@ -1667,9 +1667,9 @@ test "tag prompt entry and cancellation preserve exact text and cursor state" {
pane.tag_init = true;
pane.tag_sel = true;
pane.tag_col = 1;
- pane.cur_row = 1;
- pane.cur_col = 2;
- pane.cur_pinned = true;
+ pane.body.cur_row = 1;
+ pane.body.cur_col = 2;
+ pane.body.cur_pinned = true;
if (case.key) |key| {
p.update(.{ .key = key });
} else if (case.save) {
@@ -1679,18 +1679,18 @@ test "tag prompt entry and cancellation preserve exact text and cursor state" {
}
try std.testing.expect(pane.tag_edit);
try std.testing.expect(!pane.tag_sel);
- try std.testing.expectEqual(.insert, pane.mode);
- try std.testing.expectEqualDeep(modal.Normal.State{}, pane.normal);
+ try std.testing.expectEqual(.insert, pane.body.mode);
+ try std.testing.expectEqualDeep(modal.Normal.State{}, pane.body.normal);
try std.testing.expectEqualStrings(tail, pane.tag_tail[0..tail.len]);
try std.testing.expectEqualStrings(case.marker, pane.tag_tail[tail.len..pane.tag_tail_len]);
try std.testing.expectEqual(pane.file.?.path.len + pane.tag_tail_len, pane.tag_col);
p.update(.{ .key = .{ .cp = Key.escape } });
try std.testing.expect(pane.prompt == .none);
try std.testing.expect(!pane.tag_edit);
- try std.testing.expectEqual(.normal, pane.mode);
+ try std.testing.expectEqual(.normal, pane.body.mode);
try std.testing.expectEqualStrings(tail, pane.tag_tail[0..pane.tag_tail_len]);
- try std.testing.expectEqual(@as(i32, 1), pane.cur_row);
- try std.testing.expectEqual(@as(i32, 2), pane.cur_col);
+ try std.testing.expectEqual(@as(i32, 1), pane.body.cur_row);
+ try std.testing.expectEqual(@as(i32, 2), pane.body.cur_col);
try std.testing.expectEqualStrings("one\ntwo\n", pane.file.?.content);
}
}
@@ -1713,7 +1713,7 @@ test "tag prompt capacity refusal leaves the existing tail and input state untou
try std.testing.expect(pane.prompt == .none);
try std.testing.expect(!pane.tag_edit);
try std.testing.expect(pane.tag_sel);
- try std.testing.expectEqual(.normal, pane.mode);
+ try std.testing.expectEqual(.normal, pane.body.mode);
try std.testing.expectEqual(@as(u16, 17), pane.tag_col);
try std.testing.expectEqual(pane.tag_tail.len - 1, pane.tag_tail_len);
for (pane.tag_tail) |byte| try std.testing.expectEqual(@as(u8, 'x'), byte);
@@ -1739,9 +1739,9 @@ test "tag prompt owns the pipe behavior through cancellation and submission" {
const p = try Pardes.init(std.testing.allocator, .{ .tty_only = true });
defer p.deinit();
const pane = try p.setTestFile("one\ntwo\n");
- pane.cur_row = 0;
- pane.cur_col = 2;
- pane.vsel = .{ .active = true, .row = 0, .col = 0, .explicit = true };
+ pane.body.cur_row = 0;
+ pane.body.cur_col = 2;
+ pane.body.vsel = .{ .active = true, .row = 0, .col = 0, .explicit = true };
for (std.enums.values(modal.Normal.PipeBehavior)) |how| {
p.startPrompt(pane, .{ .pipe = .append });
p.update(.{ .key = .{ .cp = Key.escape } });
@@ -1767,21 +1767,21 @@ test "tag prompt cancellation restores the selection before regex previews" {
.{ .key = 'S', .pattern = " ", .secondary = 2 },
};
for (cases) |case| {
- pane.cur_row = 0;
- pane.cur_col = 10;
- pane.cur_pinned = true;
- pane.vsel = .{ .active = true, .row = 0, .col = 0, .explicit = true };
- pane.nsel = 0;
+ pane.body.cur_row = 0;
+ pane.body.cur_col = 10;
+ pane.body.cur_pinned = true;
+ pane.body.vsel = .{ .active = true, .row = 0, .col = 0, .explicit = true };
+ pane.body.nsel = 0;
p.update(.{ .key = .{ .cp = case.key } });
try std.testing.expect(pane.prompt == .search);
p.update(.{ .key = .{ .cp = case.pattern[0], .text = case.pattern } });
- try std.testing.expectEqual(case.secondary, pane.nsel);
+ try std.testing.expectEqual(case.secondary, pane.body.nsel);
p.update(.{ .key = .{ .cp = Key.escape } });
- try std.testing.expectEqual(@as(u8, 0), pane.nsel);
+ try std.testing.expectEqual(@as(u8, 0), pane.body.nsel);
try std.testing.expectEqual(@as(u8, 0), pane.nsel_snap);
- try std.testing.expectEqual(@as(i32, 10), pane.cur_col);
- try std.testing.expectEqual(@as(i32, 0), pane.vsel.col);
- try std.testing.expect(pane.vsel.active and pane.vsel.explicit);
+ try std.testing.expectEqual(@as(i32, 10), pane.body.cur_col);
+ try std.testing.expectEqual(@as(i32, 0), pane.body.vsel.col);
+ try std.testing.expect(pane.body.vsel.active and pane.body.vsel.explicit);
try std.testing.expectEqualStrings("one two one", pane.file.?.content);
}
}
@@ -1802,18 +1802,18 @@ test "tag prompt prefix allocation failure preserves an already seeded prompt" {
pane.tag_sel = true;
pane.tag_col = 14;
pane.tag_anchor = 7;
- pane.normal = .{ .count = 9, .prefix = .goto };
+ pane.body.normal = .{ .count = 9, .prefix = .goto };
const previous_prompt = pane.prompt;
- const previous_normal = pane.normal;
+ const previous_normal = pane.body.normal;
_ = p.scratch.reset(.free_all);
failing.fail_index = failing.alloc_index;
p.startPrompt(pane, request);
try std.testing.expect(failing.has_induced_failure);
try std.testing.expectEqualDeep(previous_prompt, pane.prompt);
- try std.testing.expectEqualDeep(previous_normal, pane.normal);
+ try std.testing.expectEqualDeep(previous_normal, pane.body.normal);
try std.testing.expectEqualStrings(tail, pane.tag_tail[0..pane.tag_tail_len]);
try std.testing.expect(pane.tag_edit and pane.tag_sel);
- try std.testing.expectEqual(.normal, pane.mode);
+ try std.testing.expectEqual(.normal, pane.body.mode);
try std.testing.expectEqual(@as(u16, 14), pane.tag_col);
try std.testing.expectEqual(@as(u16, 7), pane.tag_anchor);
}
@@ -1867,7 +1867,7 @@ test "tag prompt successful seeded entry needs one scratch allocation" {
const before = failing.alloc_index;
p.startPrompt(pane, request);
try std.testing.expectEqual(before + 1, failing.alloc_index);
- try std.testing.expect(pane.tag_edit and pane.mode == .insert);
+ try std.testing.expect(pane.tag_edit and pane.body.mode == .insert);
}
}
@@ -1892,20 +1892,20 @@ test "tag prompt failure may initialize only the default tail" {
pane.tag_tail_len = 0;
pane.tag_col = 17;
pane.tag_sel = true;
- pane.normal = .{ .count = 9, .prefix = .goto };
- const previous_normal = pane.normal;
+ pane.body.normal = .{ .count = 9, .prefix = .goto };
+ const previous_normal = pane.body.normal;
_ = p.scratch.reset(.free_all);
failing.fail_index = failing.alloc_index + failure;
p.startPrompt(pane, request);
if (!failing.has_induced_failure) {
- try std.testing.expect(pane.tag_edit and pane.mode == .insert);
+ try std.testing.expect(pane.tag_edit and pane.body.mode == .insert);
succeeded = true;
break;
}
try std.testing.expect(pane.prompt == .none);
try std.testing.expect(!pane.tag_edit and pane.tag_sel);
- try std.testing.expectEqual(.normal, pane.mode);
- try std.testing.expectEqualDeep(previous_normal, pane.normal);
+ try std.testing.expectEqual(.normal, pane.body.mode);
+ try std.testing.expectEqualDeep(previous_normal, pane.body.normal);
try std.testing.expectEqual(@as(u16, 17), pane.tag_col);
if (pane.tag_init) {
saw_seeded_failure = true;
@@ -2390,10 +2390,10 @@ const OutputTests = struct {
try std.testing.expectEqual(matches[1], pane.search_row.?);
try std.testing.expect(pardes.test_api.searchStep(p, 0, -1));
try std.testing.expectEqual(matches[0], pane.search_row.?);
- try std.testing.expectEqual(@as(i32, 3), pane.cur_row);
+ try std.testing.expectEqual(@as(i32, 3), pane.body.cur_row);
try std.testing.expect(pardes.test_api.searchStep(p, 0, 1));
try std.testing.expectEqual(matches[1], pane.search_row.?);
- try std.testing.expectEqual(@as(i32, 5), pane.cur_row);
+ try std.testing.expectEqual(@as(i32, 5), pane.body.cur_row);
try std.testing.expect(pardes.test_api.searchStep(p, 0, 1));
try std.testing.expectEqual(matches[1], pane.search_row.?);
@@ -2571,9 +2571,9 @@ const OutputTests = struct {
const id = p.active;
const help = p.panes[id].?;
for ("gevkk") |key| p.update(.{ .key = .{ .cp = key } });
- try std.testing.expect(help.vsel.active);
- try std.testing.expect(help.vsel.row > 5);
- try std.testing.expect(help.cur_row != help.vsel.row);
+ try std.testing.expect(help.body.vsel.active);
+ try std.testing.expect(help.body.vsel.row > 5);
+ try std.testing.expect(help.body.cur_row != help.body.vsel.row);
for (" h?") |key| p.update(.{ .key = .{ .cp = key } });
try std.testing.expectEqual(id, p.active);
const content = help.file.?.content;
@@ -2607,35 +2607,35 @@ const OutputTests = struct {
const result = p.panes[id].?;
p.active = id;
for ("Cv3") |key| p.update(.{ .key = .{ .cp = key } });
- try std.testing.expect(result.nsel > 0);
- try std.testing.expect(result.select);
- try std.testing.expect(result.vsel.active);
- try std.testing.expect(result.normal.count > 0);
+ try std.testing.expect(result.body.nsel > 0);
+ try std.testing.expect(result.body.select);
+ try std.testing.expect(result.body.vsel.active);
+ try std.testing.expect(result.body.normal.count > 0);
result.file.?.scroll = 1;
result.hscroll = 2;
- const selected = result.vsel;
- const selections = result.nsel;
- const cursor_row = result.cur_row;
- const cursor_col = result.cur_col;
+ const selected = result.body.vsel;
+ const selections = result.body.nsel;
+ const cursor_row = result.body.cur_row;
+ const cursor_col = result.body.cur_col;
try fillResults(p, 0, "/", .{ .query = .hover }, "", try p.gpa.dupe(u8, content), null);
- try std.testing.expectEqual(selected, result.vsel);
- try std.testing.expectEqual(selections, result.nsel);
- try std.testing.expectEqual(cursor_row, result.cur_row);
- try std.testing.expectEqual(cursor_col, result.cur_col);
+ try std.testing.expectEqual(selected, result.body.vsel);
+ try std.testing.expectEqual(selections, result.body.nsel);
+ try std.testing.expectEqual(cursor_row, result.body.cur_row);
+ try std.testing.expectEqual(cursor_col, result.body.cur_col);
try std.testing.expectEqual(@as(usize, 1), result.file.?.scroll);
try std.testing.expectEqual(@as(i32, 2), result.hscroll);
- try std.testing.expect(result.normal.count > 0);
+ try std.testing.expect(result.body.normal.count > 0);
try fillResults(p, 0, "/", .{ .query = .hover }, "", try p.gpa.dupe(u8, "short\n"), null);
try std.testing.expectEqualStrings("short\n", result.file.?.content);
- try std.testing.expect(!result.vsel.active and !result.msel.active and !result.select);
- try std.testing.expectEqual(@as(u8, 0), result.nsel);
- try std.testing.expectEqual(@as(i32, 0), result.cur_row);
- try std.testing.expectEqual(@as(i32, 0), result.cur_col);
+ try std.testing.expect(!result.body.vsel.active and !result.body.msel.active and !result.body.select);
+ try std.testing.expectEqual(@as(u8, 0), result.body.nsel);
+ try std.testing.expectEqual(@as(i32, 0), result.body.cur_row);
+ try std.testing.expectEqual(@as(i32, 0), result.body.cur_col);
try std.testing.expectEqual(@as(usize, 0), result.file.?.scroll);
try std.testing.expectEqual(@as(i32, 0), result.hscroll);
- try std.testing.expectEqual(modal.Normal.State{}, result.normal);
+ try std.testing.expectEqual(modal.Normal.State{}, result.body.normal);
}
test "generated result replacement cancels an in-progress body selection" {
@@ -2665,7 +2665,7 @@ const OutputTests = struct {
try std.testing.expect(p.drag == .none);
p.update(.{ .mouse = .{ .button = config.select_button, .kind = .release, .col = x + 2, .row = y + 1 } });
for (result.sel) |selection| try std.testing.expectEqual(.none, selection.state);
- try std.testing.expect(!result.vsel.active and !result.msel.active);
+ try std.testing.expect(!result.body.vsel.active and !result.body.msel.active);
}
test "dump origins accept only builtins that actually own output panes" {
@@ -2993,8 +2993,8 @@ const TerminalTests = struct {
gpa.free(sn.style);
};
- for ([_]pardes.Pane.Mode{ .tty, .normal }, 0..) |mode, i| {
- pane.mode = mode;
+ for ([_]panes.Text.Mode{ .tty, .normal }, 0..) |mode, i| {
+ pane.body.mode = mode;
p.shell_rows.stale = true;
_ = frame.reset(.retain_capacity);
const s = try p.render(frame.allocator());
@@ -3204,7 +3204,7 @@ const TerminalTests = struct {
while (p.nextEffect()) |_| {}
const pane = p.panes[0].?;
pane.tty_filter = false;
- pane.mode = .normal;
+ pane.body.mode = .normal;
p.update(.{ .output = .{ .pane = 0, .bytes = "\x1b[31mAAA\x1b[0m\r\n\x1b[32mBBB\x1b[0m\r\n\x1b[34mCCC\x1b[0m" } });
@@ -3254,7 +3254,7 @@ const TerminalTests = struct {
while (p.nextEffect()) |_| {}
const pane = p.panes[0].?;
pane.tty_filter = false;
- pane.mode = .normal;
+ pane.body.mode = .normal;
// A ONE-cell prompt carrying a combining mark — an NFD `e` — then `ABC`
// typed at it. The cell walk that finds the prompt's end must step ONE
@@ -3290,7 +3290,7 @@ const TerminalTests = struct {
// Raw palette, so a leaked background reads back as `.index` — the theme
// filter would repaint every blank cell and hide the evidence.
pane.tty_filter = false;
- pane.mode = .normal;
+ pane.body.mode = .normal;
// Sixty rows, each a distinct background, so a leaked colour names the row
// it leaked from.
@@ -3346,7 +3346,7 @@ const TerminalTests = struct {
while (p.nextEffect()) |_| {}
const pane = p.panes[0].?;
pane.tty_filter = false;
- pane.mode = .normal;
+ pane.body.mode = .normal;
p.update(.{ .output = .{ .pane = 0, .bytes = "\x1b[31mAAA\x1b[0m\r\n\x1b[32mBBB\x1b[0m\r\n\x1b[34mCCC\x1b[0m" } });
@@ -3383,7 +3383,7 @@ const TerminalTests = struct {
while (p.nextEffect()) |_| {}
const pane = p.panes[0].?;
pane.tty_filter = false;
- pane.mode = .normal;
+ pane.body.mode = .normal;
p.update(.{ .output = .{ .pane = 0, .bytes = "\x1b[31mAAA\x1b[0m\r\n\x1b[32mBBB\x1b[0m\r\n\x1b[34mCCC\x1b[0m" } });
@@ -3459,7 +3459,7 @@ const TerminalTests = struct {
while (p.nextEffect()) |_| {}
const pane = p.panes[0].?;
pane.tty_filter = filter;
- pane.mode = .normal;
+ pane.body.mode = .normal;
var buf: [256]u8 = undefined;
const bytes = try std.fmt.bufPrint(
@@ -3539,7 +3539,7 @@ const TerminalTests = struct {
while (p.nextEffect()) |_| {}
const pane = p.panes[0].?;
pane.tty_filter = false;
- pane.mode = .tty;
+ pane.body.mode = .tty;
for (0..60) |i| {
var buf: [40]u8 = undefined;
@@ -3598,13 +3598,13 @@ const TerminalTests = struct {
// ABSOLUTE assertions: both modes were wrong identically here, so a
// tty/normal differential says nothing.
for ([_]bool{ false, true }) |filter| {
- for ([_]pardes.Pane.Mode{ .tty, .normal }) |mode| {
+ for ([_]panes.Text.Mode{ .tty, .normal }) |mode| {
const p = try Pardes.init(testing.allocator, .{ .tty_only = true, .cols = 12, .rows = 8 });
defer p.deinit();
while (p.nextEffect()) |_| {}
const pane = p.panes[0].?;
pane.tty_filter = filter;
- pane.mode = mode;
+ pane.body.mode = mode;
p.update(.{ .output = .{ .pane = 0, .bytes = "\x1b[32m\u{754C}\x1b[41m\x1b[K\x1b[7G\x1b[44m\x1b[K\r\n" } });
var frame = std.heap.ArenaAllocator.init(testing.allocator);
@@ -3634,13 +3634,13 @@ const TerminalTests = struct {
// ghostty leaves a `spacer_head` in that last column, carrying the row's
// background, and wraps the glyph to the next row. A head OWNS its column,
// so skipping it the way a tail is skipped left the row's final column bare.
- for ([_]pardes.Pane.Mode{ .tty, .normal }) |mode| {
+ for ([_]panes.Text.Mode{ .tty, .normal }) |mode| {
const p = try Pardes.init(testing.allocator, .{ .startup_config = "Theme helix\n", .tty_only = true, .cols = 16, .rows = 8 });
defer p.deinit();
while (p.nextEffect()) |_| {}
const pane = p.panes[0].?;
pane.tty_filter = false;
- pane.mode = mode;
+ pane.body.mode = mode;
p.update(.{ .output = .{ .pane = 0, .bytes = "\x1b[41mzzzzzzzzzzzzz\u{754C}\x1b[0m\r\n" } });
var frame = std.heap.ArenaAllocator.init(testing.allocator);
@@ -3667,7 +3667,7 @@ const TerminalTests = struct {
while (p.nextEffect()) |_| {}
const pane = p.panes[0].?;
pane.tty_filter = false;
- pane.mode = .tty;
+ pane.body.mode = .tty;
for (0..40) |i| {
var buf: [64]u8 = undefined;
const bytes = std.fmt.bufPrint(&buf, "\x1b[38;5;{d}mline-{d:0>2}\x1b[0m\r\n", .{ 20 + i, i }) catch unreachable;
@@ -3717,7 +3717,7 @@ const TerminalTests = struct {
while (p.nextEffect()) |_| {}
const pane = p.panes[0].?;
pane.tty_filter = filter;
- pane.mode = .normal;
+ pane.body.mode = .normal;
var frame = std.heap.ArenaAllocator.init(testing.allocator);
defer frame.deinit();
@@ -3749,7 +3749,7 @@ const TerminalTests = struct {
while (p.nextEffect()) |_| {}
const pane = p.panes[0].?;
pane.tty_filter = false;
- pane.mode = .normal;
+ pane.body.mode = .normal;
for (0..6) |i| {
var buf: [40]u8 = undefined;
@@ -3791,7 +3791,7 @@ const TerminalTests = struct {
while (p.nextEffect()) |_| {}
const pane = p.panes[0].?;
pane.tty_filter = false;
- pane.mode = .normal;
+ pane.body.mode = .normal;
p.update(.{ .output = .{ .pane = 0, .bytes = "\x1b[31m000\x1b[0m\r\n\x1b[32m111\x1b[0m\r\n\r\n\x1b[34m333\x1b[0m\r\n\x1b[35m444\x1b[0m" } });
@@ -3825,7 +3825,7 @@ const TerminalTests = struct {
while (p.nextEffect()) |_| {}
const pane = p.panes[0].?;
pane.tty_filter = false;
- pane.mode = .tty;
+ pane.body.mode = .tty;
p.update(.{ .output = .{ .pane = 0, .bytes = "\x1b[31mAAA\x1b[0m\r\n\x1b[32mBBB\x1b[0m\r\n\x1b[34mCCC\x1b[0m" } });
@@ -3862,7 +3862,7 @@ const TerminalTests = struct {
while (p.nextEffect()) |_| {}
const pane = p.panes[0].?;
pane.tty_filter = false;
- pane.mode = .normal;
+ pane.body.mode = .normal;
for (0..6) |i| {
var buf: [64]u8 = undefined;
const bytes = std.fmt.bufPrint(&buf, "\x1b[38;5;{d}mrow-{d}-abcdefgh\x1b[0m\r\n", .{ 30 + i, i }) catch unreachable;
@@ -3912,7 +3912,7 @@ const TerminalTests = struct {
while (p.nextEffect()) |_| {}
const pane = p.panes[0].?;
pane.tty_filter = false;
- pane.mode = .normal;
+ pane.body.mode = .normal;
for (0..26) |i| {
var buf: [64]u8 = undefined;
const bytes = std.fmt.bufPrint(&buf, "\x1b[38;5;{d}mrow-{d:0>2}-xyzzy\x1b[0m\r\n", .{ 20 + i, i }) catch unreachable;
@@ -3971,7 +3971,7 @@ const TerminalTests = struct {
// The raw palette, so a row's text names its exact colour instead of one
// this test would have to re-derive from the theme.
pane.tty_filter = false;
- pane.mode = .normal;
+ pane.body.mode = .normal;
for (0..26) |i| {
var buf: [64]u8 = undefined;
const bytes = std.fmt.bufPrint(&buf, "\x1b[38;5;{d}mrow-{d:0>2}-xyzzy\x1b[0m\r\n", .{ 20 + i, i }) catch unreachable;
@@ -4059,7 +4059,7 @@ const TerminalTests = struct {
while (p.nextEffect()) |_| {}
const pane = p.panes[0].?;
pane.tty_filter = false;
- pane.mode = .normal;
+ pane.body.mode = .normal;
for (0..26) |i| {
var buf: [64]u8 = undefined;
const bytes = std.fmt.bufPrint(&buf, "\x1b[38;5;{d}mrow-{d:0>2}-xyzzy\x1b[0m\r\n", .{ 20 + i, i }) catch unreachable;
@@ -4130,9 +4130,9 @@ test "an empty counted paste leaves no count for the next motion" {
const pane = try p.setTestFile("abcdefgh\n");
if (empty_register) p.yank = try p.gpa.dupe(u8, "");
for ("3p") |cp| p.update(.{ .key = .{ .cp = cp } });
- try std.testing.expectEqual(modal.Normal.State{}, pane.normal);
+ try std.testing.expectEqual(modal.Normal.State{}, pane.body.normal);
p.update(.{ .key = .{ .cp = 'l' } });
- try std.testing.expectEqual(@as(i32, 1), pane.cur_col);
+ try std.testing.expectEqual(@as(i32, 1), pane.body.cur_col);
try std.testing.expectEqualStrings("abcdefgh\n", pane.file.?.content);
}
}
@@ -4156,7 +4156,7 @@ test "cancelled normal gestures leave no count or subprefix after mouse and focu
defer frame.deinit();
_ = try p.render(frame.allocator());
for (keys) |cp| p.update(.{ .key = .{ .cp = cp } });
- try std.testing.expect(!std.meta.eql(modal.Normal.State{}, pane.normal));
+ try std.testing.expect(!std.meta.eql(modal.Normal.State{}, pane.body.normal));
switch (gesture) {
.body, .tag => {
const rect = p.rects[0];
@@ -4185,10 +4185,10 @@ test "cancelled normal gestures leave no count or subprefix after mouse and focu
try std.testing.expectEqual(@as(usize, 0), p.active);
},
}
- try std.testing.expectEqual(modal.Normal.State{}, pane.normal);
- const col = pane.cur_col;
+ try std.testing.expectEqual(modal.Normal.State{}, pane.body.normal);
+ const col = pane.body.cur_col;
p.update(.{ .key = .{ .cp = 'l' } });
- try std.testing.expectEqual(col + 1, pane.cur_col);
+ try std.testing.expectEqual(col + 1, pane.body.cur_col);
try std.testing.expectEqualStrings("abcdefghij\n", pane.file.?.content);
}
}
@@ -4199,16 +4199,16 @@ test "cancelled normal gestures leave no count or subprefix through raw tty mode
const p = try Pardes.init(std.testing.allocator, .{ .tty_only = true, .cols = 80, .rows = 12 });
defer p.deinit();
const pane = p.panes[0].?;
- pane.mode = .normal;
+ pane.body.mode = .normal;
p.update(.{ .output = .{ .pane = 0, .bytes = "abcdefghij\r\n" } });
for (keys) |cp| p.update(.{ .key = .{ .cp = cp } });
- try std.testing.expect(!std.meta.eql(modal.Normal.State{}, pane.normal));
+ try std.testing.expect(!std.meta.eql(modal.Normal.State{}, pane.body.normal));
p.update(.{ .key = .{ .cp = p.opts.tty_toggle, .ctrl = true } });
- try std.testing.expectEqual(pardes.Pane.Mode.tty, pane.mode);
- try std.testing.expectEqual(modal.Normal.State{}, pane.normal);
+ try std.testing.expectEqual(panes.Text.Mode.tty, pane.body.mode);
+ try std.testing.expectEqual(modal.Normal.State{}, pane.body.normal);
p.update(.{ .key = .{ .cp = p.opts.tty_toggle, .ctrl = true } });
- try std.testing.expectEqual(pardes.Pane.Mode.normal, pane.mode);
- try std.testing.expectEqual(modal.Normal.State{}, pane.normal);
+ try std.testing.expectEqual(panes.Text.Mode.normal, pane.body.mode);
+ try std.testing.expectEqual(modal.Normal.State{}, pane.body.normal);
}
}
@@ -4333,8 +4333,8 @@ test "Zig keywords keep every rendered byte colored across line-number widths" {
gpa.free(file.path);
file.path = try gpa.dupe(u8, "/highlight.zig");
file.scroll = line - 1;
- pane.cur_row = @intCast(line - 1);
- pane.cur_col = @intCast(std.mem.indexOf(u8, sample, "fn").?);
+ pane.body.cur_row = @intCast(line - 1);
+ pane.body.cur_col = @intCast(std.mem.indexOf(u8, sample, "fn").?);
pane.hscroll = view.horizontal;
p.settings.colors = true;
p.settings.wrap = view.wrap;
@@ -4373,8 +4373,8 @@ test "Zig keywords keep every rendered byte colored across line-number widths" {
const clicked = if_position.?;
p.update(.{ .mouse = .{ .button = config.select_button, .kind = .press, .col = clicked.x, .row = clicked.y } });
p.update(.{ .mouse = .{ .button = config.select_button, .kind = .release, .col = clicked.x, .row = clicked.y } });
- try std.testing.expectEqual(@as(i32, @intCast(line - 1)), pane.cur_row);
- try std.testing.expectEqual(@as(i32, @intCast(std.mem.indexOf(u8, sample, "if").?)), pane.cur_col);
+ try std.testing.expectEqual(@as(i32, @intCast(line - 1)), pane.body.cur_row);
+ try std.testing.expectEqual(@as(i32, @intCast(std.mem.indexOf(u8, sample, "if").?)), pane.body.cur_col);
}
}
}
@@ -4389,7 +4389,7 @@ test "terminal overlays preserve trailing blank styles without coloring inserted
const pane = p.panes[0].?;
pane.tty_filter = false;
p.update(.{ .output = .{ .pane = 0, .bytes = "A\r\n\x1b[41m\x1b[2K\r\n\x1b[42m\x1b[2K\r\n\x1b[44m\x1b[2K\x1b[0m" } });
- pane.mode = .normal;
+ pane.body.mode = .normal;
pane.ovl = .{ .row = 0, .rows = 3, .text = try gpa.dupe(u8, "A\n\n") };
var frame = std.heap.ArenaAllocator.init(gpa);
defer frame.deinit();
@@ -4421,16 +4421,16 @@ test "terminal overlays preserve trailing blank styles without coloring inserted
const LookResetTests = struct {
fn seed(pane: *Pane, operand: []const u8) !void {
- pane.cur_row = 0;
- pane.cur_col = 3;
- pane.vsel = .{ .active = true, .explicit = true, .row = 0, .col = 0 };
- pane.msel = .{ .active = true, .r0 = 0, .r1 = 1 };
- pane.sels[0] = .{ .row = 1, .col = 2, .arow = 0, .acol = 1 };
- pane.nsel = 1;
- pane.select = true;
- pane.normal.count = 5;
- pane.append_at = .{ .row = 0, .col = 3 };
- pane.sticky_col = 7;
+ pane.body.cur_row = 0;
+ pane.body.cur_col = 3;
+ pane.body.vsel = .{ .active = true, .explicit = true, .row = 0, .col = 0 };
+ pane.body.msel = .{ .active = true, .r0 = 0, .r1 = 1 };
+ pane.body.sels[0] = .{ .row = 1, .col = 2, .arow = 0, .acol = 1 };
+ pane.body.nsel = 1;
+ pane.body.select = true;
+ pane.body.normal.count = 5;
+ pane.body.append_at = .{ .row = 0, .col = 3 };
+ pane.body.sticky_col = 7;
for (0..pane.sel.len) |slot| {
pane.clearPointerSelection(slot);
pane.sel[slot] = .{ .state = .done, .source_id = slot + 1, .r0 = 1, .r1 = 1, .c0 = 0, .c1 = 3 };
@@ -4445,21 +4445,21 @@ const LookResetTests = struct {
}
fn cleared(pane: *const Pane) !void {
- try std.testing.expect(!pane.msel.active);
- try std.testing.expectEqual(@as(u8, 0), pane.nsel);
- try std.testing.expect(!pane.select);
- try std.testing.expectEqual(modal.Normal.State{}, pane.normal);
- try std.testing.expect(pane.append_at == null);
- try std.testing.expectEqual(@as(i32, -1), pane.sticky_col);
+ try std.testing.expect(!pane.body.msel.active);
+ try std.testing.expectEqual(@as(u8, 0), pane.body.nsel);
+ try std.testing.expect(!pane.body.select);
+ try std.testing.expectEqual(modal.Normal.State{}, pane.body.normal);
+ try std.testing.expect(pane.body.append_at == null);
+ try std.testing.expectEqual(@as(i32, -1), pane.body.sticky_col);
for (pane.sel) |selection| try std.testing.expectEqual(.none, selection.state);
for (pane.pointer_selections) |selection| try std.testing.expect(selection == null);
}
fn selected(pane: *const Pane) []const u8 {
- if (!pane.vsel.active or pane.cur_row != pane.vsel.row) return "";
- const line = modal.lineSlice(pane.file.?.content, @intCast(pane.cur_row));
- const lo: usize = @intCast(@min(pane.cur_col, pane.vsel.col));
- const hi: usize = @intCast(@max(pane.cur_col, pane.vsel.col));
+ if (!pane.body.vsel.active or pane.body.cur_row != pane.body.vsel.row) return "";
+ const line = modal.lineSlice(pane.file.?.content, @intCast(pane.body.cur_row));
+ const lo: usize = @intCast(@min(pane.body.cur_col, pane.body.vsel.col));
+ const hi: usize = @intCast(@max(pane.body.cur_col, pane.body.vsel.col));
return line[lo..modal.nextGrapheme(line, hi)];
}
@@ -4472,14 +4472,14 @@ const LookResetTests = struct {
pardes.look.lookAt(p, 0, pane.pointer_selections[0].?.raw_text.?);
try cleared(pane);
try std.testing.expectEqual(@as(usize, 0), p.active);
- try std.testing.expectEqual(@as(i32, 2), pane.cur_row);
- try std.testing.expectEqual(@as(i32, 1), pane.cur_col);
- try std.testing.expect(!pane.vsel.active);
+ try std.testing.expectEqual(@as(i32, 2), pane.body.cur_row);
+ try std.testing.expectEqual(@as(i32, 1), pane.body.cur_col);
+ try std.testing.expect(!pane.body.vsel.active);
try seed(pane, "/test.txt:2:2-4");
pardes.look.lookAt(p, 0, pane.pointer_selections[0].?.raw_text.?);
try cleared(pane);
- try std.testing.expectEqual(@as(i32, 1), pane.cur_row);
+ try std.testing.expectEqual(@as(i32, 1), pane.body.cur_row);
try std.testing.expectEqualStrings("rav", selected(pane));
p.gpa.free(pane.file.?.path);
@@ -4487,7 +4487,7 @@ const LookResetTests = struct {
try seed(pane, "needle");
pardes.look.lookAt(p, 0, pane.pointer_selections[0].?.raw_text.?);
try cleared(pane);
- try std.testing.expectEqual(@as(i32, 3), pane.cur_row);
+ try std.testing.expectEqual(@as(i32, 3), pane.body.cur_row);
try std.testing.expectEqualStrings("needle", selected(pane));
}
@@ -4512,14 +4512,14 @@ const LookResetTests = struct {
try std.testing.expectEqual(id, p.active);
try cleared(source);
try cleared(destination);
- try std.testing.expect(!source.vsel.active);
+ try std.testing.expect(!source.body.vsel.active);
if (range) {
- try std.testing.expectEqual(@as(i32, 1), destination.cur_row);
+ try std.testing.expectEqual(@as(i32, 1), destination.body.cur_row);
try std.testing.expectEqualStrings("rav", selected(destination));
} else {
- try std.testing.expectEqual(@as(i32, 2), destination.cur_row);
- try std.testing.expectEqual(@as(i32, 1), destination.cur_col);
- try std.testing.expect(!destination.vsel.active);
+ try std.testing.expectEqual(@as(i32, 2), destination.body.cur_row);
+ try std.testing.expectEqual(@as(i32, 1), destination.body.cur_col);
+ try std.testing.expect(!destination.body.vsel.active);
}
}
}