diff --git a/src/config/Config.zig b/src/config/Config.zig index 1d780ab8c..22ae6b7d3 100644 --- a/src/config/Config.zig +++ b/src/config/Config.zig @@ -532,6 +532,8 @@ keybind: Keybinds = .{}, /// configure your shell to enable the integration. /// * "detect" - Detect the shell based on the filename. /// * "fish", "zsh" - Use this specific shell injection scheme. +/// * "no-cursor" - Detect the shell as in 'detect', but doesn't set cursor +/// shapes /// /// The default value is "detect". @"shell-integration": ShellIntegration = .detect, @@ -2182,6 +2184,7 @@ pub const ShellIntegration = enum { detect, fish, zsh, + @"no-cursor", }; /// OSC 10 and 11 default color reporting format. diff --git a/src/shell-integration/bash/ghostty.bash b/src/shell-integration/bash/ghostty.bash index b8a7e3d8c..b312a987d 100644 --- a/src/shell-integration/bash/ghostty.bash +++ b/src/shell-integration/bash/ghostty.bash @@ -41,8 +41,10 @@ function __ghostty_precmd() { PS2=$PS2'\[\e]133;B\a\]' # Cursor + if test "$GHOSTTY_SHELL_INTEGRATION_NO_CURSOR" != "1"; then PS1=$PS1'\[\e[5 q\]' PS0=$PS0'\[\e[0 q\]' + fi # Command PS0=$PS0'$(__ghostty_get_current_command)' diff --git a/src/shell-integration/fish/vendor_conf.d/ghostty-shell-integration.fish b/src/shell-integration/fish/vendor_conf.d/ghostty-shell-integration.fish index 1b5ec5e25..f176d80c4 100755 --- a/src/shell-integration/fish/vendor_conf.d/ghostty-shell-integration.fish +++ b/src/shell-integration/fish/vendor_conf.d/ghostty-shell-integration.fish @@ -51,12 +51,17 @@ status --is-interactive || ghostty_exit function __ghostty_setup --on-event fish_prompt -d "Setup ghostty integration" functions -e __ghostty_setup - # Change the cursor to a beam on prompt. - function __ghostty_set_cursor_beam --on-event fish_prompt -d "Set cursor shape" - echo -en "\e[5 q" - end - function __ghostty_reset_cursor --on-event fish_preexec -d "Reset cursor shape" - echo -en "\e[0 q" + # Check if we are setting cursors + set --local no_cursor "$GHOSTTY_SHELL_INTEGRATION_NO_CURSOR" + + if test -z $no_cursor + # Change the cursor to a beam on prompt. + function __ghostty_set_cursor_beam --on-event fish_prompt -d "Set cursor shape" + echo -en "\e[5 q" + end + function __ghostty_reset_cursor --on-event fish_preexec -d "Reset cursor shape" + echo -en "\e[0 q" + end end # Setup prompt marking @@ -82,7 +87,7 @@ function __ghostty_setup --on-event fish_prompt -d "Setup ghostty integration" # Report pwd. This is actually built-in to fish but only for terminals # that match an allowlist and that isn't us. - function __update_cwd_osc --on-variable PWD -d 'Notify capable terminals when $PWD changes' + function __update_cwd_osc --on-variable PWD -d 'Notify capable terminals when $PWD changes' if status --is-command-substitution || set -q INSIDE_EMACS return end @@ -93,7 +98,9 @@ function __ghostty_setup --on-event fish_prompt -d "Setup ghostty integration" set --global fish_handle_reflow 1 # Initial calls for first prompt - __ghostty_set_cursor_beam + if test -z $no_cursor + __ghostty_set_cursor_beam + end __ghostty_mark_prompt_start __update_cwd_osc end diff --git a/src/shell-integration/zsh/ghostty-integration b/src/shell-integration/zsh/ghostty-integration index 8697d59b4..c9611b9ab 100755 --- a/src/shell-integration/zsh/ghostty-integration +++ b/src/shell-integration/zsh/ghostty-integration @@ -200,21 +200,23 @@ _ghostty_deferred_init() { functions[_ghostty_preexec]+=" builtin print -rnu $_ghostty_fd \$'\\e]2;'\"\${(V)1}\"\$'\\a'" - # Enable cursor shape changes depending on the current keymap. - # This implementation leaks blinking block cursor into external commands - # executed from zle. For example, users of fzf-based widgets may find - # themselves with a blinking block cursor within fzf. - _ghostty_zle_line_init _ghostty_zle_line_finish _ghostty_zle_keymap_select() { - case ${KEYMAP-} in - # Blinking block cursor. - vicmd|visual) builtin print -nu "$_ghostty_fd" '\e[1 q';; - # Blinking bar cursor. - *) builtin print -nu "$_ghostty_fd" '\e[5 q';; - esac - } - # Restore the blinking default shape before executing an external command - functions[_ghostty_preexec]+=" - builtin print -rnu $_ghostty_fd \$'\\e[0 q'" + if [[ "$GHOSTTY_SHELL_INTEGRATION_NO_CURSOR" != 1 ]]; then + # Enable cursor shape changes depending on the current keymap. + # This implementation leaks blinking block cursor into external commands + # executed from zle. For example, users of fzf-based widgets may find + # themselves with a blinking block cursor within fzf. + _ghostty_zle_line_init _ghostty_zle_line_finish _ghostty_zle_keymap_select() { + case ${KEYMAP-} in + # Blinking block cursor. + vicmd|visual) builtin print -nu "$_ghostty_fd" '\e[1 q';; + # Blinking bar cursor. + *) builtin print -nu "$_ghostty_fd" '\e[5 q';; + esac + } + # Restore the blinking default shape before executing an external command + functions[_ghostty_preexec]+=" + builtin print -rnu $_ghostty_fd \$'\\e[0 q'" + fi # Some zsh users manually run `source ~/.zshrc` in order to apply rc file # changes to the current shell. This is a terrible practice that breaks many diff --git a/src/termio/Exec.zig b/src/termio/Exec.zig index 5fc3c6c1f..caa188a7d 100644 --- a/src/termio/Exec.zig +++ b/src/termio/Exec.zig @@ -812,6 +812,13 @@ const Subprocess = struct { .detect => null, .fish => .fish, .zsh => .zsh, + .@"no-cursor" => nc: { + // We add an environment variable for the shell integration + // scripts to pick up to prevent setting cursor shapes. + // Setting to "no_cursor" means we will detect the shell + try env.put("GHOSTTY_SHELL_INTEGRATION_NO_CURSOR", "1"); + break :nc null; + }, }; const dir = opts.resources_dir orelse break :shell null;