Rework atuin init (#652)

* Rework `atuin init`

This allows users to disable the CTRL-R and Up Arrow bindings,
independently from one another

* Document --disable-{ctrl-r,up-arrow}

* Apply suggestions from code review

Co-authored-by: Ellie Huxtable <ellie@elliehuxtable.com>

Co-authored-by: Ellie Huxtable <ellie@elliehuxtable.com>
This commit is contained in:
Jamie Quigley 2022-12-24 17:18:44 +00:00 committed by GitHub
parent ed394afa82
commit a5616aea8f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 135 additions and 84 deletions

View file

@ -53,7 +53,7 @@ I wanted to. And I **really** don't want to.
## Features ## 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 - store shell history in a sqlite database
- backup and sync **encrypted** shell history - backup and sync **encrypted** shell history
- the same history across terminals, across sessions, and across machines - the same history across terminals, across sessions, and across machines

View file

@ -1,11 +1,27 @@
# Key binding # Key binding
By default, Atuin will rebind both <kbd>Ctrl-r</kbd> and the up arrow. If you do not want By default, Atuin will rebind both <kbd>Ctrl-r</kbd> and the up arrow.
this to happen, set ATUIN_NOBIND before the call to `atuin init`
For example You can also disable either the up-arrow or <kbd>Ctrl-r</kbd> 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" export ATUIN_NOBIND="true"
eval "$(atuin init zsh)" 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 to ctrl-r, add any other bindings you want here too
bind -x '"\C-r": __atuin_history' bind -x '"\C-r": __atuin_history'
``` ```
# fish # fish
``` ```

View file

@ -1,7 +1,20 @@
use clap::Parser; use clap::{Parser, ValueEnum};
#[derive(Parser)] #[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 setup
Zsh, Zsh,
/// Bash setup /// Bash setup
@ -10,27 +23,78 @@ pub enum Cmd {
Fish, 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 { impl Cmd {
pub fn run(&self) { fn init_zsh(&self) {
match self { let base = include_str!("../shell/atuin.zsh");
Self::Zsh => init_zsh(),
Self::Bash => init_bash(), println!("{base}");
Self::Fish => init_fish(),
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(),
} }
} }
} }

View file

@ -25,7 +25,6 @@ pub enum AtuinCmd {
Server(server::Cmd), Server(server::Cmd),
/// Output shell setup /// Output shell setup
#[command(subcommand)]
Init(init::Cmd), Init(init::Cmd),
/// Generate a UUID /// Generate a UUID

View file

@ -2,7 +2,8 @@ ATUIN_SESSION=$(atuin uuid)
export ATUIN_SESSION export ATUIN_SESSION
_atuin_preexec() { _atuin_preexec() {
local id; id=$(atuin history start -- "$1") local id
id=$(atuin history start -- "$1")
export ATUIN_HISTORY_ID="${id}" export ATUIN_HISTORY_ID="${id}"
} }
@ -11,11 +12,10 @@ _atuin_precmd() {
[[ -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_history () __atuin_history() {
{
tput rmkx tput rmkx
# shellcheck disable=SC2048,SC2086 # shellcheck disable=SC2048,SC2086
HISTORY="$(RUST_LOG=error atuin search $* -i -- "${READLINE_LINE}" 3>&1 1>&2 2>&3)" HISTORY="$(RUST_LOG=error atuin search $* -i -- "${READLINE_LINE}" 3>&1 1>&2 2>&3)"
@ -32,9 +32,3 @@ else
precmd_functions+=(_atuin_precmd) precmd_functions+=(_atuin_precmd)
preexec_functions+=(_atuin_preexec) preexec_functions+=(_atuin_preexec)
fi 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

View file

@ -38,18 +38,3 @@ function _atuin_bind_up
up-or-search up-or-search
end end
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

View file

@ -12,42 +12,42 @@ autoload -U add-zsh-hook
export ATUIN_SESSION=$(atuin uuid) export ATUIN_SESSION=$(atuin uuid)
export ATUIN_HISTORY="atuin history list" export ATUIN_HISTORY="atuin history list"
_atuin_preexec(){ _atuin_preexec() {
local id; id=$(atuin history start -- "$1") local id
export ATUIN_HISTORY_ID="$id" id=$(atuin history start -- "$1")
export ATUIN_HISTORY_ID="$id"
} }
_atuin_precmd(){ _atuin_precmd() {
local EXIT="$?" 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(){ _atuin_search() {
emulate -L zsh emulate -L zsh
zle -I zle -I
# Switch to cursor mode, then back to application # Switch to cursor mode, then back to application
echoti rmkx echoti rmkx
# swap stderr and stdout, so that the tui stuff works # swap stderr and stdout, so that the tui stuff works
# TODO: not this # TODO: not this
# shellcheck disable=SC2048 # shellcheck disable=SC2048
output=$(RUST_LOG=error atuin search $* -i -- $BUFFER 3>&1 1>&2 2>&3) output=$(RUST_LOG=error atuin search $* -i -- $BUFFER 3>&1 1>&2 2>&3)
echoti smkx echoti smkx
if [[ -n $output ]] ; then if [[ -n $output ]]; then
RBUFFER="" RBUFFER=""
LBUFFER=$output LBUFFER=$output
fi fi
zle reset-prompt zle reset-prompt
} }
_atuin_up_search(){ _atuin_up_search() {
_atuin_search --shell-up-key-binding _atuin_search --shell-up-key-binding
} }
add-zsh-hook preexec _atuin_preexec 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_search_widget _atuin_search
zle -N _atuin_up_search_widget _atuin_up_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