aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--atuin/src/command/init.rs20
-rw-r--r--atuin/src/shell/atuin.bash58
2 files changed, 66 insertions, 12 deletions
diff --git a/atuin/src/command/init.rs b/atuin/src/command/init.rs
index eea4fa48..4eae98d3 100644
--- a/atuin/src/command/init.rs
+++ b/atuin/src/command/init.rs
@@ -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) {
diff --git a/atuin/src/shell/atuin.bash b/atuin/src/shell/atuin.bash
index cf68c854..ae17ff29 100644
--- a/atuin/src/shell/atuin.bash
+++ b/atuin/src/shell/atuin.bash
@@ -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