summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-09-29 10:31:15 -0300
committerGabriel Schneider <[email protected]>2026-10-01 00:12:16 -0300
commit5fd713889b6bdeb27c58941b77266c9336bf7b7d (patch)
tree8b8ad1c1a0beb814aa3ad63a8790b554fb09c599
parent2d0c506583d18d6f004fc117282deb2faea1d17e (diff)
downloadpardes-5fd713889b6bdeb27c58941b77266c9336bf7b7d.tar.gz
pardes-5fd713889b6bdeb27c58941b77266c9336bf7b7d.zip
ThemeSel is Themes and FontSel is Fonts; the old words still work in init files and dumps
The user asked for the plainer words. Every use is renamed: the builtins, leader paths, /commands, the docs and tutor, tests, and the themesel golden, re-recorded. An init file's ThemeSel or FontSel runs the new word and says `ThemeSel: renamed to Themes`, as ColumnTags is said; a dump naming an output pane by the old word restores it. Co-Authored-By: Claude Opus 5.5 <[email protected]>
-rw-r--r--README.md2
-rw-r--r--docs/config.md6
-rw-r--r--docs/design.typ2
-rw-r--r--docs/fs.md2
-rw-r--r--docs/helix-keys.md2
-rw-r--r--docs/macos.md2
-rw-r--r--docs/themes.md4
-rw-r--r--docs/ui-review.md4
-rw-r--r--src/Output.zig9
-rw-r--r--src/builtins.zig4
-rw-r--r--src/colors.zig2
-rw-r--r--src/config.zig4
-rw-r--r--src/exec.zig28
-rw-r--r--src/ninep/ctl.zig4
-rw-r--r--test/appearance_gallery.py8
-rw-r--r--test/output.zig10
-rw-r--r--test/snapshots/themesel.golden2
-rw-r--r--test/snapshots/themesel.snap2
18 files changed, 62 insertions, 35 deletions
diff --git a/README.md b/README.md
index 826f86c8..d7548e8c 100644
--- a/README.md
+++ b/README.md
@@ -16,7 +16,7 @@ diagnostics and embedded terminal: `orchard` (the near-black default), `dusk`,
`daybreak` provide high contrast dark and light choices. Six classic-inspired
adaptations add `forge`, `lagoon`, `solarium`, `spectrum`, `harvest`, and `clay`.
`forge_black` and `orchard_black` offer pure-black variations; `forge_soft`
-offers a deliberately softer contrast. Execute `ThemeSel` to choose native
+offers a deliberately softer contrast. Execute `Themes` to choose native
themes first, followed by the existing legacy/imported collection. `FocusTint` toggles
the active pane and column tag tints (on by default), and `SyntaxBold` toggles bold
syntax keywords (off by default), in both GUI and TTY.
diff --git a/docs/config.md b/docs/config.md
index 96281cd5..9d7446f1 100644
--- a/docs/config.md
+++ b/docs/config.md
@@ -96,7 +96,7 @@ The SDL GUI also has `WindowOpacity`, which takes one argument.
`builtins.Board.enabled` holds, and that build has no config file.)
`Theme <name>` wants one of the names in the compiled ring. Do not derive the
-spelling — read it off `ThemeSel` (`SPC t t`), which lists every one as the
+spelling — read it off `Themes` (`SPC t t`), which lists every one as the
exact `Theme <name>` line that selects it. `slug` in `tools/gen_themes.zig`
lowercases, folds punctuation runs to a single `_` and then TRIMS leading and
trailing ones (`penumbra+.toml` is `penumbra`, not `penumbra_`), and every
@@ -109,7 +109,7 @@ project gains or loses a file. A name that is not in the ring is ignored.
The fifteen [native Pardes themes](themes.md) lead the ring: `orchard` (the
default), `dusk`, `ink`, `paper`, `daybreak`, `atelier`, `forge`, `lagoon`,
`solarium`, `spectrum`, `harvest`, `clay`, `forge_black`, `forge_soft`, and
-`orchard_black`. `ThemeSel` lists them first under Pardes themes, followed by
+`orchard_black`. `Themes` lists them first under Pardes themes, followed by
a separate legacy/imported section. They add coordinated
focus, search, diagnostic and terminal colors; `ink` and `daybreak` are high
contrast dark and light options. The original `helix`, `dark` and `acme`
@@ -391,7 +391,7 @@ asked for one. Neither reaches the child as a keystroke, so an application
that would otherwise answer Ctrl-V by reading the system clipboard itself
never gets the chance to read the wrong thing.
-`Font` and `FontSel` exist ONLY in the SDL GUI and native macOS builds — a
+`Font` and `Fonts` exist ONLY in the SDL GUI and native macOS builds — a
terminal's font belongs to its emulator and a browser's to the page — so a
`Font` line is one of the silently-ignored ones everywhere else. Both builds
resolve the name by walking the font directories on every lookup, so a face
diff --git a/docs/design.typ b/docs/design.typ
index 639884a9..ed2bbb94 100644
--- a/docs/design.typ
+++ b/docs/design.typ
@@ -2010,7 +2010,7 @@ one pair per theme, and the three per-button tints and the dimmed extra cursors
are mixed off it, so what stays fixed is the distinction between buttons and not
the colours. `NextColor` browses the ring one
step at a time — at 228 it is no longer how you REACH one —
-`Theme <name>` jumps to one and `ThemeSel` (`SPC t t`) lists them all into an
+`Theme <name>` jumps to one and `Themes` (`SPC t t`) lists them all into an
output buffer whose rows are those very commands — execute a row (Tab, middle
click) and the theme goes on; n/N select such a row WHOLE, since a command
line holds no place to pick out of it — the third grain of that motion, the
diff --git a/docs/fs.md b/docs/fs.md
index dedfe94f..ceca1dd9 100644
--- a/docs/fs.md
+++ b/docs/fs.md
@@ -274,7 +274,7 @@ argument to a builtin that takes none, or none to one that needs it (`Msg`,
`Mount`, `Find`, a setting's value but a switch's, which flips bare);
`bad value in control message "X"` for a setting's value it does not take
(for `Theme`, naming the themes that share the name's first letter, since
-all of them, `ThemeSel`'s list, are too many for an error);
+all of them, `Themes`'s list, are too many for an error);
and `not a session control message "X": write it to pane/<n>/ctl` or `not
a window control message "X": write it to /ctl` for a word of the other ctl. 9ns maps them all to EINVAL, and a write
refused here has done nothing. A line that then fails as it runs fails the
diff --git a/docs/helix-keys.md b/docs/helix-keys.md
index 5d89ba92..b1035ad6 100644
--- a/docs/helix-keys.md
+++ b/docs/helix-keys.md
@@ -135,7 +135,7 @@ language-backend queries, and the shell pipe.
| `SPC y` `SPC Y` `SPC p` `SPC P` `SPC R` | helix's clipboard menu on helix's own letters: yank the selection to the system clipboard (`ClipYank`) or the PRIMARY selection alone (`ClipYankMain`), paste the system clipboard after (`ClipPaste`) / before (`ClipPasteBefore`) the selection, replace the selection with it (`ClipReplace`) | the same as `"+y`, `"+p`, `"+P`, `"+R`: register `+` (and `*`) IS the desktop's clipboard, the only register that reaches it. `SPC y` writes `+` alone, as helix's does, not the default register too. Builtins rather than bare chords because a leader path names a builtin: they land in Help's index and are executable words like every other verb. The clipboard holds one text, so N values go out joined by newlines, as helix sends them. On a tty the write is OSC 52 out and the READ is OSC 52 back, which many terminals refuse or gate — so `SPC y` works there and `SPC p` can be a no-op | out of corpus |
| a paste from the OUTER terminal | one `Event.paste`, spliced in at the cursor | the tty shell enables bracketed paste and coalesces `paste_start`..`paste_end` into a single event; before that the bytes arrived as individual key presses and normal mode RAN them, which is how a pasted `d` deleted a line. The bytes deliberately never enter the yank register — clipboard and default register are separate stores in both directions | pardes-specific |
| `/` (any pane) | pardes' own plain-substring search into a `+Search` output buffer: the pattern is typed on a line of its own on the pane's notice band, Enter fills the buffer, and its rows are ordinary look targets. Enter also GOES to the first row — the buffer is focused and then the step `n` is and the look Enter is run in it (`Pardes.lookFirstHit`), so `/foo` lands on the first hit with the matched span selected. A pattern that matched nothing opens its empty buffer and moves nothing | KEEP, do not touch; not in the corpus (helix `/` is regex search). Find and Grep answer with OTHER files and deliberately do NOT jump. The stepping half is the next row | pardes-specific |
-| `n` / `N` (any pane) | MOTION, not a jump: move the SELECTION to the next / previous look-able text and open NOTHING. Enter — the look chord — on what it leaves selected is what opens it | KEEP, do not touch; not in the corpus (helix's `n`/`N` walk regex search hits). What a step selects is the pane's GRAIN (`output_pane.Grain`, read in `Pardes.lookSpanIn`): in FREE TEXT — a terminal, a file, a PDF, a prose answer buffer — the largest whitespace-delimited run `look.resolve` can act on (`look.lookableSpan`, wrapper punctuation peeled off both ends), several to a line; in a RESULTS BUFFER one stop per ROW, the largest run its head resolves as (`look.lookableLineSpan`), because a row there IS one location and the words after it are the match rather than a second place to go; in a COMMAND list the whole line. The walk is a RING across PANES: every pane that has performed a Look, most recent first (`Pardes.look_src`), then the output buffers that have not, newest first, and only when both are empty the active pane. Exhausting a pane enters the next at its first (forward) / last (backward) span and the end wraps to the start, so `N` is the exact inverse of `n`. What it lands on becomes an EXPLICIT `vsel` with the cursor on its FIRST column, in the pane the walk focuses. ONE motion in every pane kind and every buffer kind — a PDF steps the `+Search` buffer its own search filled, `n` to select the row and Enter to jump. The single thing a buffer may change is that grain, and it changes it by BEING a kind of buffer rather than by a branch: `output_pane.Traits.steps` (a list of locations) makes a step take one row at a time, and `Traits.commands` makes it take the WHOLE LINE, because a command list (`ThemeSel`/`FontSel`) holds words to run and there is no path inside `Theme gruvbox` to pick out. Tab on what `n` selected wears the theme, which is the same middle click on the row is. `]d`/`[d` are helix's diagnostic motions, a different binding, and they do still jump to each diagnostic (`docs/lsp.md`) | pardes-specific |
+| `n` / `N` (any pane) | MOTION, not a jump: move the SELECTION to the next / previous look-able text and open NOTHING. Enter — the look chord — on what it leaves selected is what opens it | KEEP, do not touch; not in the corpus (helix's `n`/`N` walk regex search hits). What a step selects is the pane's GRAIN (`output_pane.Grain`, read in `Pardes.lookSpanIn`): in FREE TEXT — a terminal, a file, a PDF, a prose answer buffer — the largest whitespace-delimited run `look.resolve` can act on (`look.lookableSpan`, wrapper punctuation peeled off both ends), several to a line; in a RESULTS BUFFER one stop per ROW, the largest run its head resolves as (`look.lookableLineSpan`), because a row there IS one location and the words after it are the match rather than a second place to go; in a COMMAND list the whole line. The walk is a RING across PANES: every pane that has performed a Look, most recent first (`Pardes.look_src`), then the output buffers that have not, newest first, and only when both are empty the active pane. Exhausting a pane enters the next at its first (forward) / last (backward) span and the end wraps to the start, so `N` is the exact inverse of `n`. What it lands on becomes an EXPLICIT `vsel` with the cursor on its FIRST column, in the pane the walk focuses. ONE motion in every pane kind and every buffer kind — a PDF steps the `+Search` buffer its own search filled, `n` to select the row and Enter to jump. The single thing a buffer may change is that grain, and it changes it by BEING a kind of buffer rather than by a branch: `output_pane.Traits.steps` (a list of locations) makes a step take one row at a time, and `Traits.commands` makes it take the WHOLE LINE, because a command list (`Themes`/`Fonts`) holds words to run and there is no path inside `Theme gruvbox` to pick out. Tab on what `n` selected wears the theme, which is the same middle click on the row is. `]d`/`[d` are helix's diagnostic motions, a different binding, and they do still jump to each diagnostic (`docs/lsp.md`) | pardes-specific |
| insert: printable text | file: real edit; terminal: typed run splice | | helix-verified (file) |
| insert: `Enter` | newline; keeps the current full indent levels and adds one 4-space logical tab when the text before the cursor ends in `(`, `[`, `{`, or `)` (including `})`) | plain lines match `insert_newline`; delimiter heuristic is pardes-specific | helix-verified (plain) / pardes-specific (delimiter) |
| insert: `Backspace` (+ `Shift-Backspace`) | delete prev char, joins lines at col 0; in a line's leading blanks, back to the previous 4-column indent stop (a whole unit when on one; a tab still goes alone) | matches `delete_char_backward` and its dedent; `Ctrl-h` alias in B | helix-verified |
diff --git a/docs/macos.md b/docs/macos.md
index cf7091e6..8bb81be6 100644
--- a/docs/macos.md
+++ b/docs/macos.md
@@ -495,7 +495,7 @@ has none:
The face is the shell's business and the size is the window's, so the two are
reached differently on purpose.
-`Font <name>` and the `FontSel` picker are ordinary core builtins, enabled by
+`Font <name>` and the `Fonts` picker are ordinary core builtins, enabled by
`pardes.font_picker` — the frontends that draw their own text, which is now the
SDL shell and this one. `src/fonts.zig` moved out of `gui/` for that reason. It
walks the platform's font directories and reads four small sfnt tables per file
diff --git a/docs/themes.md b/docs/themes.md
index 38596819..5349a764 100644
--- a/docs/themes.md
+++ b/docs/themes.md
@@ -3,11 +3,11 @@
Pardes ships fifteen native palettes: six originals, six classic-inspired
adaptations and three contrast variants, designed for tags, text, search, diagnostics and embedded
terminals together. `orchard` is the initial theme.
-Execute `Theme <name>` anywhere, or open `ThemeSel` with `SPC t t` and select
+Execute `Theme <name>` anywhere, or open `Themes` with `SPC t t` and select
a theme's command. Put the same command in your [startup configuration](config.md)
to keep a preference. `NextColor` cycles through the native themes first,
then the retained `helix`, `dark` and `acme` themes and imported palettes.
-`ThemeSel` groups the new palettes under `Pardes themes`, followed by
+`Themes` groups the new palettes under `Pardes themes`, followed by
`Legacy and imported themes`; its navigation skips the section headings.
See the [Agave visual review](ui-review.md) for the original six-palette gallery.
diff --git a/docs/ui-review.md b/docs/ui-review.md
index 1180a20e..decf042d 100644
--- a/docs/ui-review.md
+++ b/docs/ui-review.md
@@ -12,7 +12,7 @@ and silver-blue chrome. `forge_black` and `orchard_black` use pure black;
`forge_soft` joins `dusk`, `lagoon` and `solarium` as deliberately softer
alternatives. Light and Acme-inspired choices remain available.
-`ThemeSel` opens with the native collection, followed by a separate legacy
+`Themes` opens with the native collection, followed by a separate legacy
and imported section. Keyboard navigation skips both section headings.
`Collapse` now transfers all released rows to one expanded pane, preferring
@@ -36,7 +36,7 @@ sent to the user's session.
- [Six contrast studies, OS screenshot crops](screenshots/theme-preferences.png)
- [Neutral Forge, full workspace](screenshots/theme-preferences-forge.png)
-- [Native-first ThemeSel, full workspace](screenshots/theme-selector.png)
+- [Native-first Themes, full workspace](screenshots/theme-selector.png)
## Compact rails, classic palettes and workspace pets
diff --git a/src/Output.zig b/src/Output.zig
index dd6ab92a..a75718bf 100644
--- a/src/Output.zig
+++ b/src/Output.zig
@@ -250,6 +250,9 @@ pub fn fromWord(w: []const u8) ?Origin {
if (std.mem.eql(u8, w, "/")) return .search;
if (std.mem.eql(u8, w, config.errors_buffer)) return .errors;
if (std.mem.eql(u8, w, config.pdf_links_buffer)) return .pdf_links;
+ // A dump from before the rename names them by their old words.
+ if (std.mem.eql(u8, w, "ThemeSel")) return .{ .cmd = .Themes };
+ if (builtins.capabilities.font_picker) if (std.mem.eql(u8, w, "FontSel")) return .{ .cmd = .Fonts };
if (std.meta.stringToEnum(Builtin, w)) |b|
if (builtins.registry.outputTraits(b) != null) return .{ .cmd = b };
if (std.meta.stringToEnum(lsp.Kind, w)) |k| return .{ .query = k };
@@ -591,13 +594,13 @@ pub fn openThemes(p: *Pardes, id: usize) !void {
try out.writer.print(comptime config.Runtime.findAction(.theme).?.word ++ " {s}\n", .{t.name});
}
const content = try out.toOwnedSlice();
- try openStepped(p, id, .{ .cmd = .ThemeSel }, content);
+ try openStepped(p, id, .{ .cmd = .Themes }, content);
}
pub fn isWalkRow(file: *const File.State, row: usize, line: []const u8) bool {
const state = file.output orelse return true;
if (usesLocationsConfig(state.from)) return isResultRow(file, row);
- if (!std.meta.eql(state.from, Origin{ .cmd = .ThemeSel })) return true;
+ if (!std.meta.eql(state.from, Origin{ .cmd = .Themes })) return true;
// Section labels are for reading, not stops in the command walk.
return std.mem.startsWith(u8, std.mem.trimStart(u8, line, " \t"), comptime config.Runtime.findAction(.theme).?.word ++ " ");
}
@@ -611,7 +614,7 @@ pub fn openFonts(p: *Pardes, id: usize) !void {
for (font_list) |f|
try out.writer.print(comptime config.Runtime.findAction(.font).?.word ++ " {s}\n", .{f.name});
const content = try out.toOwnedSlice();
- try openStepped(p, id, .{ .cmd = .FontSel }, content);
+ try openStepped(p, id, .{ .cmd = .Fonts }, content);
}
}
diff --git a/src/builtins.zig b/src/builtins.zig
index 2247fcbb..041eb1b8 100644
--- a/src/builtins.zig
+++ b/src/builtins.zig
@@ -741,7 +741,7 @@ pub const NextColor = struct {
};
/// List the themes in a pane, each a word to click.
-pub const ThemeSel = struct {
+pub const Themes = struct {
pub const scope: Scope = .session;
pub const output: OutputTraits = .{ .name = config.themes_buffer, .steps = true, .commands = true };
pub fn run(c: Ctx) void {
@@ -779,7 +779,7 @@ pub const DumpThemes = struct {
};
/// List the fonts in a pane, each a word to click.
-pub const FontSel = struct {
+pub const Fonts = struct {
pub const scope: Scope = .session;
pub const output: OutputTraits = .{ .name = config.fonts_buffer, .steps = true, .commands = true };
pub const enabled = capabilities.font_picker;
diff --git a/src/colors.zig b/src/colors.zig
index 8319a112..5694998d 100644
--- a/src/colors.zig
+++ b/src/colors.zig
@@ -559,7 +559,7 @@ fn invalidateThemeDependentRasters(p: *Pardes) void {
}
/// Themes whose names share `name`'s first letter, a line of them, for a
-/// Theme given a name there is none of: all of them (ThemeSel) are too many
+/// Theme given a name there is none of: all of them (Themes) are too many
/// for a message or a refused write.
pub fn themesNear(buf: []u8, name: []const u8) []const u8 {
var w = std.Io.Writer.fixed(buf);
diff --git a/src/config.zig b/src/config.zig
index c7ea5411..2b5bf280 100644
--- a/src/config.zig
+++ b/src/config.zig
@@ -88,7 +88,7 @@ pub const leader_path = paths: {
.Wrap = "tw",
.Tagbottom = "tb",
.NextColor = "tn",
- .ThemeSel = "tt",
+ .Themes = "tt",
.Theme = null,
.Shell = null,
.Petscii = "tp",
@@ -109,7 +109,7 @@ pub const leader_path = paths: {
.Exec = null,
});
if (builtins.capabilities.font_picker) {
- table.set(.FontSel, "tf");
+ table.set(.Fonts, "tf");
table.set(.Font, null);
table.set(.TaglineSize, null);
}
diff --git a/src/exec.zig b/src/exec.zig
index 60c4172d..1fc38b9c 100644
--- a/src/exec.zig
+++ b/src/exec.zig
@@ -811,11 +811,35 @@ pub fn applyStartupConfig(p: *Pardes) void {
if (executeBuiltinLine(p, p.active, line)) continue;
// A setting pardes no longer has is said, once, and changes nothing.
const word = commandText(line);
- if (std.mem.eql(u8, word[0 .. std.mem.indexOfAny(u8, word, " \t") orelse word.len], "ColumnTags"))
+ const head = word[0 .. std.mem.indexOfAny(u8, word, " \t") orelse word.len];
+ if (std.mem.eql(u8, head, "ColumnTags"))
p.setMessage(p.active, "ColumnTags: column tags are always shown now; the init line is ignored");
+ // A word renamed runs as its new name, and says so, once a line.
+ for ([_][2][]const u8{ .{ "ThemeSel", "Themes" }, .{ "FontSel", "Fonts" } }) |renamed| if (std.mem.eql(u8, head, renamed[0])) {
+ _ = executeBuiltinLine(p, p.active, renamed[1]);
+ var said: [64]u8 = undefined;
+ p.setMessage(p.active, std.fmt.bufPrint(&said, "{s}: renamed to {s}", .{ renamed[0], renamed[1] }) catch "renamed");
+ };
}
}
+test "an init file's ThemeSel runs as Themes and says it was renamed" {
+ const p = try Pardes.init(std.testing.allocator, .{ .tty_only = true, .cols = 80, .rows = 24 });
+ defer p.deinit();
+ p.opts.startup_config = "ThemeSel\n";
+ applyStartupConfig(p);
+ var listed = false;
+ for (p.panes) |slot| if (slot) |pane| if (pane.file) |f| if (f.output) |o| {
+ listed = listed or std.meta.eql(o.from, panes.Output.Origin{ .cmd = .Themes });
+ };
+ try std.testing.expect(listed);
+ var said = false;
+ for (p.panes) |slot| if (slot) |pane| {
+ said = said or std.mem.eql(u8, pane.msg[0..pane.msg_len], "ThemeSel: renamed to Themes");
+ };
+ try std.testing.expect(said);
+}
+
test "an init file's retired ColumnTags line is said and ignored" {
const p = try Pardes.init(std.testing.allocator, .{ .tty_only = true, .cols = 80, .rows = 24 });
defer p.deinit();
@@ -873,7 +897,7 @@ pub fn applySettingBuiltin(p: *Pardes, setting: config.Runtime.Setting, arg: ?[]
if (!p.announce) return;
var near: [96]u8 = undefined;
var text: [200]u8 = undefined;
- return p.reportFailure(p.active, std.fmt.bufPrint(&text, "Theme: no theme \"{s}\"; like it: {s}; ThemeSel lists all", .{ want[0..@min(want.len, 40)], colors.themesNear(&near, want) }) catch "Theme: no such theme");
+ return p.reportFailure(p.active, std.fmt.bufPrint(&text, "Theme: no theme \"{s}\"; like it: {s}; Themes lists all", .{ want[0..@min(want.len, 40)], colors.themesNear(&near, want) }) catch "Theme: no such theme");
},
.font => {
if (comptime !font_picker) return;
diff --git a/src/ninep/ctl.zig b/src/ninep/ctl.zig
index 22a0923b..18a7eaa9 100644
--- a/src/ninep/ctl.zig
+++ b/src/ninep/ctl.zig
@@ -414,7 +414,7 @@ fn checkBuiltin(p: *Pardes, req: Req, line: []const u8, scope: builtins.Scope) ?
// `refuse` quotes the line after it, in what is left of 128.
var near: [40]u8 = undefined;
var why: [104]u8 = undefined;
- return refuse(p, req, std.fmt.bufPrint(&why, "bad value in control message; like it: {s}; ThemeSel lists all", .{pardes.colors.themesNear(&near, arg)}) catch "bad value in control message", line);
+ return refuse(p, req, std.fmt.bufPrint(&why, "bad value in control message; like it: {s}; Themes lists all", .{pardes.colors.themesNear(&near, arg)}) catch "bad value in control message", line);
},
.font => config.Runtime.FontSpec.parse(arg) != null,
else => probe: {
@@ -1093,7 +1093,7 @@ test "the root ctl reads the settings as a write takes them, and takes the sessi
try testing.expectEqualStrings("bad value in control message; takes acme, pardes \"Placement east\"", wr(p, root_ctl, "Placement east").reply.ename);
const no_theme = wr(p, root_ctl, "Theme no-such-theme").reply.ename;
try testing.expectStringStartsWith(no_theme, "bad value in control message; like it: n");
- try testing.expect(std.mem.endsWith(u8, no_theme, "; ThemeSel lists all \"Theme no-such-theme\""));
+ try testing.expect(std.mem.endsWith(u8, no_theme, "; Themes lists all \"Theme no-such-theme\""));
try testing.expectEqualStrings("wrong #args in control message \"Newcol 2\"", wr(p, root_ctl, "Newcol 2").reply.ename);
try testing.expectEqualStrings("wrong #args in control message \"Theme\"", wr(p, root_ctl, "Theme").reply.ename);
// A bare required word fails the check, so the line before never runs.
diff --git a/test/appearance_gallery.py b/test/appearance_gallery.py
index bc9a7570..46b17dd9 100644
--- a/test/appearance_gallery.py
+++ b/test/appearance_gallery.py
@@ -51,7 +51,7 @@ Orchard: crisp woodland color
Dusk: intentionally soft and warm
Theme dusk
-ThemeSel: Pardes themes come first.
+Themes: Pardes themes come first.
'''
@@ -159,16 +159,16 @@ def run(args):
if args.theme_selector:
command(client, terminal, 'Collapse')
before = set(panes(client))
- command(client, right, 'ThemeSel')
+ command(client, right, 'Themes')
selector = require(wait_for(lambda: next((s for s in panes(client) if s not in before), None)),
- 'ThemeSel missing')
+ 'Themes missing')
body = client.read(f'/pane/{selector}/body').decode()
native, legacy = body.split('# Legacy and imported themes', 1)
for theme in ('forge_black', 'forge_soft', 'orchard_black'):
require('Theme ' + theme + '\n' in native, 'native contrast variant below legacy heading')
require('Theme helix\n' in legacy, 'legacy theme section missing')
require('Theme orchard' in ''.join(c[0] for c in client.screen()['cells']),
- 'ThemeSel did not open at native first entry')
+ 'Themes did not open at native first entry')
take_frame('theme-selector')
report['native_themes_first'] = True
client.write(f'/pane/{selector}/exec', b'Del\n')
diff --git a/test/output.zig b/test/output.zig
index 478f1b4a..21c02e0a 100644
--- a/test/output.zig
+++ b/test/output.zig
@@ -952,13 +952,13 @@ test "N exactly reverses n across output panes and the ring seam" {
try std.testing.expect(saw_first and saw_second);
}
-test "ThemeSel groups native themes first and skips headings in both directions" {
+test "Themes groups native themes first and skips headings in both directions" {
const p = try Pardes.init(std.testing.allocator, .{ .tty_only = true, .cols = 100, .rows = 40 });
defer p.deinit();
const source = try p.setTestFile("notes\n");
pardes.colors.setThemeIndex(p, pardes.themes.len - 1);
const original_theme = p.settings.theme;
- try std.testing.expect(p.executeBuiltinLine(0, "ThemeSel"));
+ try std.testing.expect(p.executeBuiltinLine(0, "Themes"));
const tid = source.search_pane orelse return error.MissingThemeList;
const list = p.panes[tid].?;
const content = list.file.?.content;
@@ -979,12 +979,12 @@ test "ThemeSel groups native themes first and skips headings in both directions"
for (pardes.themes[0 .. pardes.native_theme_count + 1]) |theme| {
p.update(.{ .key = .{ .cp = 'n' } });
try std.testing.expectEqual(tid, p.active);
- const selected = selectedOutputText(list) orelse return error.MissingThemeSelection;
+ const selected = selectedOutputText(list) orelse return error.MissingThemesection;
try std.testing.expectEqualStrings(theme.name, selected["Theme ".len..]);
try std.testing.expectEqual(original_theme, p.settings.theme);
}
p.update(.{ .key = .{ .cp = 'N' } });
- const previous = selectedOutputText(list) orelse return error.MissingThemeSelection;
+ const previous = selectedOutputText(list) orelse return error.MissingThemesection;
try std.testing.expectEqualStrings(pardes.themes[pardes.native_theme_count - 1].name, previous["Theme ".len..]);
p.update(.{ .key = .{ .cp = Key.tab } });
try std.testing.expectEqual(pardes.native_theme_count - 1, p.settings.theme);
@@ -999,7 +999,7 @@ test "n/N selects command outputs by whole row" {
defer p.deinit();
p.update(.{ .resize = .{ .cols = 100, .rows = 40 } });
- try std.testing.expect(p.executeBuiltinLine(p.active, "ThemeSel"));
+ try std.testing.expect(p.executeBuiltinLine(p.active, "Themes"));
const tid = p.panes[p.active].?.search_pane orelse return error.MissingThemeList;
const themes = p.panes[tid].?;
try std.testing.expect(panes.Output.fileTraits(themes.file.?.output).commands);
diff --git a/test/snapshots/themesel.golden b/test/snapshots/themesel.golden
index 8d453978..92e641f5 100644
--- a/test/snapshots/themesel.golden
+++ b/test/snapshots/themesel.golden
@@ -31,7 +31,7 @@
| 27 line 27
| 28 line 28
== snap list grid=100x31 cursor=7,3
-|3: 1 line 1 ThemeSel
+|3: 1 line 1 Themes
|16: /tmp/pardes-snap/themesel/cwd/+Themes Save Tty Collapse Del
|17: 1 # Pardes themes
|18: 2 Theme orchard
diff --git a/test/snapshots/themesel.snap b/test/snapshots/themesel.snap
index 04a95d23..2b7b03c4 100644
--- a/test/snapshots/themesel.snap
+++ b/test/snapshots/themesel.snap
@@ -1,7 +1,7 @@
# RULE: a results buffer is a list of things you can RUN, and its traits say
# what a ROW IS. Every list before this one held LOCATIONS — a row with a
# `path:LINE:COL` word inside it — so n/N select that word and Enter Looks it.
-# `SPC t t` (ThemeSel) opens the first one whose rows are COMMANDS: `Theme
+# `SPC t t` (Themes) opens the first one whose rows are COMMANDS: `Theme
# <name>`, exactly the line you would type, with no path in it to pick out, so
# n/N select the WHOLE ROW. One motion, two grains, and the same split either
# way — the step only SELECTS, and Tab (Exec, or the middle button, which is