summaryrefslogtreecommitdiff
path: root/src/config.zig
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-07-31 19:02:04 -0300
committerGabriel Schneider <[email protected]>2026-08-01 15:02:08 -0300
commit005178177a1ddb2eb2f1af5fad36e2717758ee8e (patch)
tree6e974c12def02fd855446d84db25232c1f3b4fd2 /src/config.zig
parent41847fce244fdd0d01971c302b89d1252f6497ed (diff)
downloadpardes-005178177a1ddb2eb2f1af5fad36e2717758ee8e.tar.gz
pardes-005178177a1ddb2eb2f1af5fad36e2717758ee8e.zip
the gui wears any monospace font on the machine
Diffstat (limited to 'src/config.zig')
-rw-r--r--src/config.zig180
1 files changed, 103 insertions, 77 deletions
diff --git a/src/config.zig b/src/config.zig
index 2603a40c..0db1d344 100644
--- a/src/config.zig
+++ b/src/config.zig
@@ -58,89 +58,114 @@ pub const leader: []const Chord = &.{.{ .cp = ' ' }};
/// still reach. Also Help's own path below, so the character is spelled once.
pub const leader_help: u8 = '?';
-/// SPC leader: ONE key path per builtin, the whole remapping surface. An
-/// EnumArray, so a new enum field is a compile error until someone has DECIDED
-/// its path. Groups are just shared first letters (f files, h docs, c columns,
-/// t toggles, s session, l language, w windows).
+/// what an unlisted builtin's path is until someone says otherwise: a value no
+/// key path can be, so the loop at the bottom of the table can refuse it
+const undecided: []const u8 = "<undecided>";
+
+/// SPC leader: ONE key path per builtin, the whole remapping surface. A new
+/// enum field is a compile error until someone has DECIDED its path — that is
+/// what `undecided` and the loop under the table are for, and it used to be
+/// EnumArray.init's own doing (it demands every field). It cannot be any more:
+/// the gui-only builtins are not fields of this literal's type on tty or web,
+/// so the literal cannot name them and a default is the only way to have both.
+/// Groups are just shared first letters (f files, h docs, c columns, t
+/// toggles, s session, l language, w windows).
///
/// `null` = this builtin's shortcut is not a leader path. Look and Exec are
/// the two: their shortcuts are Enter/Tab and the two mouse buttons below, and
/// a third spelling under SPC would be a key that does nothing you cannot
/// already do with the key your hand is on. The option is the honest type —
/// "every builtin has a leader path" was only ever true by accident.
-pub const leader_path = std.EnumArray(Builtin, ?[]const u8).init(.{
- .Help = &[_]u8{leader_help},
- // The whole LANGUAGE group lives under `l`, and pardes's own builtins keep
- // the letters they always had — `SPC d` is Del, `SPC k` is Kill.
- //
- // Helix puts these on bare `<space>` letters, and an earlier pass followed
- // it there, which cost `d`, `k`, `s`, `h` and the session group. That is
- // the wrong trade: those five are pardes's most-pressed keys and predate
- // the language work, whereas an LSP command is something you reach for
- // deliberately and can afford one more keystroke. Each one still keeps
- // HELIX'S OWN LETTER inside the group, so the mapping is `<space>X` ->
- // `SPC l X` with nothing to re-learn but the prefix.
- //
- // The five GOTOS are untouched and remain exactly helix's — `gd` `gD` `gy`
- // `gi` `gr`, plus `]d`/`[d` and `=`. Those never collided with anything, so
- // there was never a reason to move them. They are in PART 3.
- .Hover = "lk",
- .Rename = "lr",
- .CodeAction = "la",
- .SelectRefs = "lh",
- .Symbols = "ls",
- .WsSymbols = "lS",
- .Diagnostics = "ld",
- .WsDiagnostics = "lD",
- .Lspinfo = "li",
- .Lspwhy = "lw",
- .Del = "d",
- .Kill = "k",
- // the `f` file group (spacemacs): Save left vim's `w` to join Find here,
- // which frees `w` for the window group (SPC w h/j/k/l) to move into.
- .Save = "fs",
- .Find = "ff",
- .Grep = "fg",
- .Tutor = "ht",
- .Newcol = "cn",
- .Delcol = "cd",
- .Debug = "td",
- .Colors = "tc",
- .NextColor = "tn",
- .Crt = "tr",
- // the theme picker joins the toggles it belongs with; `Theme` itself takes
- // a NAME, and a key path can never carry one, so it has none (the same
- // reason Look and Exec have none)
- .ThemeSel = "tt",
- .Theme = null,
- // the image toggles join the same `t` group; Palette takes `l` because
- // `p` is Petscii's and `c` is Colors'.
- .Petscii = "tp",
- .Palette = "tl",
- .Ascii = "ta",
- .Dump = "sd",
- .Restore = "sr",
- // the `w` window group `Save` vacated: the four directional focus moves
- // the Ctrl-w prefix does, spelled h/j/k/l because focus IS a motion, plus
- // `t` for the file<->terminal hop.
- .Left = "wh",
- .Down = "wj",
- .Up = "wk",
- .Right = "wl",
- .Toggleterm = "wt",
- // the `j` JUMP group, its own letter rather than more of `w`: the window
- // group moves focus by GEOMETRY (the pane left of this one), these move it
- // by TIME (the pane I was in before). `o` and `i` are the letters of the
- // chords that do the same thing, `jj` is the group's obvious verb, and
- // `jl` is the list itself.
- .Back = "jo",
- .Forward = "ji",
- .Last = "jj",
- .Jumplist = "jl",
- // the two acme verbs: keys and buttons, no leader path — see above
- .Look = null,
- .Exec = null,
-});
+pub const leader_path = paths: {
+ var table = std.EnumArray(Builtin, ?[]const u8).initDefault(@as(?[]const u8, undecided), .{
+ .Help = &[_]u8{leader_help},
+ // The whole LANGUAGE group lives under `l`, and pardes's own builtins keep
+ // the letters they always had — `SPC d` is Del, `SPC k` is Kill.
+ //
+ // Helix puts these on bare `<space>` letters, and an earlier pass followed
+ // it there, which cost `d`, `k`, `s`, `h` and the session group. That is
+ // the wrong trade: those five are pardes's most-pressed keys and predate
+ // the language work, whereas an LSP command is something you reach for
+ // deliberately and can afford one more keystroke. Each one still keeps
+ // HELIX'S OWN LETTER inside the group, so the mapping is `<space>X` ->
+ // `SPC l X` with nothing to re-learn but the prefix.
+ //
+ // The five GOTOS are untouched and remain exactly helix's — `gd` `gD` `gy`
+ // `gi` `gr`, plus `]d`/`[d` and `=`. Those never collided with anything, so
+ // there was never a reason to move them. They are in PART 3.
+ .Hover = "lk",
+ .Rename = "lr",
+ .CodeAction = "la",
+ .SelectRefs = "lh",
+ .Symbols = "ls",
+ .WsSymbols = "lS",
+ .Diagnostics = "ld",
+ .WsDiagnostics = "lD",
+ .Lspinfo = "li",
+ .Lspwhy = "lw",
+ .Del = "d",
+ .Kill = "k",
+ // the `f` file group (spacemacs): Save left vim's `w` to join Find here,
+ // which frees `w` for the window group (SPC w h/j/k/l) to move into.
+ .Save = "fs",
+ .Find = "ff",
+ .Grep = "fg",
+ .Tutor = "ht",
+ .Newcol = "cn",
+ .Delcol = "cd",
+ .Debug = "td",
+ .Colors = "tc",
+ .NextColor = "tn",
+ .Crt = "tr",
+ // the theme picker joins the toggles it belongs with; `Theme` itself takes
+ // a NAME, and a key path can never carry one, so it has none (the same
+ // reason Look and Exec have none)
+ .ThemeSel = "tt",
+ .Theme = null,
+ // the image toggles join the same `t` group; Palette takes `l` because
+ // `p` is Petscii's and `c` is Colors'.
+ .Petscii = "tp",
+ .Palette = "tl",
+ .Ascii = "ta",
+ .Dump = "sd",
+ .Restore = "sr",
+ // the `w` window group `Save` vacated: the four directional focus moves
+ // the Ctrl-w prefix does, spelled h/j/k/l because focus IS a motion, plus
+ // `t` for the file<->terminal hop.
+ .Left = "wh",
+ .Down = "wj",
+ .Up = "wk",
+ .Right = "wl",
+ .Toggleterm = "wt",
+ // the `j` JUMP group, its own letter rather than more of `w`: the window
+ // group moves focus by GEOMETRY (the pane left of this one), these move it
+ // by TIME (the pane I was in before). `o` and `i` are the letters of the
+ // chords that do the same thing, `jj` is the group's obvious verb, and
+ // `jl` is the list itself.
+ .Back = "jo",
+ .Forward = "ji",
+ .Last = "jj",
+ .Jumplist = "jl",
+ // the two acme verbs: keys and buttons, no leader path — see above
+ .Look = null,
+ .Exec = null,
+ });
+ // The GUI's two font builtins, in the same `t` group as the theme picker
+ // they mirror — but set here rather than named above, because on tty and
+ // web they are not builtins at all (see builtins.zig) and the literal's
+ // type has no field to write. `Font` takes a NAME, so it has no path, for
+ // the same reason `Theme` has none.
+ if (pardes.platform == .gui) {
+ table.set(.FontSel, "tf");
+ table.set(.Font, null);
+ }
+ // ...and the property EnumArray.init used to give for free: every builtin
+ // this build HAS is a builtin someone decided a path (or a null) for.
+ for (std.enums.values(Builtin)) |b| if (table.get(b)) |p| {
+ if (std.mem.eql(u8, p, undecided)) @compileError("builtin has no leader path decided: " ++ @tagName(b));
+ };
+ break :paths table;
+};
// ---- the acme chords ----
@@ -514,6 +539,7 @@ pub const search_buffer = "+Search";
pub const help_buffer = "+Help";
pub const jumps_buffer = "+Jumps";
pub const themes_buffer = "+Themes";
+pub const fonts_buffer = "+Fonts";
pub const hover_buffer = "+Hover";
pub const lsp_buffer = "+Lsp";