Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(client): add filter mode enablement and ordering configuration #2430

Merged
merged 1 commit into from
Nov 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 14 additions & 3 deletions crates/atuin-client/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,17 @@
## possible values: prefix, fulltext, fuzzy, skim
# search_mode = "fuzzy"

## which filter mode to use
## possible values: global, host, session, directory
## which filter mode to use by default
## possible values: "global", "host", "session", "directory", "workspace"
## consider using search.filters to customize the enablement and order of filter modes
# filter_mode = "global"

## With workspace filtering enabled, Atuin will filter for commands executed
## in any directory within a git repository tree (default: false)
## in any directory within a git repository tree (default: false).
##
## To use workspace mode by default when available, set this to true and
## set filter_mode to "workspace" or leave it unspecified and
## set search.filters to include "workspace" before other filter modes.
# workspaces = false

## which filter mode to use when atuin is invoked from a shell up-key binding
Expand Down Expand Up @@ -254,3 +259,9 @@ records = true
## Whether the theme manager should output normal or extra information to help fix themes.
## Boolean, true or false. If unset, left up to the theme manager.
# debug = true

[search]
## The list of enabled filter modes, in order of priority.
## The "workspace" mode is skipped when not in a workspace or workspaces = false.
## Default filter mode can be overridden with the filter_mode setting.
# filters = [ "global", "host", "session", "workspace", "directory" ]
38 changes: 36 additions & 2 deletions crates/atuin-client/src/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,12 @@ pub struct Daemon {
pub tcp_port: u64,
}

#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct Search {
/// The list of enabled filter modes, in order of priority.
pub filters: Vec<FilterMode>,
}

impl Default for Preview {
fn default() -> Self {
Self {
Expand Down Expand Up @@ -400,6 +406,20 @@ impl Default for Daemon {
}
}

impl Default for Search {
fn default() -> Self {
Self {
filters: vec![
FilterMode::Global,
FilterMode::Host,
FilterMode::Session,
FilterMode::Workspace,
FilterMode::Directory,
],
}
}
}

// The preview height strategy also takes max_preview_height into account.
#[derive(Clone, Debug, Deserialize, Copy, PartialEq, Eq, ValueEnum, Serialize)]
pub enum PreviewStrategy {
Expand Down Expand Up @@ -430,7 +450,7 @@ pub struct Settings {
pub key_path: String,
pub session_path: String,
pub search_mode: SearchMode,
pub filter_mode: FilterMode,
pub filter_mode: Option<FilterMode>,
pub filter_mode_shell_up_key_binding: Option<FilterMode>,
pub search_mode_shell_up_key_binding: Option<SearchMode>,
pub shell_up_key_binding: bool,
Expand Down Expand Up @@ -486,6 +506,9 @@ pub struct Settings {
#[serde(default)]
pub daemon: Daemon,

#[serde(default)]
pub search: Search,

#[serde(default)]
pub theme: Theme,
}
Expand Down Expand Up @@ -688,6 +711,13 @@ impl Settings {
None
}

pub fn default_filter_mode(&self) -> FilterMode {
self.filter_mode
.filter(|x| self.search.filters.contains(x))
.or(self.search.filters.first().copied())
.unwrap_or(FilterMode::Global)
}

#[cfg(not(feature = "check-update"))]
pub async fn needs_update(&self) -> Option<Version> {
None
Expand Down Expand Up @@ -715,7 +745,7 @@ impl Settings {
.set_default("sync_address", "https://api.atuin.sh")?
.set_default("sync_frequency", "10m")?
.set_default("search_mode", "fuzzy")?
.set_default("filter_mode", "global")?
.set_default("filter_mode", None::<String>)?
.set_default("style", "compact")?
.set_default("inline_height", 40)?
.set_default("show_preview", true)?
Expand Down Expand Up @@ -758,6 +788,10 @@ impl Settings {
.set_default("daemon.socket_path", socket_path.to_str())?
.set_default("daemon.systemd_socket", false)?
.set_default("daemon.tcp_port", 8889)?
.set_default(
"search.filters",
vec!["global", "host", "session", "workspace", "directory"],
)?
.set_default("theme.name", "default")?
.set_default("theme.debug", None::<bool>)?
.set_default(
Expand Down
2 changes: 1 addition & 1 deletion crates/atuin/src/command/client/history.rs
Original file line number Diff line number Diff line change
Expand Up @@ -466,7 +466,7 @@ impl Cmd {
(true, true) => [Session, Directory],
(true, false) => [Session, Global],
(false, true) => [Global, Directory],
(false, false) => [settings.filter_mode, Global],
(false, false) => [settings.default_filter_mode(), Global],
};

let history = db
Expand Down
9 changes: 2 additions & 7 deletions crates/atuin/src/command/client/search.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ impl Cmd {
settings.search_mode = self.search_mode.unwrap();
}
if self.filter_mode.is_some() {
settings.filter_mode = self.filter_mode.unwrap();
settings.filter_mode = self.filter_mode;
}
if self.inline_height.is_some() {
settings.inline_height = self.inline_height.unwrap();
Expand Down Expand Up @@ -287,12 +287,7 @@ async fn run_non_interactive(
..filter_options
};

let dir = dir.unwrap_or_else(|| "/".to_string());
let filter_mode = if settings.workspaces && utils::has_git_dir(dir.as_str()) {
FilterMode::Workspace
} else {
settings.filter_mode
};
let filter_mode = settings.default_filter_mode();

let results = db
.search(
Expand Down
28 changes: 27 additions & 1 deletion crates/atuin/src/command/client/search/engines.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use async_trait::async_trait;
use atuin_client::{
database::{Context, Database},
history::History,
settings::{FilterMode, SearchMode},
settings::{FilterMode, SearchMode, Settings},
};
use eyre::Result;

Expand All @@ -24,6 +24,32 @@ pub struct SearchState {
pub context: Context,
}

impl SearchState {
pub(crate) fn rotate_filter_mode(&mut self, settings: &Settings, offset: isize) {
let mut i = settings
.search
.filters
.iter()
.position(|&m| m == self.filter_mode)
.unwrap_or_default();
for _ in 0..settings.search.filters.len() {
i = (i.wrapping_add_signed(offset)) % settings.search.filters.len();
let mode = settings.search.filters[i];
if self.filter_mode_available(mode, settings) {
self.filter_mode = mode;
break;
}
}
}

fn filter_mode_available(&self, mode: FilterMode, settings: &Settings) -> bool {
match mode {
FilterMode::Workspace => settings.workspaces && self.context.git_root.is_some(),
_ => true,
}
}
}

#[async_trait]
pub trait SearchEngine: Send + Sync + 'static {
async fn full_query(
Expand Down
39 changes: 7 additions & 32 deletions crates/atuin/src/command/client/search/interactive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -459,29 +459,7 @@ impl State {
}
}
KeyCode::Char('u') if ctrl => self.search.input.clear(),
KeyCode::Char('r') if ctrl => {
let filter_modes = if settings.workspaces && self.search.context.git_root.is_some()
{
vec![
FilterMode::Global,
FilterMode::Host,
FilterMode::Session,
FilterMode::Directory,
FilterMode::Workspace,
]
} else {
vec![
FilterMode::Global,
FilterMode::Host,
FilterMode::Session,
FilterMode::Directory,
]
};

let i = self.search.filter_mode as usize;
let i = (i + 1) % filter_modes.len();
self.search.filter_mode = filter_modes[i];
}
KeyCode::Char('r') if ctrl => self.search.rotate_filter_mode(settings, 1),
KeyCode::Char('s') if ctrl => {
self.switched_search_mode = true;
self.search_mode = self.search_mode.next(settings);
Expand Down Expand Up @@ -1087,15 +1065,12 @@ pub async fn history(
tab_index: 0,
search: SearchState {
input,
filter_mode: if settings.workspaces && context.git_root.is_some() {
FilterMode::Workspace
} else if settings.shell_up_key_binding {
settings
.filter_mode_shell_up_key_binding
.unwrap_or(settings.filter_mode)
} else {
settings.filter_mode
},
filter_mode: settings
.filter_mode_shell_up_key_binding
.filter(|_| settings.shell_up_key_binding)
.or_else(|| Some(settings.default_filter_mode()))
.filter(|&x| x != FilterMode::Workspace || context.git_root.is_some())
.unwrap_or(FilterMode::Global),
context,
},
engine: engines::engine(search_mode),
Expand Down