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
- 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

View File

@ -1,11 +1,27 @@
# Key binding
By default, Atuin will rebind both <kbd>Ctrl-r</kbd> 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 <kbd>Ctrl-r</kbd> and the up arrow.
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"
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
```

View File

@ -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(),
}
}
}

View File

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

View File

@ -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

View File

@ -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

View File

@ -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