diff --git a/README.md b/README.md index 2ab2e84..ccc2aa4 100644 --- a/README.md +++ b/README.md @@ -53,7 +53,7 @@ I wanted to. And I **really** don't want to. ## Features -- rebind `up` and `ctrl-r` with a full screen history search UI +- rebind `ctrl-r` and `up` (configurable) to a full screen history search UI - store shell history in a sqlite database - backup and sync **encrypted** shell history - the same history across terminals, across sessions, and across machines diff --git a/docs/key-binding.md b/docs/key-binding.md index 7a96803..013c28b 100644 --- a/docs/key-binding.md +++ b/docs/key-binding.md @@ -1,11 +1,27 @@ # Key binding -By default, Atuin will rebind both Ctrl-r and the up arrow. If you do not want -this to happen, set ATUIN_NOBIND before the call to `atuin init` +By default, Atuin will rebind both Ctrl-r and the up arrow. -For example +You can also disable either the up-arrow or Ctrl-r bindings individually, by passing +`--disable-up-arrow` or `-disable-ctrl-r` to the call to `atuin init`: ``` +# Bind ctrl-r but not up arrow +eval "$(atuin init zsh --disable-up-arrow)" + +# Bind up-arrow but not ctrl-r +eval "$(atuin init zsh --disable-ctrl-r)" +``` + +If you do not want either key to be bound, either pass both `--disable` arguments, or set the +environment varuable `ATUIN_NOBIND` to any value before the call to `atuin init`: + +``` +## Do not bind any keys +# Either: +eval "$(atuin init zsh --disable-up-arrow --disable-ctrl-r)" + +# Or: export ATUIN_NOBIND="true" eval "$(atuin init zsh)" ``` @@ -36,6 +52,7 @@ eval "$(atuin init bash)" # bind to ctrl-r, add any other bindings you want here too bind -x '"\C-r": __atuin_history' ``` + # fish ``` diff --git a/src/command/init.rs b/src/command/init.rs index 7faff03..585a828 100644 --- a/src/command/init.rs +++ b/src/command/init.rs @@ -1,7 +1,20 @@ -use clap::Parser; +use clap::{Parser, ValueEnum}; #[derive(Parser)] -pub enum Cmd { +pub struct Cmd { + shell: Shell, + + /// Disable the binding of CTRL-R to atuin + #[clap(long)] + disable_ctrl_r: bool, + + /// Disable the binding of the Up Arrow key to atuin + #[clap(long)] + disable_up_arrow: bool, +} + +#[derive(Clone, Copy, ValueEnum)] +pub enum Shell { /// Zsh setup Zsh, /// Bash setup @@ -10,27 +23,78 @@ pub enum Cmd { Fish, } -fn init_zsh() { - let full = include_str!("../shell/atuin.zsh"); - println!("{full}"); -} - -fn init_bash() { - let full = include_str!("../shell/atuin.bash"); - println!("{full}"); -} - -fn init_fish() { - let full = include_str!("../shell/atuin.fish"); - println!("{full}"); -} - impl Cmd { - pub fn run(&self) { - match self { - Self::Zsh => init_zsh(), - Self::Bash => init_bash(), - Self::Fish => init_fish(), + fn init_zsh(&self) { + let base = include_str!("../shell/atuin.zsh"); + + println!("{base}"); + + if std::env::var("ATUIN_NOBIND").is_err() { + const BIND_CTRL_R: &str = "bindkey '^r' _atuin_search_widget"; + const BIND_UP_ARROW: &str = "bindkey '^[[A' _atuin_up_search_widget +bindkey '^[OA' _atuin_up_search_widget"; + if !self.disable_ctrl_r { + println!("{BIND_CTRL_R}"); + } + if !self.disable_up_arrow { + println!("{BIND_UP_ARROW}"); + } + } + } + + fn init_bash(&self) { + let base = include_str!("../shell/atuin.bash"); + println!("{base}"); + + 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}"); + } + } + } + + fn init_fish(&self) { + let full = include_str!("../shell/atuin.fish"); + println!("{full}"); + + if std::env::var("ATUIN_NOBIND").is_err() { + const BIND_CTRL_R: &str = r"bind \cr _atuin_search"; + const BIND_UP_ARROW: &str = r"bind -k up _atuin_bind_up +bind \eOA _atuin_bind_up +bind \e\[A _atuin_bind_up"; + const BIND_CTRL_R_INS: &str = r"bind -M insert \cr _atuin_search"; + const BIND_UP_ARROW_INS: &str = r"bind -M insert -k up _atuin_bind_up +bind -M insert \eOA _atuin_bind_up +bind -M insert \e\[A _atuin_bind_up"; + + if !self.disable_ctrl_r { + println!("{BIND_CTRL_R}"); + } + if !self.disable_up_arrow { + println!("{BIND_UP_ARROW}"); + } + + println!("if bind -M insert > /dev/null 2>&1"); + if !self.disable_ctrl_r { + println!("{BIND_CTRL_R_INS}"); + } + if !self.disable_up_arrow { + println!("{BIND_UP_ARROW_INS}"); + } + println!("end"); + } + } + pub fn run(self) { + match self.shell { + Shell::Zsh => self.init_zsh(), + Shell::Bash => self.init_bash(), + Shell::Fish => self.init_fish(), } } } diff --git a/src/command/mod.rs b/src/command/mod.rs index 038b24c..1411bfd 100644 --- a/src/command/mod.rs +++ b/src/command/mod.rs @@ -25,7 +25,6 @@ pub enum AtuinCmd { Server(server::Cmd), /// Output shell setup - #[command(subcommand)] Init(init::Cmd), /// Generate a UUID diff --git a/src/shell/atuin.bash b/src/shell/atuin.bash index 9c8fa23..1056dcf 100644 --- a/src/shell/atuin.bash +++ b/src/shell/atuin.bash @@ -2,7 +2,8 @@ ATUIN_SESSION=$(atuin uuid) export ATUIN_SESSION _atuin_preexec() { - local id; id=$(atuin history start -- "$1") + local id + id=$(atuin history start -- "$1") export ATUIN_HISTORY_ID="${id}" } @@ -11,11 +12,10 @@ _atuin_precmd() { [[ -z "${ATUIN_HISTORY_ID}" ]] && return - (RUST_LOG=error atuin history end --exit "${EXIT}" -- "${ATUIN_HISTORY_ID}" &) > /dev/null 2>&1 + (RUST_LOG=error atuin history end --exit "${EXIT}" -- "${ATUIN_HISTORY_ID}" &) >/dev/null 2>&1 } -__atuin_history () -{ +__atuin_history() { tput rmkx # shellcheck disable=SC2048,SC2086 HISTORY="$(RUST_LOG=error atuin search $* -i -- "${READLINE_LINE}" 3>&1 1>&2 2>&3)" @@ -32,9 +32,3 @@ else precmd_functions+=(_atuin_precmd) preexec_functions+=(_atuin_preexec) fi - -if [[ -z ${ATUIN_NOBIND} ]]; then - bind -x '"\C-r": __atuin_history' - bind -x '"\e[A": __atuin_history --shell-up-key-binding' - bind -x '"\eOA": __atuin_history --shell-up-key-binding' -fi diff --git a/src/shell/atuin.fish b/src/shell/atuin.fish index 9446907..727d137 100644 --- a/src/shell/atuin.fish +++ b/src/shell/atuin.fish @@ -38,18 +38,3 @@ function _atuin_bind_up up-or-search end end - -if test -z $ATUIN_NOBIND - bind \cr _atuin_search - bind -k up _atuin_bind_up - bind \eOA _atuin_bind_up - bind \e\[A _atuin_bind_up - - - if bind -M insert > /dev/null 2>&1 - bind -M insert \cr _atuin_search - bind -M insert -k up _atuin_bind_up - bind -M insert \eOA _atuin_bind_up - bind -M insert \e\[A _atuin_bind_up - end -end diff --git a/src/shell/atuin.zsh b/src/shell/atuin.zsh index dd5c1af..b0e160f 100644 --- a/src/shell/atuin.zsh +++ b/src/shell/atuin.zsh @@ -12,42 +12,42 @@ autoload -U add-zsh-hook export ATUIN_SESSION=$(atuin uuid) export ATUIN_HISTORY="atuin history list" -_atuin_preexec(){ - local id; id=$(atuin history start -- "$1") - export ATUIN_HISTORY_ID="$id" +_atuin_preexec() { + local id + id=$(atuin history start -- "$1") + export ATUIN_HISTORY_ID="$id" } -_atuin_precmd(){ - local EXIT="$?" +_atuin_precmd() { + local EXIT="$?" - [[ -z "${ATUIN_HISTORY_ID}" ]] && return + [[ -z "${ATUIN_HISTORY_ID}" ]] && return - - (RUST_LOG=error atuin history end --exit $EXIT -- $ATUIN_HISTORY_ID &) > /dev/null 2>&1 + (RUST_LOG=error atuin history end --exit $EXIT -- $ATUIN_HISTORY_ID &) >/dev/null 2>&1 } -_atuin_search(){ - emulate -L zsh - zle -I +_atuin_search() { + emulate -L zsh + zle -I - # Switch to cursor mode, then back to application - echoti rmkx - # swap stderr and stdout, so that the tui stuff works - # TODO: not this + # Switch to cursor mode, then back to application + echoti rmkx + # swap stderr and stdout, so that the tui stuff works + # TODO: not this # shellcheck disable=SC2048 - output=$(RUST_LOG=error atuin search $* -i -- $BUFFER 3>&1 1>&2 2>&3) - echoti smkx + output=$(RUST_LOG=error atuin search $* -i -- $BUFFER 3>&1 1>&2 2>&3) + echoti smkx - if [[ -n $output ]] ; then - RBUFFER="" - LBUFFER=$output - fi + if [[ -n $output ]]; then + RBUFFER="" + LBUFFER=$output + fi - zle reset-prompt + zle reset-prompt } -_atuin_up_search(){ - _atuin_search --shell-up-key-binding +_atuin_up_search() { + _atuin_search --shell-up-key-binding } add-zsh-hook preexec _atuin_preexec @@ -55,11 +55,3 @@ add-zsh-hook precmd _atuin_precmd zle -N _atuin_search_widget _atuin_search zle -N _atuin_up_search_widget _atuin_up_search - -if [[ -z $ATUIN_NOBIND ]]; then - bindkey '^r' _atuin_search_widget - - # depends on terminal mode - bindkey '^[[A' _atuin_up_search_widget - bindkey '^[OA' _atuin_up_search_widget -fi