mirror of
https://github.com/atuinsh/atuin.git
synced 2025-01-12 17:28:16 +01:00
fix(bash): fix and improve the keybinding to up
(#1515)
* fix(bash): improve up key in multiline mode of ble.sh ble.sh has a multiline mode where pressing [up] can be used to move to the previous line. The command history is loaded only when the [up] key is pressed when the cursor is in the first line. However, with Atuin's integration, the [up] key always causes Atuin's history search and cannot be used to move to the previous line when the cursor is not in the first line. There is also another situation that the [up] key does not load the command history. In this patch, with ble.sh, we perform Atuin's history search only in the situation where the command history is loaded in the original binding of ble.sh. * fix(init): perform bind on explicitly specified keymaps With the current implementation, the keybindings to [C-r] and [up] are only set up in the currently activated keymaps in Bash. As a result, if the user changes the keymap after `eval "$(atuin init bash)"`, Atuin's keybindings do not take effect. In this patch, we bind Atuin's keybindings in all the keymaps (emacs, vi-insert, and vi-command) by explicitly specifying them (as done for the Zsh integration). The keybinding to "k" in the vi-command keymap is also added to make it consistent with the Zsh integration. * fix(init): work around limitation of "bind -x" in bash <= 4.2 In bash <= 4.2, "bind -x" with a key sequence with more than two bytes does not work properly. Inputting the key sequence will produce an error message saying "bash: bash_execute_unix_command: cannot find keymap for command", and the shell command is not executed. To work around this, we can first translate the key sequences to another key sequence with two bytes and run the shell command through the two-byte key sequence. In this patch, we use \C-x\C-p as the two-byte key sequence. * refactor(bash): move the inlined binding scripts to atuin.bash * refactor(init): use `is_ok()` instead of negating `is_err()` Co-authored-by: Ellie Huxtable <ellie@elliehuxtable.com> --------- Co-authored-by: Ellie Huxtable <ellie@elliehuxtable.com>
This commit is contained in:
parent
31c6ec0be5
commit
7dca752dc3
@ -55,19 +55,15 @@ bindkey -M vicmd 'k' _atuin_up_search_widget";
|
||||
|
||||
fn init_bash(&self) {
|
||||
let base = include_str!("../shell/atuin.bash");
|
||||
println!("{base}");
|
||||
let (bind_ctrl_r, bind_up_arrow) = if std::env::var("ATUIN_NOBIND").is_ok() {
|
||||
(false, false)
|
||||
} else {
|
||||
(!self.disable_ctrl_r, !self.disable_up_arrow)
|
||||
};
|
||||
|
||||
if std::env::var("ATUIN_NOBIND").is_err() {
|
||||
const BIND_CTRL_R: &str = r#"bind -x '"\C-r": __atuin_history'"#;
|
||||
const BIND_UP_ARROW: &str = r#"bind -x '"\e[A": __atuin_history --shell-up-key-binding'
|
||||
bind -x '"\eOA": __atuin_history --shell-up-key-binding'"#;
|
||||
if !self.disable_ctrl_r {
|
||||
println!("{BIND_CTRL_R}");
|
||||
}
|
||||
if !self.disable_up_arrow {
|
||||
println!("{BIND_UP_ARROW}");
|
||||
}
|
||||
}
|
||||
println!("__atuin_bind_ctrl_r={bind_ctrl_r}");
|
||||
println!("__atuin_bind_up_arrow={bind_up_arrow}");
|
||||
println!("{base}");
|
||||
}
|
||||
|
||||
fn init_fish(&self) {
|
||||
|
@ -113,6 +113,26 @@ __atuin_accept_line() {
|
||||
}
|
||||
|
||||
__atuin_history() {
|
||||
# Default action of the up key: When this function is called with the first
|
||||
# argument `--shell-up-key-binding`, we perform Atuin's history search only
|
||||
# when the up key is supposed to cause the history movement in the original
|
||||
# binding. We do this only for ble.sh because the up key always invokes
|
||||
# the history movement in the plain Bash.
|
||||
if [[ ${BLE_ATTACHED-} && ${1-} == --shell-up-key-binding ]]; then
|
||||
# When the current cursor position is not in the first line, the up key
|
||||
# should move the cursor to the previous line. While the selection is
|
||||
# performed, the up key should not start the history search.
|
||||
# shellcheck disable=SC2154 # Note: these variables are set by ble.sh
|
||||
if [[ ${_ble_edit_str::_ble_edit_ind} == *$'\n'* || $_ble_edit_mark_active ]]; then
|
||||
ble/widget/@nomarked backward-line
|
||||
local status=$?
|
||||
READLINE_LINE=$_ble_edit_str
|
||||
READLINE_POINT=$_ble_edit_ind
|
||||
READLINE_MARK=$_ble_edit_mark
|
||||
return "$status"
|
||||
fi
|
||||
fi
|
||||
|
||||
HISTORY="$(ATUIN_SHELL_BASH=t ATUIN_LOG=error atuin search "$@" -i -- "${READLINE_LINE}" 3>&1 1>&2 2>&3)"
|
||||
|
||||
# We do nothing when the search is canceled.
|
||||
@ -161,3 +181,41 @@ if [[ -n "${BLE_VERSION-}" ]] && ((_ble_version >= 400)); then
|
||||
fi
|
||||
precmd_functions+=(__atuin_precmd)
|
||||
preexec_functions+=(__atuin_preexec)
|
||||
|
||||
# shellcheck disable=SC2154
|
||||
if [[ $__atuin_bind_ctrl_r == true ]]; then
|
||||
# Note: We do not overwrite [C-r] in the vi-command keymap for Bash because
|
||||
# we do not want to overwrite "redo", which is already bound to [C-r] in
|
||||
# the vi_nmap keymap in ble.sh.
|
||||
bind -m emacs -x '"\C-r": __atuin_history'
|
||||
bind -m vi-insert -x '"\C-r": __atuin_history'
|
||||
fi
|
||||
|
||||
# shellcheck disable=SC2154
|
||||
if [[ $__atuin_bind_up_arrow == true ]]; then
|
||||
if ((BASH_VERSINFO[0] > 4 || BASH_VERSINFO[0] == 4 && BASH_VERSINFO[1] >= 3)); then
|
||||
bind -m emacs -x '"\e[A": __atuin_history --shell-up-key-binding'
|
||||
bind -m emacs -x '"\eOA": __atuin_history --shell-up-key-binding'
|
||||
bind -m vi-insert -x '"\e[A": __atuin_history --shell-up-key-binding'
|
||||
bind -m vi-insert -x '"\eOA": __atuin_history --shell-up-key-binding'
|
||||
bind -m vi-command -x '"\e[A": __atuin_history --shell-up-key-binding'
|
||||
bind -m vi-command -x '"\eOA": __atuin_history --shell-up-key-binding'
|
||||
bind -m vi-command -x '"k": __atuin_history --shell-up-key-binding'
|
||||
else
|
||||
# In bash < 4.3, "bind -x" cannot bind a shell command to a keyseq
|
||||
# having more than two bytes. To work around this, we first translate
|
||||
# the keyseqs to the two-byte sequence \C-x\C-p (which is not used by
|
||||
# default) using string macros and run the shell command through the
|
||||
# keybinding to \C-x\C-p.
|
||||
bind -m emacs -x '"\C-x\C-p": __atuin_history --shell-up-key-binding'
|
||||
bind -m emacs '"\e[A": "\C-x\C-p"'
|
||||
bind -m emacs '"\eOA": "\C-x\C-p"'
|
||||
bind -m vi-insert -x '"\C-x\C-p": __atuin_history --shell-up-key-binding'
|
||||
bind -m vi-insert -x '"\e[A": "\C-x\C-p"'
|
||||
bind -m vi-insert -x '"\eOA": "\C-x\C-p"'
|
||||
bind -m vi-command -x '"\C-x\C-p": __atuin_history --shell-up-key-binding'
|
||||
bind -m vi-command -x '"\e[A": "\C-x\C-p"'
|
||||
bind -m vi-command -x '"\eOA": "\C-x\C-p"'
|
||||
bind -m vi-command -x '"k": "\C-x\C-p"'
|
||||
fi
|
||||
fi
|
||||
|
Loading…
Reference in New Issue
Block a user