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:
parent
dcbe84b9af
commit
ed394afa82
10 changed files with 67 additions and 16 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -110,6 +110,7 @@ dependencies = [
|
||||||
"atuin-common",
|
"atuin-common",
|
||||||
"base64 0.20.0",
|
"base64 0.20.0",
|
||||||
"chrono",
|
"chrono",
|
||||||
|
"clap",
|
||||||
"config",
|
"config",
|
||||||
"directories",
|
"directories",
|
||||||
"eyre",
|
"eyre",
|
||||||
|
|
|
@ -27,6 +27,7 @@ atuin-common = { path = "../atuin-common", version = "12.0.0" }
|
||||||
|
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
chrono = { version = "0.4", features = ["serde"] }
|
chrono = { version = "0.4", features = ["serde"] }
|
||||||
|
clap = { version = "4.0.18", features = ["derive"] }
|
||||||
eyre = "0.6"
|
eyre = "0.6"
|
||||||
directories = "4"
|
directories = "4"
|
||||||
uuid = { version = "1.2", features = ["v4"] }
|
uuid = { version = "1.2", features = ["v4"] }
|
||||||
|
|
|
@ -4,6 +4,7 @@ use std::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use chrono::{prelude::*, Utc};
|
use chrono::{prelude::*, Utc};
|
||||||
|
use clap::ValueEnum;
|
||||||
use config::{Config, Environment, File as ConfigFile, FileFormat};
|
use config::{Config, Environment, File as ConfigFile, FileFormat};
|
||||||
use eyre::{eyre, Context, Result};
|
use eyre::{eyre, Context, Result};
|
||||||
use fs_err::{create_dir_all, File};
|
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 LAST_VERSION_CHECK_FILENAME: &str = "last_version_check_time";
|
||||||
pub const LATEST_VERSION_FILENAME: &str = "latest_version";
|
pub const LATEST_VERSION_FILENAME: &str = "latest_version";
|
||||||
|
|
||||||
#[derive(Clone, Debug, Deserialize, Copy)]
|
#[derive(Clone, Debug, Deserialize, Copy, ValueEnum)]
|
||||||
pub enum SearchMode {
|
pub enum SearchMode {
|
||||||
#[serde(rename = "prefix")]
|
#[serde(rename = "prefix")]
|
||||||
Prefix,
|
Prefix,
|
||||||
|
@ -28,7 +29,7 @@ pub enum SearchMode {
|
||||||
Fuzzy,
|
Fuzzy,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Deserialize, Copy, PartialEq, Eq)]
|
#[derive(Clone, Debug, Deserialize, Copy, PartialEq, Eq, ValueEnum)]
|
||||||
pub enum FilterMode {
|
pub enum FilterMode {
|
||||||
#[serde(rename = "global")]
|
#[serde(rename = "global")]
|
||||||
Global = 0,
|
Global = 0,
|
||||||
|
@ -108,6 +109,8 @@ pub struct Settings {
|
||||||
pub session_path: String,
|
pub session_path: String,
|
||||||
pub search_mode: SearchMode,
|
pub search_mode: SearchMode,
|
||||||
pub filter_mode: FilterMode,
|
pub filter_mode: FilterMode,
|
||||||
|
pub filter_mode_shell_up_key_binding: FilterMode,
|
||||||
|
pub shell_up_key_binding: bool,
|
||||||
pub exit_mode: ExitMode,
|
pub exit_mode: ExitMode,
|
||||||
// This is automatically loaded when settings is created. Do not set in
|
// This is automatically loaded when settings is created. Do not set in
|
||||||
// config! Keep secrets and settings apart.
|
// config! Keep secrets and settings apart.
|
||||||
|
@ -288,6 +291,8 @@ impl Settings {
|
||||||
.set_default("sync_address", "https://api.atuin.sh")?
|
.set_default("sync_address", "https://api.atuin.sh")?
|
||||||
.set_default("search_mode", "fuzzy")?
|
.set_default("search_mode", "fuzzy")?
|
||||||
.set_default("filter_mode", "global")?
|
.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("exit_mode", "return-original")?
|
||||||
.set_default("session_token", "")?
|
.set_default("session_token", "")?
|
||||||
.set_default("style", "auto")?
|
.set_default("style", "auto")?
|
||||||
|
|
|
@ -49,7 +49,7 @@ auto_sync = true/false
|
||||||
|
|
||||||
### `update_check`
|
### `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.
|
true.
|
||||||
|
|
||||||
```
|
```
|
||||||
|
@ -143,6 +143,16 @@ Filter modes can still be toggled via ctrl-r
|
||||||
filter_mode = "host"
|
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`
|
### `exit_mode`
|
||||||
|
|
||||||
What to do when the escape key is pressed when searching
|
What to do when the escape key is pressed when searching
|
||||||
|
|
|
@ -44,7 +44,7 @@ impl Cmd {
|
||||||
.parse_env("ATUIN_LOG")
|
.parse_env("ATUIN_LOG")
|
||||||
.init();
|
.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 db_path = PathBuf::from(settings.db_path.as_str());
|
||||||
let mut db = Sqlite::new(db_path).await?;
|
let mut db = Sqlite::new(db_path).await?;
|
||||||
|
@ -53,7 +53,7 @@ impl Cmd {
|
||||||
Self::History(history) => history.run(&settings, &mut db).await,
|
Self::History(history) => history.run(&settings, &mut db).await,
|
||||||
Self::Import(import) => import.run(&mut db).await,
|
Self::Import(import) => import.run(&mut db).await,
|
||||||
Self::Stats(stats) => stats.run(&mut db, &settings).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")]
|
#[cfg(feature = "sync")]
|
||||||
Self::Sync(sync) => sync.run(settings, &mut db).await,
|
Self::Sync(sync) => sync.run(settings, &mut db).await,
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,10 @@ use clap::Parser;
|
||||||
use eyre::Result;
|
use eyre::Result;
|
||||||
|
|
||||||
use atuin_client::{
|
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;
|
use super::history::ListMode;
|
||||||
|
@ -15,6 +18,7 @@ mod history_list;
|
||||||
mod interactive;
|
mod interactive;
|
||||||
pub use duration::format_duration;
|
pub use duration::format_duration;
|
||||||
|
|
||||||
|
#[allow(clippy::struct_excessive_bools)]
|
||||||
#[derive(Parser)]
|
#[derive(Parser)]
|
||||||
pub struct Cmd {
|
pub struct Cmd {
|
||||||
/// Filter search result by directory
|
/// Filter search result by directory
|
||||||
|
@ -49,6 +53,18 @@ pub struct Cmd {
|
||||||
#[arg(long, short)]
|
#[arg(long, short)]
|
||||||
interactive: bool,
|
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
|
/// Use human-readable formatting for time
|
||||||
#[arg(long)]
|
#[arg(long)]
|
||||||
human: bool,
|
human: bool,
|
||||||
|
@ -61,7 +77,14 @@ pub struct Cmd {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl 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 {
|
if self.interactive {
|
||||||
let item = interactive::history(&self.query, settings, db).await?;
|
let item = interactive::history(&self.query, settings, db).await?;
|
||||||
eprintln!("{item}");
|
eprintln!("{item}");
|
||||||
|
|
|
@ -329,7 +329,11 @@ pub async fn history(
|
||||||
input,
|
input,
|
||||||
results_state: ListState::default(),
|
results_state: ListState::default(),
|
||||||
context: current_context(),
|
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,
|
update_needed,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,8 @@ _atuin_precmd() {
|
||||||
__atuin_history ()
|
__atuin_history ()
|
||||||
{
|
{
|
||||||
tput rmkx
|
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
|
tput smkx
|
||||||
|
|
||||||
READLINE_LINE=${HISTORY}
|
READLINE_LINE=${HISTORY}
|
||||||
|
@ -34,6 +35,6 @@ fi
|
||||||
|
|
||||||
if [[ -z ${ATUIN_NOBIND} ]]; then
|
if [[ -z ${ATUIN_NOBIND} ]]; then
|
||||||
bind -x '"\C-r": __atuin_history'
|
bind -x '"\C-r": __atuin_history'
|
||||||
bind -x '"\e[A": __atuin_history'
|
bind -x '"\e[A": __atuin_history --shell-up-key-binding'
|
||||||
bind -x '"\eOA": __atuin_history'
|
bind -x '"\eOA": __atuin_history --shell-up-key-binding'
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -15,7 +15,7 @@ function _atuin_postexec --on-event fish_postexec
|
||||||
end
|
end
|
||||||
|
|
||||||
function _atuin_search
|
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
|
commandline -f repaint
|
||||||
if test -n "$h"
|
if test -n "$h"
|
||||||
commandline -r $h
|
commandline -r $h
|
||||||
|
@ -33,7 +33,7 @@ function _atuin_bind_up
|
||||||
set -l lineno (commandline --line)
|
set -l lineno (commandline --line)
|
||||||
switch $lineno
|
switch $lineno
|
||||||
case 1
|
case 1
|
||||||
_atuin_search
|
_atuin_search --shell-up-key-binding
|
||||||
case '*'
|
case '*'
|
||||||
up-or-search
|
up-or-search
|
||||||
end
|
end
|
||||||
|
|
|
@ -34,7 +34,8 @@ _atuin_search(){
|
||||||
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
|
||||||
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
|
echoti smkx
|
||||||
|
|
||||||
if [[ -n $output ]] ; then
|
if [[ -n $output ]] ; then
|
||||||
|
@ -45,15 +46,20 @@ _atuin_search(){
|
||||||
zle reset-prompt
|
zle reset-prompt
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_atuin_up_search(){
|
||||||
|
_atuin_search --shell-up-key-binding
|
||||||
|
}
|
||||||
|
|
||||||
add-zsh-hook preexec _atuin_preexec
|
add-zsh-hook preexec _atuin_preexec
|
||||||
add-zsh-hook precmd _atuin_precmd
|
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
|
||||||
|
|
||||||
if [[ -z $ATUIN_NOBIND ]]; then
|
if [[ -z $ATUIN_NOBIND ]]; then
|
||||||
bindkey '^r' _atuin_search_widget
|
bindkey '^r' _atuin_search_widget
|
||||||
|
|
||||||
# depends on terminal mode
|
# depends on terminal mode
|
||||||
bindkey '^[[A' _atuin_search_widget
|
bindkey '^[[A' _atuin_up_search_widget
|
||||||
bindkey '^[OA' _atuin_search_widget
|
bindkey '^[OA' _atuin_up_search_widget
|
||||||
fi
|
fi
|
||||||
|
|
Loading…
Reference in a new issue