From 4dfa44ecd95a9e6c72188484c2a2871298800e8a Mon Sep 17 00:00:00 2001 From: Jon Parise Date: Tue, 15 Sep 2026 20:34:52 -0400 Subject: [PATCH 1/3] bash: use passed exit status in precmd The Bash 4.4+ prompt hook saves the command status before doing its own work and passes it to __ghostty_precmd. The function ignored that argument and instead read the hook invocation status, causing command end markers to report zero. Use the explicit argument when present while retaining the current status fallback required by the older bash-preexec path. See #14247 --- src/shell-integration/bash/ghostty.bash | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/shell-integration/bash/ghostty.bash b/src/shell-integration/bash/ghostty.bash index 729951ab9..48115da14 100644 --- a/src/shell-integration/bash/ghostty.bash +++ b/src/shell-integration/bash/ghostty.bash @@ -134,7 +134,7 @@ _ghostty_executing="" _ghostty_last_reported_cwd="" function __ghostty_precmd() { - local ret="$?" + local ret="${1:-$?}" if test "$_ghostty_executing" != "0"; then _GHOSTTY_SAVE_PS1="$PS1" _GHOSTTY_SAVE_PS2="$PS2" From ed7f046ee4dee89e5e8bbbecbc67ee14ac1f10d1 Mon Sep 17 00:00:00 2001 From: Jon Parise Date: Tue, 15 Sep 2026 20:43:59 -0400 Subject: [PATCH 2/3] bash: recognize attributed prompt command arrays Bash includes additional variable attributes in declare output, so an exported indexed array is reported with an -ax prefix instead of -a. Match the indexed-array prefix without requiring a following space so these values continue through the array-preserving path. --- src/shell-integration/bash/ghostty.bash | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/shell-integration/bash/ghostty.bash b/src/shell-integration/bash/ghostty.bash index 48115da14..701e335c8 100644 --- a/src/shell-integration/bash/ghostty.bash +++ b/src/shell-integration/bash/ghostty.bash @@ -255,7 +255,7 @@ if (( BASH_VERSINFO[0] > 4 || (BASH_VERSINFO[0] == 4 && BASH_VERSINFO[1] >= 4) ) else PROMPT_COMMAND="__ghostty_hook 2>/dev/null" fi - elif [[ $(builtin declare -p PROMPT_COMMAND 2>/dev/null) == "declare -a "* ]]; then + elif [[ $(builtin declare -p PROMPT_COMMAND 2>/dev/null) == "declare -a"* ]]; then PROMPT_COMMAND+=("__ghostty_hook 2>/dev/null") else [[ "${PROMPT_COMMAND}" =~ (\;[[:space:]]*|$'\n')$ ]] || PROMPT_COMMAND+=";" From 591ccacbdfa59945cb4f5b015390d0b8d416a7f0 Mon Sep 17 00:00:00 2001 From: Jon Parise Date: Tue, 15 Sep 2026 21:29:21 -0400 Subject: [PATCH 3/3] bash: preserve exit status across prompt commands Existing scalar PROMPT_COMMAND entries can overwrite the last command's status before Ghostty's appended hook runs. Capture and restore the status before those commands, then consume the saved value in the final hook. Keep array hooks as independent entries because Bash 5.1 and newer restore the original status for each entry. Preserve the existing PROMPT_COMMAND type and safely handle inherited prompt commands where Ghostty's function definitions are absent. This retains the fast Bash 4.4+ PS0 integration rather than using bash-preexec's DEBUG trap. See #14247 --- src/shell-integration/bash/ghostty.bash | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/shell-integration/bash/ghostty.bash b/src/shell-integration/bash/ghostty.bash index 701e335c8..76e7cc71b 100644 --- a/src/shell-integration/bash/ghostty.bash +++ b/src/shell-integration/bash/ghostty.bash @@ -223,8 +223,15 @@ if (( BASH_VERSINFO[0] > 4 || (BASH_VERSINFO[0] == 4 && BASH_VERSINFO[1] >= 4) ) [[ -n "$cmd" ]] && __ghostty_preexec "$cmd" } + # Bash 5.1+ restores the command status for each PROMPT_COMMAND array entry. + # Scalar values need to save and restore it before existing commands run. + __ghostty_restore_status() { + builtin return "$1" + } + __ghostty_hook() { - builtin local ret=$? + builtin local ret="${__ghostty_status:-$?}" + builtin unset __ghostty_status __ghostty_precmd "$ret" # Append preexec hook to PS0 if not already present. @@ -240,13 +247,14 @@ if (( BASH_VERSINFO[0] > 4 || (BASH_VERSINFO[0] == 4 && BASH_VERSINFO[1] >= 4) ) fi } - # Append our hook to PROMPT_COMMAND, preserving its existing type. + # Append our hook to PROMPT_COMMAND, preserving its existing type. Array + # entries receive their command's status directly, while scalar values + # need a leading status capture before existing commands run. # # The 2>/dev/null suppresses "command not found" in subshells that inherit - # PROMPT_COMMAND without the function definition. This also silences any - # errors from inside __ghostty_hook itself, but those are all terminal escape - # sequences and non-actionable. - # + # PROMPT_COMMAND without the function definitions. This also silences any + # errors from inside our hooks, but those are all terminal escape sequences + # and non-actionable. # shellcheck disable=SC2128,SC2178,SC2179 if [[ ";${PROMPT_COMMAND[*]:-};" != *";__ghostty_hook 2>/dev/null;"* ]]; then if [[ -z "${PROMPT_COMMAND[*]}" ]]; then @@ -258,6 +266,7 @@ if (( BASH_VERSINFO[0] > 4 || (BASH_VERSINFO[0] == 4 && BASH_VERSINFO[1] >= 4) ) elif [[ $(builtin declare -p PROMPT_COMMAND 2>/dev/null) == "declare -a"* ]]; then PROMPT_COMMAND+=("__ghostty_hook 2>/dev/null") else + PROMPT_COMMAND='__ghostty_status=$?;if builtin declare -F __ghostty_restore_status >/dev/null;then __ghostty_restore_status "$__ghostty_status";else (exit "$__ghostty_status");fi;'"${PROMPT_COMMAND}" [[ "${PROMPT_COMMAND}" =~ (\;[[:space:]]*|$'\n')$ ]] || PROMPT_COMMAND+=";" PROMPT_COMMAND+="__ghostty_hook 2>/dev/null" fi