From 31653ed99699425ba720f3a8c827c70d61313066 Mon Sep 17 00:00:00 2001 From: Patrick Jackson Date: Fri, 10 Nov 2023 16:58:05 -0700 Subject: [PATCH] Bash `enter_accept` best effort fixes (#1384) * fix(bash): Rewrite the enter_accept integration * docs(bash): Update bash installation instructions with warnings --- README.md | 18 ++++++++-- atuin/src/shell/atuin.bash | 64 ++++++++++++++++++++++++++++------- docs/docs/advanced-install.md | 18 ++++++++-- 3 files changed, 84 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 513d9bd..5897136 100644 --- a/README.md +++ b/README.md @@ -248,16 +248,30 @@ antigen bundle atuinsh/atuin@main ### bash -We need to setup some hooks, so first install bash-preexec: +#### [ble.sh](https://github.com/akinomyoga/ble.sh) +Atuin works best in bash when using [ble.sh](https://github.com/akinomyoga/ble.sh). + +With ble.sh installed, just add atuin to your .bashrc + +```bash +echo 'eval "$(atuin init bash)"' >> ~/.bashrc ``` + +#### [bash-preexec](https://github.com/rcaloras/bash-preexec) + +[Bash-preexec](https://github.com/rcaloras/bash-preexec) can also be used, but you may experience some minor problems with the recorded duration and exit status of some commands. + +To use bash-preexec, download and initialize it + +```bash curl https://raw.githubusercontent.com/rcaloras/bash-preexec/master/bash-preexec.sh -o ~/.bash-preexec.sh echo '[[ -f ~/.bash-preexec.sh ]] && source ~/.bash-preexec.sh' >> ~/.bashrc ``` Then setup Atuin -``` +```bash echo 'eval "$(atuin init bash)"' >> ~/.bashrc ``` diff --git a/atuin/src/shell/atuin.bash b/atuin/src/shell/atuin.bash index 3c15d39..0c87e42 100644 --- a/atuin/src/shell/atuin.bash +++ b/atuin/src/shell/atuin.bash @@ -1,13 +1,13 @@ ATUIN_SESSION=$(atuin uuid) export ATUIN_SESSION -_atuin_preexec() { +__atuin_preexec() { local id id=$(atuin history start -- "$1") export ATUIN_HISTORY_ID="${id}" } -_atuin_precmd() { +__atuin_precmd() { local EXIT="$?" [[ -z "${ATUIN_HISTORY_ID}" ]] && return @@ -16,6 +16,10 @@ _atuin_precmd() { export ATUIN_HISTORY_ID="" } +__atuin_set_ret_value() { + return ${1:+"$1"} +} + __atuin_history() { # shellcheck disable=SC2048,SC2086 HISTORY="$(ATUIN_SHELL_BASH=t ATUIN_LOG=error atuin search $* -i -- "${READLINE_LINE}" 3>&1 1>&2 2>&3)" @@ -23,25 +27,61 @@ __atuin_history() { if [[ $HISTORY == __atuin_accept__:* ]] then HISTORY=${HISTORY#__atuin_accept__:} - echo "$HISTORY" - # Need to run the pre/post exec functions manually - _atuin_preexec "$HISTORY" + # Reprint the prompt, accounting for multiple lines + tput cuu $(echo -n "${PS1@P}" | tr -cd '\n' | wc -c) + echo "${PS1@P}$HISTORY" + + if [[ -n "${BLE_VERSION-}" ]]; then + blehook/invoke PREEXEC "$HISTORY" + else + # Assuming bash-preexec + # Invoke every function in the preexec array + local preexec_function + local preexec_function_ret_value + local preexec_ret_value=0 + for preexec_function in "${preexec_functions[@]:-}"; do + if type -t "$preexec_function" 1>/dev/null; then + __bp_set_ret_value "${__bp_last_ret_value:-}" + "$preexec_function" "$HISTORY" + preexec_function_ret_value="$?" + if [[ "$preexec_function_ret_value" != 0 ]]; then + preexec_ret_value="$preexec_function_ret_value" + fi + fi + done + __bp_set_ret_value "$preexec_ret_value" "$__bp_last_argument_prev_command" + fi eval "$HISTORY" - _atuin_precmd - echo + exit_status=$? + # Execute preprompt commands + __atuin_set_ret_value "$exit_status" "$HISTORY" + eval "$PROMPT_COMMAND" + # Need to reexecute the blehook + if [[ -n "${BLE_VERSION-}" ]]; then + __atuin_set_ret_value "$exit_status" "$HISTORY" + blehook/invoke PRECMD "$?" + fi + # Add it to the bash history + history -s "$HISTORY" + # Bash will redraw only the line with the prompt after we finish, + # so to work for a multiline prompt we need to print it ourselves, + # then move up a line + __atuin_set_ret_value "$exit_status" "$HISTORY" + echo "${PS1@P}" + tput cuu 1 + __atuin_set_ret_value "$exit_status" "$HISTORY" READLINE_LINE="" READLINE_POINT=${#READLINE_LINE} else READLINE_LINE=${HISTORY} READLINE_POINT=${#READLINE_LINE} fi - } if [[ -n "${BLE_VERSION-}" ]]; then - blehook PRECMD-+=_atuin_precmd - blehook PREEXEC-+=_atuin_preexec + blehook PRECMD-+=__atuin_precmd + blehook PREEXEC-+=__atuin_preexec else - precmd_functions+=(_atuin_precmd) - preexec_functions+=(_atuin_preexec) + precmd_functions+=(__atuin_precmd) + preexec_functions+=(__atuin_preexec) fi diff --git a/docs/docs/advanced-install.md b/docs/docs/advanced-install.md index cf9bbad..862bb92 100644 --- a/docs/docs/advanced-install.md +++ b/docs/docs/advanced-install.md @@ -112,16 +112,30 @@ antigen bundle atuinsh/atuin@main ### bash -We need to setup some hooks, so first install bash-preexec: +#### [ble.sh](https://github.com/akinomyoga/ble.sh) +Atuin works best in bash when using [ble.sh](https://github.com/akinomyoga/ble.sh). + +With ble.sh installed, just add atuin to your .bashrc + +```bash +echo 'eval "$(atuin init bash)"' >> ~/.bashrc ``` + +#### [bash-preexec](https://github.com/rcaloras/bash-preexec) + +[Bash-preexec](https://github.com/rcaloras/bash-preexec) can also be used, but you may experience some minor problems with the recorded duration and exit status of some commands. + +To use bash-preexec, download and initialize it + +```bash curl https://raw.githubusercontent.com/rcaloras/bash-preexec/master/bash-preexec.sh -o ~/.bash-preexec.sh echo '[[ -f ~/.bash-preexec.sh ]] && source ~/.bash-preexec.sh' >> ~/.bashrc ``` Then setup Atuin -``` +```bash echo 'eval "$(atuin init bash)"' >> ~/.bashrc ```