mirror of
https://github.com/ghostty-org/ghostty.git
synced 2026-09-19 20:18:07 +00:00
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
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user