diff --git a/scripts/shell-init.sh b/scripts/shell-init.sh index 0135a6a..0a3f4d1 100644 --- a/scripts/shell-init.sh +++ b/scripts/shell-init.sh @@ -19,20 +19,6 @@ is_interactive() { [[ -t 1 || -n ${PS1:-} ]] } -append_unique() { - local var="$1" val="$2" - [[ ";${!var:-};" == *";$val;"* ]] && return - printf -v "$var" '%s' "${!var:+${!var%;};}$val" -} - -prepend_unique_array() { - local name="$1" val="$2" - local -n arr="$name" - local out=("$val") - for f in "${arr[@]}"; do [[ $f != "$val" ]] && out+=("$f"); done - arr=("${out[@]}") -} - # ---- environment sanity ---------------------------------------------------- if [[ -z ${TERM:-} || $TERM == dumb ]]; then @@ -56,7 +42,10 @@ fi if [[ -n ${BASH_VERSION:-} && -z ${bash_preexec_imported:-} && -r "@BASHPREEXEC@" ]]; then # shellcheck disable=SC1090 . "@BASHPREEXEC@" - have __bp_install && __bp_install + # Do NOT call __bp_install here. bash-preexec must install on the FIRST prompt, + # after starship/atuin/zoxide/ghostty have modified PROMPT_COMMAND, so that + # __bp_interactive_mode stays the LAST PROMPT_COMMAND entry. Installing eagerly + # lets later hooks land after it and silently breaks preexec (atuin recording). log_shell_init "bash-preexec loaded" fi @@ -68,7 +57,8 @@ if have @STARSHIP@; then */bash) eval "$(@STARSHIP@ init bash)" ;; */zsh) eval "$(@STARSHIP@ init zsh)" ;; esac - append_unique PROMPT_COMMAND starship_precmd + # starship's bash init registers starship_precmd/starship_preexec_all with + # bash-preexec directly; no manual PROMPT_COMMAND wiring needed. else log_shell_init "starship skipped" fi @@ -87,10 +77,8 @@ if have @ATUIN@; then */bash) eval "$(@ATUIN@ init bash)" ;; */zsh) eval "$(@ATUIN@ init zsh)" ;; esac - - declare -a preexec_functions precmd_functions - prepend_unique_array preexec_functions __atuin_preexec - prepend_unique_array precmd_functions __atuin_precmd + # atuin's init registers __atuin_preexec/__atuin_precmd with bash-preexec + # itself; manual array wiring only caused duplicate hook entries. else log_shell_init "atuin skipped" fi @@ -103,16 +91,13 @@ if have zoxide; then */bash) eval "$(zoxide init bash)" ;; */zsh) eval "$(zoxide init zsh)" ;; esac - have __zoxide_hook && append_unique PROMPT_COMMAND __zoxide_hook + # zoxide's bash init hooks into bash-preexec (precmd_functions) when it is + # present; manual PROMPT_COMMAND wiring only pushed hooks past + # __bp_interactive_mode and broke preexec ordering. else log_shell_init "zoxide skipped" fi -# ---- bash-preexec PROMPT_COMMAND safety ----------------------------------- - -have __bp_precmd_invoke_cmd && append_unique PROMPT_COMMAND __bp_precmd_invoke_cmd -have __bp_interactive_mode && append_unique PROMPT_COMMAND __bp_interactive_mode - # ---- aliases -------------------------------------------------------------- if have eza; then