mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-15 00:06:09 +03:00
config: add "initial-command" config, "-e" sets that
Fixes #2601 It is more expected behavior that `-e` affects only the first window. By introducing a dedicated configuration we avoid making `-e` too magical: its simply syntax sugar for setting the "initial-command" configuration.
This commit is contained in:
@ -66,6 +66,11 @@ font_grid_set: font.SharedGridSet,
|
|||||||
last_notification_time: ?std.time.Instant = null,
|
last_notification_time: ?std.time.Instant = null,
|
||||||
last_notification_digest: u64 = 0,
|
last_notification_digest: u64 = 0,
|
||||||
|
|
||||||
|
/// Set to false once we've created at least one surface. This
|
||||||
|
/// never goes true again. This can be used by surfaces to determine
|
||||||
|
/// if they are the first surface.
|
||||||
|
first: bool = true,
|
||||||
|
|
||||||
pub const CreateError = Allocator.Error || font.SharedGridSet.InitError;
|
pub const CreateError = Allocator.Error || font.SharedGridSet.InitError;
|
||||||
|
|
||||||
/// Initialize the main app instance. This creates the main window, sets
|
/// Initialize the main app instance. This creates the main window, sets
|
||||||
|
@ -474,13 +474,19 @@ pub fn init(
|
|||||||
.config = derived_config,
|
.config = derived_config,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// The command we're going to execute
|
||||||
|
const command: ?[]const u8 = if (app.first)
|
||||||
|
config.@"initial-command" orelse config.command
|
||||||
|
else
|
||||||
|
config.command;
|
||||||
|
|
||||||
// Start our IO implementation
|
// Start our IO implementation
|
||||||
// This separate block ({}) is important because our errdefers must
|
// This separate block ({}) is important because our errdefers must
|
||||||
// be scoped here to be valid.
|
// be scoped here to be valid.
|
||||||
{
|
{
|
||||||
// Initialize our IO backend
|
// Initialize our IO backend
|
||||||
var io_exec = try termio.Exec.init(alloc, .{
|
var io_exec = try termio.Exec.init(alloc, .{
|
||||||
.command = config.command,
|
.command = command,
|
||||||
.shell_integration = config.@"shell-integration",
|
.shell_integration = config.@"shell-integration",
|
||||||
.shell_integration_features = config.@"shell-integration-features",
|
.shell_integration_features = config.@"shell-integration-features",
|
||||||
.working_directory = config.@"working-directory",
|
.working_directory = config.@"working-directory",
|
||||||
@ -618,9 +624,9 @@ pub fn init(
|
|||||||
// For xdg-terminal-exec execution we special-case and set the window
|
// For xdg-terminal-exec execution we special-case and set the window
|
||||||
// title to the command being executed. This allows window managers
|
// title to the command being executed. This allows window managers
|
||||||
// to set custom styling based on the command being executed.
|
// to set custom styling based on the command being executed.
|
||||||
const command = config.command orelse break :xdg;
|
const v = command orelse break :xdg;
|
||||||
if (command.len > 0) {
|
if (v.len > 0) {
|
||||||
const title = alloc.dupeZ(u8, command) catch |err| {
|
const title = alloc.dupeZ(u8, v) catch |err| {
|
||||||
log.warn(
|
log.warn(
|
||||||
"error copying command for title, title will not be set err={}",
|
"error copying command for title, title will not be set err={}",
|
||||||
.{err},
|
.{err},
|
||||||
@ -635,6 +641,9 @@ pub fn init(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We are no longer the first surface
|
||||||
|
app.first = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deinit(self: *Surface) void {
|
pub fn deinit(self: *Surface) void {
|
||||||
|
@ -513,7 +513,26 @@ palette: Palette = .{},
|
|||||||
/// arguments are provided, the command will be executed using `/bin/sh -c`.
|
/// arguments are provided, the command will be executed using `/bin/sh -c`.
|
||||||
/// Ghostty does not do any shell command parsing.
|
/// Ghostty does not do any shell command parsing.
|
||||||
///
|
///
|
||||||
/// If you're using the `ghostty` CLI there is also a shortcut to run a command
|
/// This command will be used for all new terminal surfaces, i.e. new windows,
|
||||||
|
/// tabs, etc. If you want to run a command only for the first terminal surface
|
||||||
|
/// created when Ghostty starts, use the `initial-command` configuration.
|
||||||
|
///
|
||||||
|
/// Ghostty supports the common `-e` flag for executing a command with
|
||||||
|
/// arguments. For example, `ghostty -e fish --with --custom --args`.
|
||||||
|
/// This flag sets the `initial-command` configuration, see that for more
|
||||||
|
/// information.
|
||||||
|
command: ?[]const u8 = null,
|
||||||
|
|
||||||
|
/// This is the same as "command", but only applies to the first terminal
|
||||||
|
/// surface created when Ghostty starts. Subsequent terminal surfaces will use
|
||||||
|
/// the `command` configuration.
|
||||||
|
///
|
||||||
|
/// After the first terminal surface is created (or closed), there is no
|
||||||
|
/// way to run this initial command again automatically. As such, setting
|
||||||
|
/// this at runtime works but will only affect the next terminal surface
|
||||||
|
/// if it is the first one ever created.
|
||||||
|
///
|
||||||
|
/// If you're using the `ghostty` CLI there is also a shortcut to set this
|
||||||
/// with arguments directly: you can use the `-e` flag. For example: `ghostty -e
|
/// with arguments directly: you can use the `-e` flag. For example: `ghostty -e
|
||||||
/// fish --with --custom --args`. The `-e` flag automatically forces some
|
/// fish --with --custom --args`. The `-e` flag automatically forces some
|
||||||
/// other behaviors as well:
|
/// other behaviors as well:
|
||||||
@ -525,7 +544,7 @@ palette: Palette = .{},
|
|||||||
/// process will exit when the command exits. Additionally, the
|
/// process will exit when the command exits. Additionally, the
|
||||||
/// `quit-after-last-window-closed-delay` is unset.
|
/// `quit-after-last-window-closed-delay` is unset.
|
||||||
///
|
///
|
||||||
command: ?[]const u8 = null,
|
@"initial-command": ?[]const u8 = null,
|
||||||
|
|
||||||
/// If true, keep the terminal open after the command exits. Normally, the
|
/// If true, keep the terminal open after the command exits. Normally, the
|
||||||
/// terminal window closes when the running command (such as a shell) exits.
|
/// terminal window closes when the running command (such as a shell) exits.
|
||||||
@ -2356,7 +2375,7 @@ pub fn loadCliArgs(self: *Config, alloc_gpa: Allocator) !void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
self.@"_xdg-terminal-exec" = true;
|
self.@"_xdg-terminal-exec" = true;
|
||||||
self.command = command.items[0 .. command.items.len - 1];
|
self.@"initial-command" = command.items[0 .. command.items.len - 1];
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2755,7 +2774,7 @@ pub fn parseManuallyHook(
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.command = command.items[0 .. command.items.len - 1];
|
self.@"initial-command" = command.items[0 .. command.items.len - 1];
|
||||||
|
|
||||||
// See "command" docs for the implied configurations and why.
|
// See "command" docs for the implied configurations and why.
|
||||||
self.@"gtk-single-instance" = .false;
|
self.@"gtk-single-instance" = .false;
|
||||||
@ -2945,7 +2964,7 @@ test "parse e: command only" {
|
|||||||
|
|
||||||
var it: TestIterator = .{ .data = &.{"foo"} };
|
var it: TestIterator = .{ .data = &.{"foo"} };
|
||||||
try testing.expect(!try cfg.parseManuallyHook(alloc, "-e", &it));
|
try testing.expect(!try cfg.parseManuallyHook(alloc, "-e", &it));
|
||||||
try testing.expectEqualStrings("foo", cfg.command.?);
|
try testing.expectEqualStrings("foo", cfg.@"initial-command".?);
|
||||||
}
|
}
|
||||||
|
|
||||||
test "parse e: command and args" {
|
test "parse e: command and args" {
|
||||||
@ -2956,7 +2975,7 @@ test "parse e: command and args" {
|
|||||||
|
|
||||||
var it: TestIterator = .{ .data = &.{ "echo", "foo", "bar baz" } };
|
var it: TestIterator = .{ .data = &.{ "echo", "foo", "bar baz" } };
|
||||||
try testing.expect(!try cfg.parseManuallyHook(alloc, "-e", &it));
|
try testing.expect(!try cfg.parseManuallyHook(alloc, "-e", &it));
|
||||||
try testing.expectEqualStrings("echo foo bar baz", cfg.command.?);
|
try testing.expectEqualStrings("echo foo bar baz", cfg.@"initial-command".?);
|
||||||
}
|
}
|
||||||
|
|
||||||
test "clone default" {
|
test "clone default" {
|
||||||
|
Reference in New Issue
Block a user