diff options
Diffstat (limited to 'src/tui_components.zig')
| -rw-r--r-- | src/tui_components.zig | 64 |
1 files changed, 36 insertions, 28 deletions
diff --git a/src/tui_components.zig b/src/tui_components.zig index a9648ee..1ce5b56 100644 --- a/src/tui_components.zig +++ b/src/tui_components.zig @@ -1580,7 +1580,7 @@ pub const CompactionSummary = struct { /// component holds no global state. pub const ToolUse = struct { /// Number of trailing output lines shown when collapsed. - pub const collapsed_tail_lines: usize = 5; + pub const collapsed_tail_lines: usize = 8; alloc: std.mem.Allocator, cache: RenderCache, @@ -1854,8 +1854,9 @@ test "AssistantText: renders wrapped text within width" { // renderBlock adds 2 margin lines: 3 content + 2 = 5. try testing.expectEqual(@as(usize, 5), lines.len); for (lines) |l| try testing.expect(vw(l) <= 7); - // First render after empty cache => changed from 0. - try testing.expectEqual(@as(?usize, 0), at.comp().firstLineChanged()); + // After a render the cache is clean, so the live signal is null. (The + // first-render diff index 0 is retained internally in changed_from.) + try testing.expectEqual(@as(?usize, null), at.comp().firstLineChanged()); } test "AssistantText: streaming keeps firstLineChanged near the tail, not 0" { @@ -2530,24 +2531,33 @@ test "ToolUse: stage 2 shows name + verbatim json + placeholder" { for (lines) |l| try testing.expect(vw(l) <= 60); } -test "ToolUse: collapsed shows only the last 5 output lines (default)" { +test "ToolUse: collapsed shows only the last collapsed_tail_lines output lines (default)" { var t = ToolUse.init(testing.allocator); defer t.deinit(); try t.setName("read"); try t.setInput("{}"); - // 8 short output lines -> collapsed shows the marker + last 5. - try t.setOutput("l1\nl2\nl3\nl4\nl5\nl6\nl7\nl8"); + // 12 short output lines -> collapsed shows the marker + the last + // collapsed_tail_lines (8) of them, eliding l1..l4. + try t.setOutput("l1\nl2\nl3\nl4\nl5\nl6\nl7\nl8\nl9\nl10\nl11\nl12"); const collapsed = try t.comp().render(40, testing.allocator); - // margin+pad+header+sep+marker+l4..l8+pad+margin = 1+1+1+1+1+5+1+1 = 12 - // Last output line (l8) is at lines[len-3] (before bottom pad + margin). - try testing.expect(std.mem.indexOf(u8, collapsed[collapsed.len - 3], "l8") != null); - try testing.expect(std.mem.indexOf(u8, collapsed[collapsed.len - 7], "l4") != null); - // The earliest output lines are elided when collapsed. - var has_l1 = false; + // margin+pad+header+sep+marker+(tail lines)+pad+margin + // = 1+1+1+1+1+collapsed_tail_lines+1+1 = 7 + collapsed_tail_lines + try testing.expectEqual(@as(usize, 7 + ToolUse.collapsed_tail_lines), collapsed.len); + // Last output line (l12) is at lines[len-3] (before bottom pad + margin); + // the first SHOWN tail line is at lines[len-3-(tail-1)]. + // Tokens are rendered as " l<n>" followed by right-padding, so match on a + // trailing space to avoid "l1" spuriously matching inside "l10".."l12". + try testing.expect(std.mem.indexOf(u8, collapsed[collapsed.len - 3], "l12 ") != null); + try testing.expect(std.mem.indexOf(u8, collapsed[collapsed.len - 3 - (ToolUse.collapsed_tail_lines - 1)], "l5 ") != null); + // The earliest output lines (l1..l4) are elided when collapsed. + var has_elided = false; for (collapsed) |l| { - if (std.mem.indexOf(u8, l, "l1") != null) has_l1 = true; + if (std.mem.indexOf(u8, l, "l1 ") != null or + std.mem.indexOf(u8, l, "l2 ") != null or + std.mem.indexOf(u8, l, "l3 ") != null or + std.mem.indexOf(u8, l, "l4 ") != null) has_elided = true; } - try testing.expect(!has_l1); + try testing.expect(!has_elided); // Expanding shows everything. t.setCollapsed(false); @@ -2555,7 +2565,7 @@ test "ToolUse: collapsed shows only the last 5 output lines (default)" { try testing.expect(expanded.len > collapsed.len); var has_l1_exp = false; for (expanded) |l| { - if (std.mem.indexOf(u8, l, "l1") != null) has_l1_exp = true; + if (std.mem.indexOf(u8, l, "l1 ") != null) has_l1_exp = true; } try testing.expect(has_l1_exp); } @@ -2620,33 +2630,31 @@ test "ToolUse: collapse/expand is a length change with a cache-derived firstLine defer t.deinit(); try t.setName("read"); try t.setInput("{}"); - try t.setOutput("l1\nl2\nl3\nl4\nl5\nl6\nl7\nl8"); + // 12 output lines, so collapsing (tail = collapsed_tail_lines = 8) truncates. + try t.setOutput("l1\nl2\nl3\nl4\nl5\nl6\nl7\nl8\nl9\nl10\nl11\nl12"); // Default collapsed: - // margin+pad+header+sep+truncmark+5lines+pad+margin = 1+1+1+1+1+5+1+1 = 12 + // margin+pad+header+sep+truncmark+8lines+pad+margin = 1+1+1+1+1+8+1+1 = 15 const collapsed = try t.comp().render(40, testing.allocator); - try testing.expectEqual(@as(usize, 12), collapsed.len); - // A stable re-render is clean (cache-derived, no drift). + try testing.expectEqual(@as(usize, 15), collapsed.len); + // A stable re-render is clean: the live signal is null. _ = try t.comp().render(40, testing.allocator); try testing.expectEqual(@as(?usize, null), t.comp().firstLineChanged()); - // Expand: margin+pad+header+sep+8lines+pad+margin = 1+1+1+1+8+1+1 = 14 + // Expand: margin+pad+header+sep+12lines+pad+margin = 1+1+1+1+12+1+1 = 18 t.setCollapsed(false); // While dirty (full drop), the signal is the cache-derived 0. try testing.expectEqual(@as(?usize, 0), t.comp().firstLineChanged()); const expanded = try t.comp().render(40, testing.allocator); - try testing.expectEqual(@as(usize, 14), expanded.len); - // After the render the baseline was dropped on the toggle, so the diff - // reports from 0 — cache-derived, not a hand-managed value. - try testing.expectEqual(@as(?usize, 0), t.comp().firstLineChanged()); - // Stable re-render is clean again. - _ = try t.comp().render(40, testing.allocator); + try testing.expectEqual(@as(usize, 18), expanded.len); + // After the render the cache is clean, so the live signal is null again + // (the toggle's drop-from-0 diff is internal bookkeeping, not a live cut). try testing.expectEqual(@as(?usize, null), t.comp().firstLineChanged()); - // Collapse again: shrink back to 12 rows. + // Collapse again: shrink back to 15 rows. t.setCollapsed(true); const recollapsed = try t.comp().render(40, testing.allocator); - try testing.expectEqual(@as(usize, 12), recollapsed.len); + try testing.expectEqual(@as(usize, 15), recollapsed.len); } test "ToolUse: args are rendered VERBATIM (no pretty-print) and within width" { |
