Allow overriding filter and search modes from CLI (#635)

* Allow overriding filter and search modes from CLI arguments

* Use session filter mode for bash up key binding

* We precisely do not want to add quotes here so that all arguments are properly passed

* Add --shell-up-key-binding hidden command argument and filter_mode_shell_up_key_binding configuration option to allow customizing the filter mode used when atuin is invoked from a shell up-key binding

* Correct up binding for zsh

Co-authored-by: Ellie Huxtable <ellie@elliehuxtable.com>
This commit is contained in:
Patrick Decat 2022-12-18 19:26:09 +01:00 committed by GitHub
parent dcbe84b9af
commit ed394afa82
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 67 additions and 16 deletions

1
Cargo.lock generated
View file

@ -110,6 +110,7 @@ dependencies = [
"atuin-common",
"base64 0.20.0",
"chrono",
"clap",
"config",
"directories",
"eyre",

View file

@ -27,6 +27,7 @@ atuin-common = { path = "../atuin-common", version = "12.0.0" }
log = "0.4"
chrono = { version = "0.4", features = ["serde"] }
clap = { version = "4.0.18", features = ["derive"] }
eyre = "0.6"
directories = "4"
uuid = { version = "1.2", features = ["v4"] }

View file

@ -4,6 +4,7 @@ use std::{
};
use chrono::{prelude::*, Utc};
use clap::ValueEnum;
use config::{Config, Environment, File as ConfigFile, FileFormat};
use eyre::{eyre, Context, Result};
use fs_err::{create_dir_all, File};
@ -16,7 +17,7 @@ pub const LAST_SYNC_FILENAME: &str = "last_sync_time";
pub const LAST_VERSION_CHECK_FILENAME: &str = "last_version_check_time";
pub const LATEST_VERSION_FILENAME: &str = "latest_version";
#[derive(Clone, Debug, Deserialize, Copy)]
#[derive(Clone, Debug, Deserialize, Copy, ValueEnum)]
pub enum SearchMode {
#[serde(rename = "prefix")]
Prefix,
@ -28,7 +29,7 @@ pub enum SearchMode {
Fuzzy,
}
#[derive(Clone, Debug, Deserialize, Copy, PartialEq, Eq)]
#[derive(Clone, Debug, Deserialize, Copy, PartialEq, Eq, ValueEnum)]
pub enum FilterMode {
#[serde(rename = "global")]
Global = 0,
@ -108,6 +109,8 @@ pub struct Settings {
pub session_path: String,
pub search_mode: SearchMode,
pub filter_mode: FilterMode,
pub filter_mode_shell_up_key_binding: FilterMode,
pub shell_up_key_binding: bool,
pub exit_mode: ExitMode,
// This is automatically loaded when settings is created. Do not set in
// config! Keep secrets and settings apart.
@ -288,6 +291,8 @@ impl Settings {
.set_default("sync_address", "https://api.atuin.sh")?
.set_default("search_mode", "fuzzy")?
.set_default("filter_mode", "global")?
.set_default("filter_mode_shell_up_key_binding", "global")?
.set_default("shell_up_key_binding", false)?
.set_default("exit_mode", "return-original")?
.set_default("session_token", "")?
.set_default("style", "auto")?

View file

@ -49,7 +49,7 @@ auto_sync = true/false
### `update_check`
Configures whether or not to automatically check for updates. Defaults to
Configures whether or not to automatically check for updates. Defaults to
true.
```
@ -143,6 +143,16 @@ Filter modes can still be toggled via ctrl-r
filter_mode = "host"
```
### `filter_mode_shell_up_key_binding`
The default filter to use when searching and being invoked from a shell up-key binding.
Accepts exactly the same options as `filter_mode` above
```
filter_mode_shell_up_key_binding = "session"
```
### `exit_mode`
What to do when the escape key is pressed when searching

View file

@ -44,7 +44,7 @@ impl Cmd {
.parse_env("ATUIN_LOG")
.init();
let settings = Settings::new().wrap_err("could not load client settings")?;
let mut settings = Settings::new().wrap_err("could not load client settings")?;
let db_path = PathBuf::from(settings.db_path.as_str());
let mut db = Sqlite::new(db_path).await?;
@ -53,7 +53,7 @@ impl Cmd {
Self::History(history) => history.run(&settings, &mut db).await,
Self::Import(import) => import.run(&mut db).await,
Self::Stats(stats) => stats.run(&mut db, &settings).await,
Self::Search(search) => search.run(&mut db, &settings).await,
Self::Search(search) => search.run(&mut db, &mut settings).await,
#[cfg(feature = "sync")]
Self::Sync(sync) => sync.run(settings, &mut db).await,
}

View file

@ -3,7 +3,10 @@ use clap::Parser;
use eyre::Result;
use atuin_client::{
database::current_context, database::Database, history::History, settings::Settings,
database::current_context,
database::Database,
history::History,
settings::{FilterMode, SearchMode, Settings},
};
use super::history::ListMode;
@ -15,6 +18,7 @@ mod history_list;
mod interactive;
pub use duration::format_duration;
#[allow(clippy::struct_excessive_bools)]
#[derive(Parser)]
pub struct Cmd {
/// Filter search result by directory
@ -49,6 +53,18 @@ pub struct Cmd {
#[arg(long, short)]
interactive: bool,
/// Allow overriding filter mode over config
#[arg(long = "filter-mode")]
filter_mode: Option<FilterMode>,
/// Allow overriding search mode over config
#[arg(long = "search-mode")]
search_mode: Option<SearchMode>,
/// Marker argument used to inform atuin that it was invoked from a shell up-key binding (hidden from help to avoid confusion)
#[arg(long = "shell-up-key-binding", hide = true)]
shell_up_key_binding: bool,
/// Use human-readable formatting for time
#[arg(long)]
human: bool,
@ -61,7 +77,14 @@ pub struct Cmd {
}
impl Cmd {
pub async fn run(self, db: &mut impl Database, settings: &Settings) -> Result<()> {
pub async fn run(self, db: &mut impl Database, settings: &mut Settings) -> Result<()> {
if self.search_mode.is_some() {
settings.search_mode = self.search_mode.unwrap();
}
if self.filter_mode.is_some() {
settings.filter_mode = self.filter_mode.unwrap();
}
settings.shell_up_key_binding = self.shell_up_key_binding;
if self.interactive {
let item = interactive::history(&self.query, settings, db).await?;
eprintln!("{item}");

View file

@ -329,7 +329,11 @@ pub async fn history(
input,
results_state: ListState::default(),
context: current_context(),
filter_mode: settings.filter_mode,
filter_mode: if settings.shell_up_key_binding {
settings.filter_mode_shell_up_key_binding
} else {
settings.filter_mode
},
update_needed,
};

View file

@ -17,7 +17,8 @@ _atuin_precmd() {
__atuin_history ()
{
tput rmkx
HISTORY="$(RUST_LOG=error atuin search -i -- "${READLINE_LINE}" 3>&1 1>&2 2>&3)"
# shellcheck disable=SC2048,SC2086
HISTORY="$(RUST_LOG=error atuin search $* -i -- "${READLINE_LINE}" 3>&1 1>&2 2>&3)"
tput smkx
READLINE_LINE=${HISTORY}
@ -34,6 +35,6 @@ fi
if [[ -z ${ATUIN_NOBIND} ]]; then
bind -x '"\C-r": __atuin_history'
bind -x '"\e[A": __atuin_history'
bind -x '"\eOA": __atuin_history'
bind -x '"\e[A": __atuin_history --shell-up-key-binding'
bind -x '"\eOA": __atuin_history --shell-up-key-binding'
fi

View file

@ -15,7 +15,7 @@ function _atuin_postexec --on-event fish_postexec
end
function _atuin_search
set h (RUST_LOG=error atuin search -i -- (commandline -b) 3>&1 1>&2 2>&3)
set h (RUST_LOG=error atuin search $* -i -- (commandline -b) 3>&1 1>&2 2>&3)
commandline -f repaint
if test -n "$h"
commandline -r $h
@ -33,7 +33,7 @@ function _atuin_bind_up
set -l lineno (commandline --line)
switch $lineno
case 1
_atuin_search
_atuin_search --shell-up-key-binding
case '*'
up-or-search
end

View file

@ -34,7 +34,8 @@ _atuin_search(){
echoti rmkx
# swap stderr and stdout, so that the tui stuff works
# TODO: not this
output=$(RUST_LOG=error atuin search -i -- $BUFFER 3>&1 1>&2 2>&3)
# shellcheck disable=SC2048
output=$(RUST_LOG=error atuin search $* -i -- $BUFFER 3>&1 1>&2 2>&3)
echoti smkx
if [[ -n $output ]] ; then
@ -45,15 +46,20 @@ _atuin_search(){
zle reset-prompt
}
_atuin_up_search(){
_atuin_search --shell-up-key-binding
}
add-zsh-hook preexec _atuin_preexec
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_search_widget
bindkey '^[OA' _atuin_search_widget
bindkey '^[[A' _atuin_up_search_widget
bindkey '^[OA' _atuin_up_search_widget
fi