From 005178177a1ddb2eb2f1af5fad36e2717758ee8e Mon Sep 17 00:00:00 2001 From: Gabriel Schneider Date: Fri, 31 Jul 2026 19:02:04 -0300 Subject: the gui wears any monospace font on the machine --- src/builtins.zig | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) (limited to 'src/builtins.zig') 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 ` +/// 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 ` 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 -- cgit v1.3