From 1350d3fd74dfb968cae447a2b2b132ee146069a5 Mon Sep 17 00:00:00 2001 From: Koichi Murase Date: Mon, 1 Jan 2024 23:26:02 +0900 Subject: fix(bash): fix small issues of `enter_accept` for the plain Bash (#1467) * fix(bash): history should be updated before preexec * fix(bash): properly execute "--" With the current implementation, the user command "--" would not be executed even if it were the intended one. This is because it would be confused as an option by the "eval" builtin. We can specify "--" to tell "eval" that the later arguments should be literally treated as the command. * fix(bash): correctly restore $? and $_ * fix(bash): fix the use of preexec_ret_value The exit status of preexec_ret_value is used to suppress the execution of the corresponding command in the extdebug mode. The current implementation somehow tries to set $? before the call of stty, which does not have any effect. Instead, we can manually turn off the execution of the user command when the condition matches. * feat(bash): support array PROMPT_COMMAND of Bash >= 5.1 --- atuin/src/shell/atuin.bash | 38 +++++++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/atuin/src/shell/atuin.bash b/atuin/src/shell/atuin.bash index 0fe3220b..0ea03bb0 100644 --- a/atuin/src/shell/atuin.bash +++ b/atuin/src/shell/atuin.bash @@ -41,6 +41,9 @@ __atuin_history() { fi echo "${PS1@P}$HISTORY" + # Add it to the bash history + history -s "$HISTORY" + # Assuming bash-preexec # Invoke every function in the preexec array local preexec_function @@ -56,31 +59,36 @@ __atuin_history() { fi fi done - # shellcheck disable=SC2154 - __atuin_set_ret_value "$preexec_ret_value" "$__bp_last_argument_prev_command" - # Juggle the terminal settings so that the command can be interacted with - local stty_backup - stty_backup=$(stty -g) - stty "$ATUIN_STTY" + # If extdebug is turned on and any preexec function returns non-zero + # exit status, we do not run the user command. + if ! { shopt -q extdebug && ((preexec_ret_value)); }; then + # Juggle the terminal settings so that the command can be interacted with + local stty_backup + stty_backup=$(stty -g) + stty "$ATUIN_STTY" - eval "$HISTORY" - exit_status=$? + # Execute the command. Note: We need to record $? and $_ after the + # user command within the same call of "eval" because $_ is otherwise + # overwritten by the last argument of "eval". + __atuin_set_ret_value "${__bp_last_ret_value-}" "${__bp_last_argument_prev_command-}" + eval -- "$HISTORY"$'\n__bp_last_ret_value=$? __bp_last_argument_prev_command=$_' - stty "$stty_backup" + stty "$stty_backup" + fi # Execute preprompt commands - __atuin_set_ret_value "$exit_status" "$HISTORY" - eval "$PROMPT_COMMAND" - # Add it to the bash history - history -s "$HISTORY" + local __atuin_prompt_command + for __atuin_prompt_command in "${PROMPT_COMMAND[@]}"; do + __atuin_set_ret_value "${__bp_last_ret_value-}" "${__bp_last_argument_prev_command-}" + eval -- "$__atuin_prompt_command" + done # 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" + __atuin_set_ret_value "${__bp_last_ret_value-}" "${__bp_last_argument_prev_command-}" echo "${PS1@P}" tput cuu 1 - __atuin_set_ret_value "$exit_status" "$HISTORY" fi READLINE_LINE="" -- cgit v1.3.1