summaryrefslogtreecommitdiff
path: root/src/pardes.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/pardes.zig')
-rw-r--r--src/pardes.zig42
1 files changed, 38 insertions, 4 deletions
diff --git a/src/pardes.zig b/src/pardes.zig
index 5c6d2422..ec743bc6 100644
--- a/src/pardes.zig
+++ b/src/pardes.zig
@@ -13387,7 +13387,7 @@ pub const Pardes = struct {
s.previous_tag_layers = &.{};
s.cell_diffs = &.{};
const chrome = p.chromeTheme();
- const th = p.theme(); // the message row paints in the editor's colours
+ const th = p.theme();
// Separators have their own role; a scrollbar need not frame the page.
s.fill(0, 0, s.cols, s.rows, .{ .bg = .{ .rgb = chrome.border } });
@@ -13407,9 +13407,14 @@ pub const Pardes = struct {
const r = p.rects[id];
const tx = r.x + config.GUTTER;
const tw = r.w - config.GUTTER;
+ // Painted the way the sticky context headers above them are: the
+ // tagline font and the tagline's own colours, so a notice reads as
+ // a band belonging to the pane rather than as a line of body text
+ // that happens to sit at the bottom of it.
const msg_style: CellStyle = .{
- .fg = if (th.fg) |c| .{ .rgb = c } else .default,
- .bg = if (th.bg) |c| .{ .rgb = c } else .default,
+ .fg = .{ .rgb = chrome.tag_fg },
+ .bg = .{ .rgb = chrome.tag_bg },
+ .font_role = .tagline,
};
// The stack sits directly above the tagline, one line to a row, in
// the order collectNotices chose. A single notice therefore lands
@@ -13417,7 +13422,7 @@ pub const Pardes = struct {
const bottom = if (p.settings.tag_bottom) r.y + r.h - 1 - BOX_H else r.y + r.h - 1;
for (pane.notices.slice(), 0..) |kind, i| {
const row = bottom - @as(u16, @intCast(pane.notices.len - 1 - i));
- s.fill(tx, row, tw, 1, .{ .bg = msg_style.bg });
+ s.fill(tx, row, tw, 1, .{ .bg = msg_style.bg, .font_role = .tagline });
switch (kind) {
.message => _ = s.print(tx, row, tw, pane.msg[0..pane.msg_len], msg_style),
.leader => {
@@ -14634,6 +14639,35 @@ test "Esc back into a tty leaves its view at the prompt" {
try std.testing.expectEqual(live, sp.terminal.?.vt.screens.active.pages.scrollbar().offset);
}
+test "a builtin announces itself on the message row, and Verbose silences it" {
+ if (platform == .web) return;
+ const p = try Pardes.init(std.testing.allocator, .{ .tty_only = true, .cols = 80, .rows = 24 });
+ defer p.deinit();
+ const pane = p.panes[p.active].?;
+
+ p.sync();
+ try std.testing.expect(p.settings.verbose);
+ // Wrap, not Collapse: a builtin that folds its own pane away leaves no row
+ // for its announcement, which is correct and not what this is testing.
+ try std.testing.expect(p.executeBuiltinLine(p.active, "Wrap"));
+ try std.testing.expectEqualStrings("Wrap", pane.msg[0..pane.msg_len]);
+
+ // The notice list is what the paint pass reads, so the announcement has to
+ // reach it, not just the buffer.
+ p.collectNotices(pane, p.rects[p.active], p.active);
+ try std.testing.expect(pane.notices.len > 0);
+ try std.testing.expectEqual(Pane.Notices.Kind.message, pane.notices.kinds[0]);
+
+ // Msg owns the row itself, so it does not announce over its own text.
+ try std.testing.expect(p.executeBuiltinLine(p.active, "Msg hello"));
+ try std.testing.expectEqualStrings("hello", pane.msg[0..pane.msg_len]);
+
+ pane.msg_len = 0;
+ p.settings.verbose = false;
+ try std.testing.expect(p.executeBuiltinLine(p.active, "Wrap"));
+ try std.testing.expectEqual(@as(u16, 0), pane.msg_len);
+}
+
test "closing the last pane in a column leaves an empty one in its place" {
if (platform == .web) return;
const p = try Pardes.init(std.testing.allocator, .{ .tty_only = true, .cols = 120, .rows = 24 });