Skip to content

Commit

Permalink
fix(bash): improve the support for enter_accept with ble.sh (#1465)
Browse files Browse the repository at this point in the history
* feat(bash): check version of ble.sh

blehooks are only supported in ble.sh >= 0.4, so we require the ble.sh
version to be larger or equal to 0.4.  We also describe the version
requirement in README.md.

* fix(bash): use ble.sh's contrib/integration/bash-preexec

ble.sh provides module "contrib/integration/bash-preexec", which can
be used with the same interface as bash-preexec.  This module provides
"preexec_functions" and "precmd_functions" without requiring
bash-preexec.

This module also properly handles it when both ble.sh and bash-preexec
are loaded; the module resolves the conflicts between ble.sh and
bash-preexec, and the module also tries to support bash-preexec in the
detached state of ble.sh.

* fix(bash): use ble.sh's accept-line widget for enter_accept

In ble.sh, one can directly call the widget "accept-line" from a shell
script.  The widget "accept-line" is the actual widget that reserves
the command execution in ble.sh, so calling "accept-line" is
equivalent to the normal execution.  It includes all the necessary
adjustments and processing including stty and history.

In addition, the command will be executed at the top-level context
instead in a function scope.  For example, without ble.sh, running
"declare -A dict=()" through enter_accept will create an associative
array in the function scope unexpectedly.  With ble.sh, since the
command is executed at the top-level context, such a problem does not
happen.

When ble.sh is in a detached state, we fall back to the manual
execution of the command.  In this case, we cannot assume the
existence of the shell function "__bp_set_ret_value", so we always use
__atuin_set_ret_value.
  • Loading branch information
akinomyoga authored Dec 28, 2023
1 parent 5401ff1 commit a4122f0
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 42 deletions.
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -274,14 +274,16 @@ antigen bundle atuinsh/atuin@main

#### [ble.sh](https://github.com/akinomyoga/ble.sh)

Atuin works best in bash when using [ble.sh](https://github.com/akinomyoga/ble.sh).
Atuin works best in bash when using [ble.sh](https://github.com/akinomyoga/ble.sh) >= 0.4.

With ble.sh installed, just add atuin to your .bashrc
With ble.sh (>= 0.4) installed, just add atuin to your .bashrc

```bash
echo 'eval "$(atuin init bash)"' >> ~/.bashrc
```

Please make sure that the above line comes after sourcing ble.sh so atuin knows the presence of ble.sh.

#### [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.
Expand Down
78 changes: 38 additions & 40 deletions atuin/src/shell/atuin.bash
Original file line number Diff line number Diff line change
Expand Up @@ -28,25 +28,27 @@ __atuin_history() {
if [[ $HISTORY == __atuin_accept__:* ]]
then
HISTORY=${HISTORY#__atuin_accept__:}
# Reprint the prompt, accounting for multiple lines
local __atuin_prompt_offset
__atuin_prompt_offset=$(echo -n "${PS1@P}" | tr -cd '\n' | wc -c)
if ((__atuin_prompt_offset > 0)); then
tput cuu "$__atuin_prompt_offset"
fi
echo "${PS1@P}$HISTORY"

if [[ -n "${BLE_VERSION-}" ]]; then
blehook/invoke PREEXEC "$HISTORY"
if [[ -n "${BLE_ATTACHED-}" ]]; then
ble-edit/content/reset-and-check-dirty "$HISTORY"
ble/widget/accept-line
else
# Reprint the prompt, accounting for multiple lines
local __atuin_prompt_offset
__atuin_prompt_offset=$(echo -n "${PS1@P}" | tr -cd '\n' | wc -c)
if ((__atuin_prompt_offset > 0)); then
tput cuu "$__atuin_prompt_offset"
fi
echo "${PS1@P}$HISTORY"

# 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:-}"
__atuin_set_ret_value "${__bp_last_ret_value:-}"
"$preexec_function" "$HISTORY"
preexec_function_ret_value="$?"
if [[ "$preexec_function_ret_value" != 0 ]]; then
Expand All @@ -55,35 +57,32 @@ __atuin_history() {
fi
done
# shellcheck disable=SC2154
__bp_set_ret_value "$preexec_ret_value" "$__bp_last_argument_prev_command"
fi
# Juggle the terminal settings so that the command can be interacted with
local stty_backup
stty_backup=$(stty -g)
stty "$ATUIN_STTY"
__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"

eval "$HISTORY"
exit_status=$?
eval "$HISTORY"
exit_status=$?

stty "$stty_backup"
stty "$stty_backup"

# Execute preprompt commands
__atuin_set_ret_value "$exit_status" "$HISTORY"
eval "$PROMPT_COMMAND"
# Need to reexecute the blehook
if [[ -n "${BLE_VERSION-}" ]]; then
# Execute preprompt commands
__atuin_set_ret_value "$exit_status" "$HISTORY"
eval "$PROMPT_COMMAND"
# 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"
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
Expand All @@ -92,10 +91,9 @@ __atuin_history() {
fi
}

if [[ -n "${BLE_VERSION-}" ]]; then
blehook PRECMD-+=__atuin_precmd
blehook PREEXEC-+=__atuin_preexec
else
precmd_functions+=(__atuin_precmd)
preexec_functions+=(__atuin_preexec)
# shellcheck disable=SC2154
if [[ -n "${BLE_VERSION-}" ]] && ((_ble_version >= 400)); then
ble-import contrib/integration/bash-preexec
fi
precmd_functions+=(__atuin_precmd)
preexec_functions+=(__atuin_preexec)

1 comment on commit a4122f0

@vercel
Copy link

@vercel vercel bot commented on a4122f0 Dec 28, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

atuin-docs – ./

atuin-docs-git-main-atuin.vercel.app
atuin-docs-atuin.vercel.app
atuin-docs.vercel.app

Please sign in to comment.