shell-init: record the first command of every shell in atuin
bash-preexec arms its DEBUG trap from __bp_interactive_mode at the end of PROMPT_COMMAND, but its lazy installer runs mid-way through the first prompt because zoxide and ghostty append their hooks after it. Those hooks disarm the trap again, so the first interactive command of every session never reached preexec and atuin silently dropped it. Arm from PS0 instead, which is expanded once per interactive command before the DEBUG trap and is therefore independent of PROMPT_COMMAND ordering. Also guard the script against running twice: it is installed as both loginShellInit and interactiveShellInit, and /etc/profile sources /etc/bashrc, which registered starship's precmd/preexec hooks twice in every login shell.
This commit is contained in:
parent
3f29ad6cec
commit
9f28569fef
1 changed files with 32 additions and 11 deletions
|
|
@ -37,18 +37,43 @@ fi
|
|||
|
||||
(( INTERACTIVE )) || return 0
|
||||
|
||||
# ---- run-once guard --------------------------------------------------------
|
||||
|
||||
# Installed as both loginShellInit (/etc/profile) and interactiveShellInit
|
||||
# (/etc/bashrc), and /etc/profile sources /etc/bashrc, so a login shell would run
|
||||
# this twice and register starship's hooks twice. Not exported: child shells must
|
||||
# initialise on their own.
|
||||
if [[ -n ${NANUQSAURUS_SHELL_INIT_DONE:-} ]]; then
|
||||
log_shell_init "already initialised, skipping"
|
||||
return 0
|
||||
fi
|
||||
NANUQSAURUS_SHELL_INIT_DONE=1
|
||||
|
||||
# ---- bash-preexec ----------------------------------------------------------
|
||||
|
||||
if [[ -n ${BASH_VERSION:-} && -z ${bash_preexec_imported:-} && -r "@BASHPREEXEC@" ]]; then
|
||||
# shellcheck disable=SC1090
|
||||
. "@BASHPREEXEC@"
|
||||
# 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
|
||||
|
||||
# bash-preexec arms its DEBUG trap from __bp_interactive_mode, which it appends to
|
||||
# the END of PROMPT_COMMAND -- but its lazy installer runs in the MIDDLE of the
|
||||
# first prompt, because zoxide (below) and ghostty (~/.bashrc) append their hooks
|
||||
# after it. Those hooks then disarm the trap again, so the first command of every
|
||||
# session never reaches preexec and atuin never records it. PS0 is expanded once
|
||||
# per interactive command, before the DEBUG trap, so arming there is independent of
|
||||
# PROMPT_COMMAND ordering. Needs the non-forking ${ ...; } funsub (bash >= 5.3);
|
||||
# older bash keeps the previous behaviour.
|
||||
if [[ -n ${bash_preexec_imported:-} ]] &&
|
||||
((BASH_VERSINFO[0] > 5 || (BASH_VERSINFO[0] == 5 && BASH_VERSINFO[1] >= 3))); then
|
||||
# shellcheck disable=SC2016
|
||||
__nanuq_bp_arm='${ __bp_preexec_interactive_mode=on; }'
|
||||
[[ ${PS0-} == *"$__nanuq_bp_arm"* ]] || PS0=$__nanuq_bp_arm${PS0-}
|
||||
unset __nanuq_bp_arm
|
||||
log_shell_init "bash-preexec PS0 arming enabled"
|
||||
fi
|
||||
|
||||
# ---- starship --------------------------------------------------------------
|
||||
|
||||
if have @STARSHIP@; then
|
||||
|
|
@ -57,8 +82,7 @@ if have @STARSHIP@; then
|
|||
*/bash) eval "$(@STARSHIP@ init bash)" ;;
|
||||
*/zsh) eval "$(@STARSHIP@ init zsh)" ;;
|
||||
esac
|
||||
# starship's bash init registers starship_precmd/starship_preexec_all with
|
||||
# bash-preexec directly; no manual PROMPT_COMMAND wiring needed.
|
||||
# registers starship_precmd/starship_preexec_all with bash-preexec directly
|
||||
else
|
||||
log_shell_init "starship skipped"
|
||||
fi
|
||||
|
|
@ -77,8 +101,7 @@ if have @ATUIN@; then
|
|||
*/bash) eval "$(@ATUIN@ init bash)" ;;
|
||||
*/zsh) eval "$(@ATUIN@ init zsh)" ;;
|
||||
esac
|
||||
# atuin's init registers __atuin_preexec/__atuin_precmd with bash-preexec
|
||||
# itself; manual array wiring only caused duplicate hook entries.
|
||||
# registers __atuin_preexec/__atuin_precmd with bash-preexec itself
|
||||
else
|
||||
log_shell_init "atuin skipped"
|
||||
fi
|
||||
|
|
@ -91,9 +114,7 @@ if have zoxide; then
|
|||
*/bash) eval "$(zoxide init bash)" ;;
|
||||
*/zsh) eval "$(zoxide init zsh)" ;;
|
||||
esac
|
||||
# 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.
|
||||
# appends __zoxide_hook to PROMPT_COMMAND; see the PS0 note above
|
||||
else
|
||||
log_shell_init "zoxide skipped"
|
||||
fi
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue