From def16a1bc1c71d2fdcc7954e2ddec1384c2f05f7 Mon Sep 17 00:00:00 2001 From: Gabriel Schneider Date: Mon, 28 Sep 2026 14:39:52 -0300 Subject: Only Tty reads Word+arg as its argument Every builtin that takes an argument split a word at its first +, so Dump+2024.zon ran Dump with 2024.zon. A builtin now opts in with plus_arg, read by the registry, and only Tty does. Co-Authored-By: Claude Opus 5.5 --- src/builtins.zig | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'src/builtins.zig') diff --git a/src/builtins.zig b/src/builtins.zig index 02787cf5..4815a114 100644 --- a/src/builtins.zig +++ b/src/builtins.zig @@ -145,6 +145,16 @@ pub const registry = struct { return true; } + /// Whether the word takes its argument joined by a `+` as one word a + /// tag can hold and a click take whole (`Tty+fish`). Only a builtin + /// that says `pub const plus_arg = true;`: others have arguments a `+` + /// may be in (`Dump+2024.zon` is a name, not Dump's argument). + pub fn plusArg(b: Builtin()) bool { + inline for (manualBuiltinList(), 0..) |T, i| + if (@intFromEnum(b) == i) return @hasDecl(T, "plus_arg") and T.plus_arg; + return false; + } + /// Whether the word means nothing without its argument (`Mount`, /// `Msg`, a setting's value), or would ask for it at a prompt (`Find`): /// a ctl refuses it bare before any line of the write runs. A builtin @@ -822,6 +832,7 @@ pub const DelBelow = struct { /// the one named, `Tty fish`, as a terminal's own tag word `Tty+fish` says. pub const Tty = struct { pub const takes_arg = true; + pub const plus_arg = true; pub fn run(c: Ctx) void { exec.spawnTty(c.p, c.id); const arg = c.arg orelse return; -- cgit v1.3