feat: add GHOSTTY_BIN_DIR to path via shell integration

pull/8976/head
Matthew Hrehirchuk 2025-09-30 11:23:02 -06:00
parent ceac472af0
commit 4cc663fc60
6 changed files with 47 additions and 4 deletions

View File

@ -2359,6 +2359,11 @@ keybind: Keybinds = .{},
/// cache manually using various arguments.
/// (Available since: 1.2.0)
///
/// * `path` - Add Ghostty's binary directory to PATH. This ensures the `ghostty`
/// command is available in the shell even if shell init scripts reset PATH.
/// This is particularly useful on macOS where PATH is often overridden by
/// system scripts. The directory is only added if not already present.
///
/// SSH features work independently and can be combined for optimal experience:
/// when both `ssh-env` and `ssh-terminfo` are enabled, Ghostty will install its
/// terminfo on remote hosts and use `xterm-ghostty` as TERM, falling back to
@ -6994,6 +6999,7 @@ pub const ShellIntegrationFeatures = packed struct {
title: bool = true,
@"ssh-env": bool = false,
@"ssh-terminfo": bool = false,
path: bool = true,
};
pub const RepeatableCommand = struct {

View File

@ -73,6 +73,14 @@ if [ -n "$GHOSTTY_BASH_INJECT" ]; then
builtin unset GHOSTTY_BASH_RCFILE
fi
# Add Ghostty binary to PATH if the path feature is enabled
if [[ "$GHOSTTY_SHELL_FEATURES" == *"path"* && -n "$GHOSTTY_BIN_DIR" ]]; then
# Check if the directory is already in PATH
if [[ ":$PATH:" != *":$GHOSTTY_BIN_DIR:"* ]]; then
export PATH="$PATH:$GHOSTTY_BIN_DIR"
fi
fi
# Sudo
if [[ "$GHOSTTY_SHELL_FEATURES" == *"sudo"* && -n "$TERMINFO" ]]; then
# Wrap `sudo` command to ensure Ghostty terminfo is preserved.

View File

@ -196,6 +196,19 @@
set edit:before-readline = (conj $edit:before-readline $beam~)
set edit:after-readline = (conj $edit:after-readline {|_| block })
}
if (and (has-value $features path) (has-env GHOSTTY_BIN_DIR)) {
# Check if the directory is already in PATH
var path-contains-ghostty = $false
for p $paths {
if (eq $p $E:GHOSTTY_BIN_DIR) {
set path-contains-ghostty = $true
break
}
}
if (not $path-contains-ghostty) {
set paths = [$@paths $E:GHOSTTY_BIN_DIR]
}
}
if (and (has-value $features sudo) (not-eq "" $E:TERMINFO) (has-external sudo)) {
edit:add-var sudo~ $sudo-with-terminfo~
}

View File

@ -61,6 +61,14 @@ function __ghostty_setup --on-event fish_prompt -d "Setup ghostty integration"
end
end
# Add Ghostty binary to PATH if the path feature is enabled
if contains path $features; and test -n "$GHOSTTY_BIN_DIR"
# Check if the directory is already in PATH
if not contains -- "$GHOSTTY_BIN_DIR" $PATH
set --global --export PATH $PATH "$GHOSTTY_BIN_DIR"
end
end
# When using sudo shell integration feature, ensure $TERMINFO is set
# and `sudo` is not already a function or alias
if contains sudo $features; and test -n "$TERMINFO"; and test "file" = (type -t sudo 2> /dev/null; or echo "x")

View File

@ -220,6 +220,14 @@ _ghostty_deferred_init() {
builtin print -rnu $_ghostty_fd \$'\\e[0 q'"
fi
# Add Ghostty binary to PATH if the path feature is enabled
if [[ "$GHOSTTY_SHELL_FEATURES" == *"path"* ]] && [[ -n "$GHOSTTY_BIN_DIR" ]]; then
# Check if the directory is already in PATH
if [[ ":$PATH:" != *":$GHOSTTY_BIN_DIR:"* ]]; then
builtin export PATH="$PATH:$GHOSTTY_BIN_DIR"
fi
fi
# Sudo
if [[ "$GHOSTTY_SHELL_FEATURES" == *"sudo"* ]] && [[ -n "$TERMINFO" ]]; then
# Wrap `sudo` command to ensure Ghostty terminfo is preserved

View File

@ -219,8 +219,8 @@ test "setup features" {
var env = EnvMap.init(alloc);
defer env.deinit();
try setupFeatures(&env, .{ .cursor = true, .sudo = true, .title = true, .@"ssh-env" = true, .@"ssh-terminfo" = true });
try testing.expectEqualStrings("cursor,ssh-env,ssh-terminfo,sudo,title", env.get("GHOSTTY_SHELL_FEATURES").?);
try setupFeatures(&env, .{ .cursor = true, .sudo = true, .title = true, .@"ssh-env" = true, .@"ssh-terminfo" = true, .path = true });
try testing.expectEqualStrings("cursor,path,ssh-env,ssh-terminfo,sudo,title", env.get("GHOSTTY_SHELL_FEATURES").?);
}
// Test: all features disabled
@ -228,7 +228,7 @@ test "setup features" {
var env = EnvMap.init(alloc);
defer env.deinit();
try setupFeatures(&env, .{ .cursor = false, .sudo = false, .title = false, .@"ssh-env" = false, .@"ssh-terminfo" = false });
try setupFeatures(&env, .{ .cursor = false, .sudo = false, .title = false, .@"ssh-env" = false, .@"ssh-terminfo" = false, .path = false });
try testing.expect(env.get("GHOSTTY_SHELL_FEATURES") == null);
}
@ -237,7 +237,7 @@ test "setup features" {
var env = EnvMap.init(alloc);
defer env.deinit();
try setupFeatures(&env, .{ .cursor = false, .sudo = true, .title = false, .@"ssh-env" = true, .@"ssh-terminfo" = false });
try setupFeatures(&env, .{ .cursor = false, .sudo = true, .title = false, .@"ssh-env" = true, .@"ssh-terminfo" = false, .path = false });
try testing.expectEqualStrings("ssh-env,sudo", env.get("GHOSTTY_SHELL_FEATURES").?);
}
}