diff options
| author | Gabriel Schneider <[email protected]> | 2026-09-28 00:42:04 -0300 |
|---|---|---|
| committer | Gabriel Schneider <[email protected]> | 2026-10-01 00:12:14 -0300 |
| commit | 425d9beb9c977df364ed83743cb2efdef9429478 (patch) | |
| tree | eaba2e20ff041b50539d1b47fdeb498e59237cf0 /test/panes.zig | |
| parent | 1912878e753ce12fdc1ac72ae2e83ddfc18df002 (diff) | |
| download | pardes-425d9beb9c977df364ed83743cb2efdef9429478.tar.gz pardes-425d9beb9c977df364ed83743cb2efdef9429478.zip | |
File the tag code into tagline.zig and draw tags beside bodies
With tags reduced to Texts, what is left of them is the computed prefix, the
default and saved tails, entering and leaving a tag and the headers: that goes
to tagline.zig, as acme keeps the tag half of a window in wind.c. Tag and
header drawing moves next to body drawing in body_layer.zig, and the tag hit
helpers go to tag_layer.zig with the Hit they read, where sameCell now also
tells the lines of a taller tag apart. The docs describe the tag as a Text.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Diffstat (limited to 'test/panes.zig')
| -rw-r--r-- | test/panes.zig | 50 |
1 files changed, 25 insertions, 25 deletions
diff --git a/test/panes.zig b/test/panes.zig index 4804c497..954e431b 100644 --- a/test/panes.zig +++ b/test/panes.zig @@ -15,7 +15,7 @@ const filesystem = pardes.filesystem; /// The tag's caret as a byte offset into the tag as it is shown, prefix /// included. fn tagCaret(p: *Pardes, pane: *Pane) !usize { - return (try p.tagPrefix(pane)).len + @as(usize, @intCast(pane.tag.cur_col)); + return (try pardes.tagline.tagPrefix(p, pane)).len + @as(usize, @intCast(pane.tag.cur_col)); } fn setTag(pane: *Pane, text: []const u8) !void { @@ -52,7 +52,7 @@ const TagLayerTests = struct { defer frame.deinit(); _ = try p.render(frame.allocator()); const layer = try findLayer(p, .pane, 0); - const text = try p.tagText(frame.allocator(), pane); + const text = try pardes.tagline.tagText(p, frame.allocator(), pane); const at = std.mem.indexOf(u8, text, "END").?; const col = panes.File.displayWidth(text[0..at]); try std.testing.expect(col > p.rects[0].w); @@ -70,7 +70,7 @@ const TagLayerTests = struct { try std.testing.expectEqual(at, try tagCaret(p, pane)); p.update(.{ .key = .{ .cp = 'X', .text = "X" } }); _ = try p.render(frame.allocator()); - const edited = try p.tagText(frame.allocator(), pane); + const edited = try pardes.tagline.tagText(p, frame.allocator(), pane); try std.testing.expect(std.mem.endsWith(u8, edited, "界 XEND")); try std.testing.expectEqual(@as(u16, 0), pane.tag_scroll); try std.testing.expectEqualStrings("body\n", pane.file.?.content); @@ -140,7 +140,7 @@ const TagLayerTests = struct { try setTag(left, " " ++ "a" ** 110); _ = try p.render(frame.allocator()); const left_layer = try findLayer(p, .pane, 0); - const left_text = try p.tagText(frame.allocator(), left); + const left_text = try pardes.tagline.tagText(p, frame.allocator(), left); const start_x = @as(f32, @floatFromInt(left_layer.viewport.x)) * 10 + 12.5; const beyond_x = edge + 12.5; p.update(.{ .mouse = mouse(left_layer, start_x, .press) }); @@ -161,7 +161,7 @@ const TagLayerTests = struct { const x = @as(f32, @floatFromInt(header.viewport.x)) * 10 + 62.5 * 5; p.update(.{ .mouse = mouse(header, x, .press) }); p.update(.{ .mouse = mouse(header, x, .release) }); - try std.testing.expectEqual(@as(i32, 63), p.focusedHeader().?.cur_col); + try std.testing.expectEqual(@as(i32, 63), pardes.tagline.focusedHeader(p).?.cur_col); if (kind == .column) try std.testing.expectEqual(@as(?usize, 1), p.header_column) else try std.testing.expect(p.header_column == null); p.update(.{ .key = .{ .cp = Key.escape } }); } @@ -184,7 +184,7 @@ test "a tag with a newline in it is as tall as its lines, and each line is typed p.update(.{ .key = .{ .cp = 'A' } }); p.update(.{ .key = .{ .cp = Key.enter } }); p.update(.{ .key = .{ .cp = 'S', .text = "Second" } }); - try std.testing.expect(std.mem.endsWith(u8, Pardes.curTail(pane), "\nSecond")); + try std.testing.expect(std.mem.endsWith(u8, pardes.tagline.curTail(pane), "\nSecond")); try std.testing.expectEqual(@as(u16, 2), pane.tag_rows); // The pane keeps its height; the body gives the tag its row. try std.testing.expectEqual(height, p.rects[0].h); @@ -252,7 +252,7 @@ const TagNavigationTests = struct { // Nothing to remember yet: `:` lands on Save, in normal mode. key(p, ':'); try std.testing.expect(first.focus == .tag and first.tag.mode == .normal); - const tail = Pardes.curTail(first); + const tail = pardes.tagline.curTail(first); try std.testing.expectEqualStrings("Save", tail[@intCast(first.tag.cur_col)..][0..4]); key(p, Key.home); for (0..3) |_| key(p, Key.right); @@ -278,7 +278,7 @@ const TagNavigationTests = struct { _ = try p.render(frame.allocator()); const rect = p.rects[0]; const y = if (p.settings.tag_bottom) rect.y + rect.h - pardes.BOX_H else rect.y; - const prefix: u16 = @intCast(panes.File.displayWidth(try p.tagPrefix(first))); + const prefix: u16 = @intCast(panes.File.displayWidth(try pardes.tagline.tagPrefix(p, first))); ClickCursorTests.click(p, .left, rect.x + pardes.TAG_TEXT_INSET + prefix + 6, y); try std.testing.expectEqual(@as(usize, 0), p.active); try std.testing.expect(first.focus == .tag and first.tag.mode == .insert); @@ -316,7 +316,7 @@ const TagNavigationTests = struct { try std.testing.expectEqual(chord == Key.tab, saved); // ...and the tag still knows where it was. key(p, ':'); - try std.testing.expectEqualStrings("Save", Pardes.curTail(pane)[@intCast(pane.tag.cur_col)..][0..4]); + try std.testing.expectEqualStrings("Save", pardes.tagline.curTail(pane)[@intCast(pane.tag.cur_col)..][0..4]); } } @@ -403,14 +403,14 @@ const TagNavigationTests = struct { key(p, ':'); key(p, 'i'); key(p, Key.end); - const before = Pardes.curTail(pane).len; + const before = pardes.tagline.curTail(pane).len; try std.testing.expect(pane.focus == .tag and pane.tag.mode == .insert and pane.body.mode == .normal); for ("hjklHJKL:") |letter| { const text = [_]u8{letter}; p.update(.{ .key = .{ .cp = letter, .text = &text } }); try std.testing.expect(pane.focus == .tag and pane.tag.mode == .insert); } - try std.testing.expectEqualStrings("hjklHJKL:", Pardes.curTail(pane)[before..]); + try std.testing.expectEqualStrings("hjklHJKL:", pardes.tagline.curTail(pane)[before..]); try std.testing.expectEqualStrings("body\n", pane.file.?.content); try std.testing.expectEqual(@as(usize, 0), p.active); } @@ -1187,7 +1187,7 @@ const TagNameTintTests = struct { var arena = std.heap.ArenaAllocator.init(p.gpa); defer arena.deinit(); const surface = try p.render(arena.allocator()); - const text = try p.tagText(arena.allocator(), pane); + const text = try pardes.tagline.tagText(p, arena.allocator(), pane); const base = std.mem.lastIndexOfScalar(u8, name, '/') orelse return error.MissingDirectory; const rect = p.rects[id]; const y = if (p.settings.tag_bottom) rect.y + rect.h - pardes.BOX_H else rect.y; @@ -1235,7 +1235,7 @@ const TagNameTintTests = struct { configure(p); defer p.custom_theme = null; const name = "/a/very/long/directory/that/extends/past/the/tag/界e\u{301}name-with-a-long-tail.zig"; - p.draftName(pane, 0); + pardes.tagline.draftName(p, pane, 0); redraft(pane, name); pane.input.cur_col = @intCast(std.mem.indexOf(u8, name, "界").?); try std.testing.expect((try check(p, 0, name)) > 0); @@ -1304,7 +1304,7 @@ test "pane filename drafts commit and cancel without changing body or command ta const original = try p.gpa.dupe(u8, pane.file.?.path); defer p.gpa.free(original); try pane.appendTag(" SyntaxBold"); - const tail = try p.gpa.dupe(u8, Pardes.curTail(pane)); + const tail = try p.gpa.dupe(u8, pardes.tagline.curTail(pane)); defer p.gpa.free(tail); for ([_]bool{ false, true }) |commit| { clickPathEnd(p, pane); @@ -1312,13 +1312,13 @@ test "pane filename drafts commit and cancel without changing body or command ta p.update(.{ .paste = "/new name.zig" }); try std.testing.expectEqualStrings(original, pane.file.?.path); try std.testing.expectEqualStrings("/new name.zig", pane.input.own.?); - try std.testing.expectEqualStrings(tail, Pardes.curTail(pane)); + try std.testing.expectEqualStrings(tail, pardes.tagline.curTail(pane)); try std.testing.expectEqualStrings("original body\n", pane.file.?.content); p.update(.{ .key = .{ .cp = if (commit) Key.enter else Key.escape } }); try std.testing.expect(pane.focus == .body); try std.testing.expect(pane.prompt == .none); try std.testing.expectEqualStrings(if (commit) "/new name.zig" else original, pane.file.?.path); - try std.testing.expectEqualStrings(tail, Pardes.curTail(pane)); + try std.testing.expectEqualStrings(tail, pardes.tagline.curTail(pane)); while (p.nextEffect()) |effect| try std.testing.expect(std.meta.activeTag(effect) != .save_file); } try std.testing.expect(pane.file.?.revision != pane.file.?.saved_revision); @@ -1351,13 +1351,13 @@ test "leaving a pane or entering a header cancels an uncommitted filename" { const pane = try p.setTestFile("untouched\n"); for ([_]bool{ false, true }) |header| { p.active = 0; - p.exitHeader(); + pardes.tagline.exitHeader(p); p.update(.tick); clickPathEnd(p, pane); p.update(.{ .paste = "/draft" }); try std.testing.expect(pane.prompt == .name); if (header) { - p.enterHeader(null); + pardes.tagline.enterHeader(p, null); p.update(.tick); } else { try std.testing.expect(p.executeBuiltinLine(0, "New")); @@ -1379,7 +1379,7 @@ test "middle clicking Save commits the drafted filename before issuing a save" { var arena = std.heap.ArenaAllocator.init(p.gpa); defer arena.deinit(); _ = try p.render(arena.allocator()); - const text = try p.tagText(arena.allocator(), pane); + const text = try pardes.tagline.tagText(p, arena.allocator(), pane); const save_at = std.mem.indexOf(u8, text, "Save").?; const x: u16 = @intCast(p.rects[0].x + pardes.TAG_TEXT_INSET + save_at - pane.tag_scroll); const y = p.rects[0].y; @@ -1421,15 +1421,15 @@ test "paste into pane commands and prompts never inserts into the body" { p.update(.{ .key = .{ .cp = 'A' } }); // A tag takes a paste as a body does, newline and all. p.update(.{ .paste = " Custom\nCommand" }); - try std.testing.expect(std.mem.indexOf(u8, Pardes.curTail(pane), " Custom\nCommand") != null); + try std.testing.expect(std.mem.indexOf(u8, pardes.tagline.curTail(pane), " Custom\nCommand") != null); p.update(.{ .key = .{ .cp = Key.escape } }); p.startPrompt(pane, .{ .search = config.search_marker }); p.update(.{ .paste = "t\r\nwo" }); try std.testing.expectEqualStrings(config.search_marker ++ "two", pane.promptText().?); - try std.testing.expect(std.mem.indexOf(u8, Pardes.curTail(pane), " Custom\nCommand") != null); + try std.testing.expect(std.mem.indexOf(u8, pardes.tagline.curTail(pane), " Custom\nCommand") != null); try std.testing.expectEqualStrings("one two one\n", pane.file.?.content); p.update(.{ .key = .{ .cp = Key.escape } }); - try std.testing.expect(std.mem.indexOf(u8, Pardes.curTail(pane), " Custom\nCommand") != null); + try std.testing.expect(std.mem.indexOf(u8, pardes.tagline.curTail(pane), " Custom\nCommand") != null); } test "long pane tags reveal commands and map visible clicks to whole tag addresses" { @@ -1446,7 +1446,7 @@ test "long pane tags reveal commands and map visible clicks to whole tag address const surface = try p.render(arena.allocator()); try std.testing.expect(pane.tag_scroll > 0); try std.testing.expect(surface.cursor.?.x < p.rects[0].x + p.rects[0].w); - const text = try p.tagText(p.gpa, pane); + const text = try pardes.tagline.tagText(p, p.gpa, pane); defer p.gpa.free(text); const offset = std.mem.indexOf(u8, text, "SyntaxBold").?; const x: u16 = @intCast(p.rects[0].x + pardes.TAG_TEXT_INSET + panes.File.rawDisplayCol(text, offset) - pane.tag_scroll); @@ -1455,7 +1455,7 @@ test "long pane tags reveal commands and map visible clicks to whole tag address p.update(.{ .mouse = .{ .col = x, .row = y, .button = config.exec_button, .kind = .press } }); p.update(.{ .mouse = .{ .col = x, .row = y, .button = config.exec_button, .kind = .release } }); try std.testing.expectEqual(!before, p.settings.syntax_bold); - try std.testing.expectEqualStrings(text, try p.tagText(p.scratch.allocator(), pane)); + try std.testing.expectEqualStrings(text, try pardes.tagline.tagText(p, p.scratch.allocator(), pane)); } test "terminal overlay recoloring never materializes unrelated history" { @@ -4155,7 +4155,7 @@ test "cancelled normal gestures leave no count or subprefix after mouse and focu const tag_y = if (p.settings.tag_bottom) rect.y + rect.h - pardes.BOX_H else rect.y; const body_y = p.bodyTop(pane, rect); const x = if (gesture == .tag) - rect.x + pardes.TAG_TEXT_INSET + @as(u16, @intCast(panes.File.displayWidth(try p.tagPrefix(pane)))) + 3 + rect.x + pardes.TAG_TEXT_INSET + @as(u16, @intCast(panes.File.displayWidth(try pardes.tagline.tagPrefix(p, pane)))) + 3 else rect.x + config.GUTTER + @as(u16, @intCast(panes.File.gutterWidth(pane))) + 3; const y = if (gesture == .tag) tag_y else body_y; |
