diff options
| author | Gabriel Schneider <[email protected]> | 2026-09-29 10:31:15 -0300 |
|---|---|---|
| committer | Gabriel Schneider <[email protected]> | 2026-10-01 00:12:16 -0300 |
| commit | 5fd713889b6bdeb27c58941b77266c9336bf7b7d (patch) | |
| tree | 8b8ad1c1a0beb814aa3ad63a8790b554fb09c599 | |
| parent | 2d0c506583d18d6f004fc117282deb2faea1d17e (diff) | |
| download | pardes-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.md | 2 | ||||
| -rw-r--r-- | docs/config.md | 6 | ||||
| -rw-r--r-- | docs/design.typ | 2 | ||||
| -rw-r--r-- | docs/fs.md | 2 | ||||
| -rw-r--r-- | docs/helix-keys.md | 2 | ||||
| -rw-r--r-- | docs/macos.md | 2 | ||||
| -rw-r--r-- | docs/themes.md | 4 | ||||
| -rw-r--r-- | docs/ui-review.md | 4 | ||||
| -rw-r--r-- | src/Output.zig | 9 | ||||
| -rw-r--r-- | src/builtins.zig | 4 | ||||
| -rw-r--r-- | src/colors.zig | 2 | ||||
| -rw-r--r-- | src/config.zig | 4 | ||||
| -rw-r--r-- | src/exec.zig | 28 | ||||
| -rw-r--r-- | src/ninep/ctl.zig | 4 | ||||
| -rw-r--r-- | test/appearance_gallery.py | 8 | ||||
| -rw-r--r-- | test/output.zig | 10 | ||||
| -rw-r--r-- | test/snapshots/themesel.golden | 2 | ||||
| -rw-r--r-- | test/snapshots/themesel.snap | 2 |
18 files changed, 62 insertions, 35 deletions
@@ -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 @@ -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 |
