summaryrefslogtreecommitdiff
path: root/src/builtins.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/builtins.zig
parent41847fce244fdd0d01971c302b89d1252f6497ed (diff)
downloadpardes-005178177a1ddb2eb2f1af5fad36e2717758ee8e.tar.gz
pardes-005178177a1ddb2eb2f1af5fad36e2717758ee8e.zip
the gui wears any monospace font on the machine
Diffstat (limited to 'src/builtins.zig')
-rw-r--r--src/builtins.zig61
1 files changed, 61 insertions, 0 deletions
diff --git a/src/builtins.zig b/src/builtins.zig
index 7378e395..85a6470d 100644
--- a/src/builtins.zig
+++ b/src/builtins.zig
@@ -31,6 +31,11 @@ const Pardes = pardes.Pardes;
const Pane = pardes.Pane;
const output_pane = @import("output_pane.zig");
const config = @import("config.zig");
+/// The installed fonts, for the two builtins at the bottom of this file. A
+/// GUI-only file behind a comptime branch, the way look.zig imports the web's
+/// source archive: the tty and web builds evaluate the other arm and compile
+/// none of it.
+const fonts = if (pardes.platform == .gui) @import("gui/fonts.zig") else struct {};
/// What a builtin gets to act on. One bundle rather than five parameters
/// because most builtins want two of them and zig rejects the unused rest.
@@ -228,6 +233,62 @@ pub const Crt = struct {
}
};
+// ---- the GUI's font, and NOTHING on any other platform ----
+//
+// Theme and ThemeSel again, one layer down: a word that takes a name, and the
+// list of what it takes. What is different is that these two only EXIST in a
+// gui build, and the mechanism is the one this file's header describes rather
+// than a new one — `all()` folds the enum out of the SHAPE of each decl, so a
+// struct whose `run` is not `fn (Ctx) void` is not a builtin. Here `run` is a
+// void const on tty and web: the enum has no field, `SPC ?` has no row, the
+// dispatcher has no prong, and nothing in a tty binary ever opens a font
+// directory. The body sits inside the struct as an ordinary private decl,
+// which the walk never sees (it only reads pub, file-scope declarations) and
+// which nothing on those platforms ever analyses.
+//
+// A `pub const Font = if (gui) struct {...} else struct {}` would read better
+// and is WRONG: zig names a struct born inside an if-expression
+// "builtins.Font__struct_32751", and that name is the user-visible word.
+
+/// The GUI font BY NAME — `Font DejaVuSansMono-Regular`, the way `Theme <name>`
+/// takes a theme, and inert without an argument for the same reason (there is
+/// no font called nothing). The name is a font FILE's stem, which is what the
+/// picker lists; resolving it is a walk of the font directories that stops at
+/// the first match, so nothing is cached and an install five seconds ago is
+/// findable.
+///
+/// The core cannot load a font — it has no rasterizer, no atlas and no window
+/// — so this asks: the resolved PATH goes in fonts.want, the shell takes it on
+/// its next pass and re-rasters. Exactly the shape Restore already has.
+pub const Font = struct {
+ pub const run = if (pardes.platform == .gui) apply else {};
+ fn apply(c: Ctx) void {
+ const want = std.mem.trim(u8, c.arg orelse return, " \t\r\n");
+ const hit = fonts.list(c.p.scratch.allocator(), want);
+ if (hit.len == 0) return;
+ const path = hit[0].path;
+ if (path.len > fonts.want_buf.len) return;
+ @memcpy(fonts.want_buf[0..path.len], path);
+ fonts.want = fonts.want_buf[0..path.len];
+ }
+};
+
+/// ...and the list of what Font takes: every MONOSPACE font on the machine,
+/// one `Font <name>` row each, in the picker ThemeSel already is (rows that
+/// are commands, so n/N execute them — walking the list wears each font in
+/// turn and picking one is stopping on it).
+///
+/// Monospace only, which is the one judgement in the feature: the grid is a
+/// fixed cell, so a proportional face is not a worse-looking option but an
+/// unreadable one — and this picker EXECUTES what it steps onto, so listing
+/// them would mean the list wearing one on the way past. See fonts.monospaced.
+pub const FontSel = struct {
+ pub const run = if (pardes.platform == .gui) apply else {};
+ fn apply(c: Ctx) void {
+ output_pane.openFonts(c.p, c.id);
+ }
+};
+
// The image pane's three renderer toggles. They used to be words the image tag
// printed and the execute dispatcher matched by hand; as builtins they are
// executable anywhere, pressable under SPC and listed by `SPC ?`, the whole