diff --git a/src/config/Config.zig b/src/config/Config.zig index e9c1d95af..a527cd70e 100644 --- a/src/config/Config.zig +++ b/src/config/Config.zig @@ -268,6 +268,16 @@ palette: Palette = .{}, /// command: ?[]const u8 = null, +/// A single argument to pass to the command. This can be repeated to +/// pass multiple arguments. This slightly clunky configuration style is +/// so that Ghostty doesn't have to perform any sort of shell parsing +/// to find argument boundaries. +/// +/// This cannot be used to override argv[0]. argv[0] will always be +/// set by Ghostty to be the command (possibly with a hyphen-prefix to +/// indicate that it is a login shell, depending on the OS). +@"command-arg": RepeatableString = .{}, + /// The directory to change to after starting the command. /// /// The default is "inherit" except in special scenarios listed next. diff --git a/src/termio/Exec.zig b/src/termio/Exec.zig index d4d80d696..6db769dc6 100644 --- a/src/termio/Exec.zig +++ b/src/termio/Exec.zig @@ -744,24 +744,25 @@ const Subprocess = struct { env.remove("GHOSTTY_MAC_APP"); } - // If we're NOT in a flatpak (usually!), then we just exec the - // process directly. If we are in a flatpak, we use flatpak-spawn - // to escape the sandbox. - const args = if (!internal_os.isFlatpak()) try alloc.dupe( - []const u8, - &[_][]const u8{argv0_override orelse path}, - ) else args: { - var args = try std.ArrayList([]const u8).initCapacity(alloc, 8); + // Build our args list + const args = args: { + const cap = 1 + opts.full_config.@"command-arg".list.items.len; + var args = try std.ArrayList([]const u8).initCapacity(alloc, cap); defer args.deinit(); - // We run our shell wrapped in a /bin/sh login shell because - // some systems do not properly initialize the env vars unless - // we start this way (NixOS!) - try args.append("/bin/sh"); - try args.append("-l"); - try args.append("-c"); - try args.append(path); + if (!internal_os.isFlatpak()) { + try args.append(argv0_override orelse path); + } else { + // We run our shell wrapped in a /bin/sh login shell because + // some systems do not properly initialize the env vars unless + // we start this way (NixOS!) + try args.append("/bin/sh"); + try args.append("-l"); + try args.append("-c"); + try args.append(path); + } + try args.appendSlice(opts.full_config.@"command-arg".list.items); break :args try args.toOwnedSlice(); };