summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/config.md2
-rw-r--r--docs/tags.md5
-rw-r--r--docs/themes.md1
-rw-r--r--src/colors.zig4
-rw-r--r--src/draw.zig1
-rw-r--r--src/pardes.zig19
-rw-r--r--src/themes/acme.zig2
-rw-r--r--test/gui-goldens.txt2
8 files changed, 32 insertions, 4 deletions
diff --git a/docs/config.md b/docs/config.md
index 77ed68e7..c2e0b318 100644
--- a/docs/config.md
+++ b/docs/config.md
@@ -316,7 +316,7 @@ name, thirteen required RGB roles (`sel_bg`, `sel_fg`, `tag_bg`, `tag_fg`,
`box`, `box_dim`, `kw`, `str`, `num`, `comment`, `lineno`, `scroll_track`,
`scroll_thumb`), nullable `bg`/`fg`, and either a 16-color RGB `palette` or
`null`. Optional nullable RGB roles extend this format:
-`tag_active_bg`, `tag_active_fg`, `tag_name_fg`, `tag_active_name_fg`, `border`, `lineno_active`, `search_bg`, `search_fg`,
+`tag_active_bg`, `tag_active_fg`, `tag_name_fg`, `tag_active_name_fg`, `border`, `empty_col`, `lineno_active`, `search_bg`, `search_fg`,
`diagnostic_error`, `diagnostic_warning`, `diagnostic_info`, and
`diagnostic_hint`. Missing new roles use backward-compatible defaults, so
previously exported files remain valid. [Theme customization](themes.md)
diff --git a/docs/tags.md b/docs/tags.md
index 7787d7f1..26f3dcf0 100644
--- a/docs/tags.md
+++ b/docs/tags.md
@@ -172,8 +172,9 @@ underlines and the optional `SyntaxBold` keyword weight.
## Empty columns
-A column can hold no pane, as acme's can: its tag stands over blank space, the
-frame's own fill, where acme paints white (cols.c:186-188). `Newcol` makes an
+A column can hold no pane, as acme's can: its tag stands over blank space in
+the theme's `empty_col` colour, white in the acme theme as acme paints it
+(cols.c:186-188), and the frame's border fill in themes that do not set it. `Newcol` makes an
empty column right of the keyboard's and gives its tag the keyboard. Closing a
column's last pane (`Del`, `Del k`/`Del j`, a shell exiting, a drag to another
column) leaves the column empty where it was, and the keyboard goes to its tag
diff --git a/docs/themes.md b/docs/themes.md
index 8cc4ff9b..103a3f5a 100644
--- a/docs/themes.md
+++ b/docs/themes.md
@@ -108,6 +108,7 @@ so existing exported themes remain valid.
| `column_box` | Column grip while held, and its drag rail | `num` |
| `column_box_dim` | Column drag grip at rest, in every focus state | Equal mix of `column_box` and `tag_bg` |
| `border` | Quiet separators | `scroll_track` |
+| `empty_col` | A column with no pane, under its tag (acme: white) | `border` |
| `lineno_active` | Restrained current line number foreground | `lineno` |
| `search_bg`, `search_fg` | Search matches, independent of selection | `sel_bg`, `sel_fg` |
| `diagnostic_error` | Error text | `fg`, or `tag_fg` for an inherited foreground |
diff --git a/src/colors.zig b/src/colors.zig
index aeff7b00..401b77f1 100644
--- a/src/colors.zig
+++ b/src/colors.zig
@@ -54,6 +54,8 @@ pub const Theme = struct {
column_box: ?[3]u8 = null,
column_box_dim: ?[3]u8 = null,
border: ?[3]u8 = null,
+ /// What an empty column shows under its tag; the border fill without it.
+ empty_col: ?[3]u8 = null,
search_bg: ?[3]u8 = null,
search_fg: ?[3]u8 = null,
diagnostic_error: ?[3]u8 = null,
@@ -144,6 +146,7 @@ pub const ChromeTheme = struct {
tag_name_fg: [3]u8,
tag_active_name_fg: [3]u8,
border: [3]u8,
+ empty_col: [3]u8,
search_bg: [3]u8,
search_fg: [3]u8,
diagnostic_error: [3]u8,
@@ -167,6 +170,7 @@ pub const ChromeTheme = struct {
.tag_name_fg = th.tag_name_fg orelse th.tag_fg,
.tag_active_name_fg = th.tag_active_name_fg orelse (th.tag_name_fg orelse (th.tag_active_fg orelse th.tag_fg)),
.border = th.border orelse th.scroll_track,
+ .empty_col = th.empty_col orelse (th.border orelse th.scroll_track),
.search_bg = th.search_bg orelse th.sel_bg,
.search_fg = th.search_fg orelse th.sel_fg,
.diagnostic_error = th.diagnostic_error orelse (th.fg orelse th.tag_fg),
diff --git a/src/draw.zig b/src/draw.zig
index b12ab52c..8f2f95f9 100644
--- a/src/draw.zig
+++ b/src/draw.zig
@@ -189,6 +189,7 @@ pub fn render(p: *Pardes, arena: std.mem.Allocator) !*Surface {
// Separators have their own role; a scrollbar need not frame the page.
const whole = s.regions[0].rect;
s.fill(whole.x, whole.y, whole.w, whole.h, .{ .bg = .{ .rgb = chrome.border } });
+ for (0..p.ncol) |c| if (p.col_n[c] == 0) s.fill(p.col_x[c], p.topBarHeight() + p.columnBarHeight(), p.col_w[c], s.rows -| (p.topBarHeight() + p.columnBarHeight()), .{ .bg = .{ .rgb = chrome.empty_col } });
for (&p.panes, 0..) |*slot, id| {
const pane = slot.* orelse continue;
diff --git a/src/pardes.zig b/src/pardes.zig
index bad512a9..e3f4bb60 100644
--- a/src/pardes.zig
+++ b/src/pardes.zig
@@ -1317,6 +1317,25 @@ test "Placement pardes brings back the old rules, and says so in Config" {
try std.testing.expectEqual(config.Runtime.Placement.acme, p.settings.placement);
}
+test "an empty column shows its theme's empty_col under its tag: acme's white, else the border" {
+ const p = try Pardes.init(std.testing.allocator, .{ .tty_only = true, .cols = 120, .rows = 20 });
+ defer p.deinit();
+ p.newColumn(0);
+ tagline.exitHeader(p);
+ inline for (.{ "acme", "dark" }) |name| {
+ try std.testing.expect(p.executeBuiltinLine(0, "Theme " ++ name));
+ p.chrome_animation.displayed = colors.ChromeTheme.fromTheme(p.theme());
+ p.sync();
+ var arena: std.heap.ArenaAllocator = .init(std.testing.allocator);
+ defer arena.deinit();
+ const s = try p.render(arena.allocator());
+ const cell = s.at(p.col_x[1] + 3, p.screen_h - 2);
+ const want = p.chromeTheme().empty_col;
+ try std.testing.expectEqual(want, cell.style.bg.rgb);
+ if (std.mem.eql(u8, name, "acme")) try std.testing.expectEqual([3]u8{ 0xff, 0xff, 0xff }, want) else try std.testing.expectEqual(p.chromeTheme().border, want);
+ }
+}
+
test "dragging a column's only pane to another leaves that column in place, empty" {
const p = try Pardes.init(std.testing.allocator, .{ .tty_only = true, .cols = 160, .rows = 32 });
defer p.deinit();
diff --git a/src/themes/acme.zig b/src/themes/acme.zig
index d91e626b..693055d6 100644
--- a/src/themes/acme.zig
+++ b/src/themes/acme.zig
@@ -27,6 +27,8 @@ pub const theme = .{
.lineno = .{ 0x99, 0x99, 0x80 },
.scroll_track = .{ 0x99, 0x99, 0x4c },
.scroll_thumb = .{ 0xff, 0xff, 0xea },
+ // acme paints a column with no window white (cols.c:187).
+ .empty_col = .{ 0xff, 0xff, 0xff },
.palette = .{
.{ 0x00, 0x00, 0x00 }, .{ 0xaa, 0x22, 0x22 }, .{ 0x22, 0x80, 0x22 }, .{ 0x88, 0x66, 0x00 },
.{ 0x22, 0x44, 0xbb }, .{ 0x99, 0x33, 0x99 }, .{ 0x11, 0x88, 0x88 }, .{ 0x55, 0x55, 0x55 },
diff --git a/test/gui-goldens.txt b/test/gui-goldens.txt
index 78639bfc..9a8baf9c 100644
--- a/test/gui-goldens.txt
+++ b/test/gui-goldens.txt
@@ -14,4 +14,4 @@
15-theme-acme-light cdd8f24e67ed9940c4af3eaa5d54eb71c4fb0efb8fe48ce12368b72bbca90003
16-debug f6b3b93bc6ca178f1762b7f77857586861e105c51eb6202d519f7605fed523d8
17-terminal ea0d877ba228515f0ab7c10097486bf09318762c6e475c481fdbf478939d3a1b
-18-mid-transition 6100b892b4654594f9eb09fd105ce9639e99f7d145fee2f9c9986825d936785d
+18-mid-transition 9c84c5e27a7ecb063919aaef7a8d8a477e6b5b41909938f233b6cba859f8affc