diff options
| author | Lucas Trzesniewski <lucas.trzesniewski@gmail.com> | 2026-02-12 01:06:11 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-02-11 16:06:11 -0800 |
| commit | 6076b6b36bf1faffee41e958acdfc0a00bf3ecc3 (patch) | |
| tree | ae9c3e4458aabbfb09872d30488a4162a4e05ad4 | |
| parent | chore: update changelog (diff) | |
| download | atuin-6076b6b36bf1faffee41e958acdfc0a00bf3ecc3.zip | |
feat: `switch-context` (#3149)
This PR lets you change the current search context to the one of the
currently selected command, which lets you easily see the surrounding
commands of its session.
It adds the following:
- `switch-context` and `clear-context` actions
- A `has-context` condition
- `CTX:` and `C>` prefixes to show we're in another context
The `switch-context` behavior is as follows:
- The selected command defines the new context
- The filter mode is automatically switched to SESSION
- The search input is cleared, which gives you a full overview of the
other commands executed in the same session
- The command which triggered this mode keeps being selected to get a
clear overview
- The filter mode can be changed to modes such as DIRECTORY, but not to
GLOBAL or SESSION+ as IMO those would be confusing in this mode
This lets you easily navigate between modes and commands the way you
prefer, for instance by switching the context through selected commands
or switching back to the default mode with the same key.
This could certainly still be improved (the docs are missing for
instance), and if you have any feedback I can change the behavior as you
see fit. I can add the docs when you'll approve the new names.
Closes #2784
## Checks
- [x] I am happy for maintainers to push small adjustments to this PR,
to speed up the review cycle
- [x] I have checked that there are no existing pull requests for the
same thing
---------
Co-authored-by: Ellie Huxtable <ellie@elliehuxtable.com>
Diffstat (limited to '')
| -rw-r--r-- | crates/atuin-client/src/database.rs | 13 | ||||
| -rw-r--r-- | crates/atuin/src/command/client/search/engines.rs | 4 | ||||
| -rw-r--r-- | crates/atuin/src/command/client/search/interactive.rs | 93 | ||||
| -rw-r--r-- | crates/atuin/src/command/client/search/keybindings/actions.rs | 6 | ||||
| -rw-r--r-- | crates/atuin/src/command/client/search/keybindings/conditions.rs | 15 | ||||
| -rw-r--r-- | crates/atuin/src/command/client/search/keybindings/defaults.rs | 10 | ||||
| -rw-r--r-- | crates/atuin/src/command/client/search/keybindings/keymap.rs | 1 | ||||
| -rw-r--r-- | docs/docs/configuration/advanced-key-binding.md | 3 | ||||
| -rw-r--r-- | docs/docs/configuration/config.md | 15 | ||||
| -rw-r--r-- | docs/docs/configuration/key-binding.md | 21 | ||||
| -rw-r--r-- | docs/docs/guide/advanced-usage.md | 49 | ||||
| -rw-r--r-- | docs/docs/guide/basic-usage.md | 2 | ||||
| -rw-r--r-- | docs/mkdocs.yml | 1 |
13 files changed, 206 insertions, 27 deletions
diff --git a/crates/atuin-client/src/database.rs b/crates/atuin-client/src/database.rs index 28d6c0f0..7aa095f7 100644 --- a/crates/atuin-client/src/database.rs +++ b/crates/atuin-client/src/database.rs @@ -32,6 +32,7 @@ use super::{ settings::{FilterMode, SearchMode, Settings}, }; +#[derive(Clone)] pub struct Context { pub session: String, pub cwd: String, @@ -72,6 +73,18 @@ pub async fn current_context() -> eyre::Result<Context> { }) } +impl Context { + pub fn from_history(entry: &History) -> Self { + Context { + session: entry.session.to_string(), + cwd: entry.cwd.to_string(), + hostname: entry.hostname.to_string(), + host_id: String::new(), + git_root: utils::in_git_repo(entry.cwd.as_str()), + } + } +} + fn get_session_start_time(session_id: &str) -> Option<i64> { if let Ok(uuid) = Uuid::parse_str(session_id) && let Some(timestamp) = uuid.get_timestamp() diff --git a/crates/atuin/src/command/client/search/engines.rs b/crates/atuin/src/command/client/search/engines.rs index 95d6658b..5c53817e 100644 --- a/crates/atuin/src/command/client/search/engines.rs +++ b/crates/atuin/src/command/client/search/engines.rs @@ -1,7 +1,7 @@ use async_trait::async_trait; use atuin_client::{ database::{Context, Database}, - history::History, + history::{History, HistoryId}, settings::{FilterMode, SearchMode, Settings}, }; use eyre::Result; @@ -22,6 +22,7 @@ pub struct SearchState { pub input: Cursor, pub filter_mode: FilterMode, pub context: Context, + pub custom_context: Option<HistoryId>, } impl SearchState { @@ -44,6 +45,7 @@ impl SearchState { fn filter_mode_available(&self, mode: FilterMode, settings: &Settings) -> bool { match mode { + FilterMode::Global | FilterMode::SessionPreload => self.custom_context.is_none(), FilterMode::Workspace => settings.workspaces && self.context.git_root.is_some(), _ => true, } diff --git a/crates/atuin/src/command/client/search/interactive.rs b/crates/atuin/src/command/client/search/interactive.rs index b5186706..c6a6064a 100644 --- a/crates/atuin/src/command/client/search/interactive.rs +++ b/crates/atuin/src/command/client/search/interactive.rs @@ -16,10 +16,11 @@ use super::{ history_list::{HistoryList, ListState}, }; use atuin_client::{ - database::{Database, current_context}, + database::{Context, Database, current_context}, history::{History, HistoryId, HistoryStats, store::HistoryStore}, settings::{ - CursorStyle, ExitMode, KeymapMode, PreviewStrategy, SearchMode, Settings, UiColumn, + CursorStyle, ExitMode, FilterMode, KeymapMode, PreviewStrategy, SearchMode, Settings, + UiColumn, }, }; @@ -59,6 +60,7 @@ pub enum InputAction { ReturnQuery, Continue, Redraw, + SwitchContext(Option<usize>), } #[derive(Clone)] @@ -304,6 +306,7 @@ impl State { selected_index: self.results_state.selected(), results_len: self.results_len, original_input_empty: self.original_input_empty, + has_context: self.search.custom_context.is_some(), }; // Convert KeyEvent to SingleKey @@ -657,6 +660,10 @@ impl State { self.engine = engines::engine(self.search_mode); InputAction::Continue } + Action::SwitchContext => { + InputAction::SwitchContext(Some(self.results_state.selected())) + } + Action::ClearContext => InputAction::SwitchContext(None), Action::ToggleTab => { self.tab_index = (self.tab_index + 1) % TAB_TITLES.len(); InputAction::Continue @@ -916,6 +923,11 @@ impl State { Compactness::Ultracompact => { if self.switched_search_mode { format!("S{}>", self.search_mode.as_str().chars().next().unwrap()) + } else if self.search.custom_context.is_some() { + format!( + "C{}>", + self.search.filter_mode.as_str().chars().next().unwrap() + ) } else { format!( "{}> ", @@ -1166,6 +1178,8 @@ impl State { fn build_input(&self, style: StyleState, prefix_width: u16) -> Paragraph<'_> { let (pref, mode) = if self.switched_search_mode { (" SRCH:", self.search_mode.as_str()) + } else if self.search.custom_context.is_some() { + (" CTX:", self.search.filter_mode.as_str()) } else { ("", self.search.filter_mode.as_str()) }; @@ -1372,7 +1386,7 @@ pub async fn history( let update_needed = tokio::spawn(async move { settings2.needs_update().await }).fuse(); tokio::pin!(update_needed); - let context = current_context().await?; + let initial_context = current_context().await?; let history_count = db.history_count(false).await?; let search_mode = if settings.shell_up_key_binding { @@ -1382,6 +1396,10 @@ pub async fn history( } else { settings.search_mode }; + let default_filter_mode = settings + .filter_mode_shell_up_key_binding + .filter(|_| settings.shell_up_key_binding) + .unwrap_or_else(|| settings.default_filter_mode(initial_context.git_root.is_some())); let mut app = State { history_count, results_state: ListState::default(), @@ -1397,11 +1415,9 @@ pub async fn history( keymaps: KeymapSet::from_settings(settings), search: SearchState { input, - filter_mode: settings - .filter_mode_shell_up_key_binding - .filter(|_| settings.shell_up_key_binding) - .unwrap_or_else(|| settings.default_filter_mode(context.git_root.is_some())), - context, + filter_mode: default_filter_mode, + context: initial_context.clone(), + custom_context: None, }, engine: engines::engine(search_mode), results_len: 0, @@ -1448,6 +1464,7 @@ pub async fn history( let initial_input = app.search.input.as_str().to_owned(); let initial_filter_mode = app.search.filter_mode; let initial_search_mode = app.search_mode; + let initial_custom_context = app.search.custom_context.clone(); let event_ready = tokio::task::spawn_blocking(|| event::poll(Duration::from_millis(250))); @@ -1479,6 +1496,19 @@ pub async fn history( app.tab_index = 0; }, + InputAction::SwitchContext(index) => { + if let Some(index) = index && let Some(entry) = results.get(index) { + app.search.custom_context = Some(entry.id.clone()); + app.search.context = Context::from_history(entry); + app.search.filter_mode = FilterMode::Session; + app.search.input = Cursor::from(String::new()); + app.results_state = ListState::default(); + } else { + app.search.custom_context = None; + app.search.context = initial_context.clone(); + app.search.filter_mode = default_filter_mode; + } + }, InputAction::Redraw => { terminal.clear()?; terminal.draw(|f| app.draw(f, &results, stats.clone(), inspecting.as_ref(), settings, theme))?; @@ -1504,10 +1534,23 @@ pub async fn history( if initial_input != app.search.input.as_str() || initial_filter_mode != app.search.filter_mode || initial_search_mode != app.search_mode + || initial_custom_context != app.search.custom_context { results = app.query_results(&mut db, settings.smart_sort).await?; } + // In custom context mode, when no filter is applied, highlight the entry which was used + // to enter the context when changing modes. This helps to find your way around. + if app.search.custom_context.is_some() + && app.search.input.as_str().is_empty() + && (initial_custom_context != app.search.custom_context + || initial_filter_mode != app.search.filter_mode) + && let Some(history_id) = app.search.custom_context.clone() + && let Some(pos) = results.iter().position(|entry| entry.id == history_id) + { + app.results_state.select(pos); + } + let inspecting_id = app.inspecting_state.clone().current; // If inspecting ID is not the current inspecting History, update it. match inspecting_id { @@ -1600,7 +1643,10 @@ pub async fn history( // * out of bounds -> usually implies no selected entry so we return the input Ok(app.search.input.into_inner()) } - InputAction::Continue | InputAction::Redraw | InputAction::Delete(_) => { + InputAction::Continue + | InputAction::Redraw + | InputAction::Delete(_) + | InputAction::SwitchContext(_) => { unreachable!("should have been handled!") } } @@ -1827,6 +1873,7 @@ mod tests { host_id: String::new(), git_root: None, }, + custom_context: None, }, engine: engines::engine(SearchMode::Fuzzy), now: Box::new(OffsetDateTime::now_utc), @@ -1881,6 +1928,7 @@ mod tests { host_id: String::new(), git_root: None, }, + custom_context: None, }, engine: engines::engine(SearchMode::Fuzzy), now: Box::new(OffsetDateTime::now_utc), @@ -1999,6 +2047,7 @@ mod tests { host_id: String::new(), git_root: None, }, + custom_context: None, }, engine: engines::engine(SearchMode::Fuzzy), now: Box::new(OffsetDateTime::now_utc), @@ -2057,6 +2106,7 @@ mod tests { host_id: String::new(), git_root: None, }, + custom_context: None, }, engine: engines::engine(SearchMode::Fuzzy), now: Box::new(OffsetDateTime::now_utc), @@ -2111,6 +2161,7 @@ mod tests { host_id: String::new(), git_root: None, }, + custom_context: None, }, engine: engines::engine(SearchMode::Fuzzy), now: Box::new(OffsetDateTime::now_utc), @@ -2161,6 +2212,7 @@ mod tests { host_id: String::new(), git_root: None, }, + custom_context: None, }, engine: engines::engine(SearchMode::Fuzzy), now: Box::new(OffsetDateTime::now_utc), @@ -2220,6 +2272,7 @@ mod tests { host_id: String::new(), git_root: None, }, + custom_context: None, }, engine: engines::engine(SearchMode::Fuzzy), now: Box::new(OffsetDateTime::now_utc), @@ -2280,6 +2333,7 @@ mod tests { host_id: String::new(), git_root: None, }, + custom_context: None, }, engine: engines::engine(SearchMode::Fuzzy), now: Box::new(OffsetDateTime::now_utc), @@ -2490,6 +2544,26 @@ mod tests { } #[test] + fn execute_switch_context() { + use crate::command::client::search::keybindings::Action; + + let mut state = make_executor_state(100, 7); + let settings = Settings::utc(); + let result = state.execute_action(&Action::SwitchContext, &settings); + assert!(matches!(result, super::InputAction::SwitchContext(Some(7)))); + } + + #[test] + fn execute_clear_context() { + use crate::command::client::search::keybindings::Action; + + let mut state = make_executor_state(100, 7); + let settings = Settings::utc(); + let result = state.execute_action(&Action::ClearContext, &settings); + assert!(matches!(result, super::InputAction::SwitchContext(None))); + } + + #[test] fn execute_noop() { use crate::command::client::search::keybindings::Action; @@ -2638,6 +2712,7 @@ mod tests { host_id: String::new(), git_root: None, }, + custom_context: None, }, engine: engines::engine(SearchMode::Fuzzy), now: Box::new(OffsetDateTime::now_utc), diff --git a/crates/atuin/src/command/client/search/keybindings/actions.rs b/crates/atuin/src/command/client/search/keybindings/actions.rs index fae811d6..66e2709e 100644 --- a/crates/atuin/src/command/client/search/keybindings/actions.rs +++ b/crates/atuin/src/command/client/search/keybindings/actions.rs @@ -52,6 +52,8 @@ pub enum Action { Redraw, CycleFilterMode, CycleSearchMode, + SwitchContext, + ClearContext, ToggleTab, // Mode changes @@ -129,6 +131,8 @@ impl Action { "redraw" => Ok(Action::Redraw), "cycle-filter-mode" => Ok(Action::CycleFilterMode), "cycle-search-mode" => Ok(Action::CycleSearchMode), + "switch-context" => Ok(Action::SwitchContext), + "clear-context" => Ok(Action::ClearContext), "toggle-tab" => Ok(Action::ToggleTab), "vim-enter-normal" => Ok(Action::VimEnterNormal), @@ -193,6 +197,8 @@ impl Action { Action::Redraw => "redraw".to_string(), Action::CycleFilterMode => "cycle-filter-mode".to_string(), Action::CycleSearchMode => "cycle-search-mode".to_string(), + Action::SwitchContext => "switch-context".to_string(), + Action::ClearContext => "clear-context".to_string(), Action::ToggleTab => "toggle-tab".to_string(), Action::VimEnterNormal => "vim-enter-normal".to_string(), diff --git a/crates/atuin/src/command/client/search/keybindings/conditions.rs b/crates/atuin/src/command/client/search/keybindings/conditions.rs index bc485713..d460d7d4 100644 --- a/crates/atuin/src/command/client/search/keybindings/conditions.rs +++ b/crates/atuin/src/command/client/search/keybindings/conditions.rs @@ -13,6 +13,7 @@ pub enum ConditionAtom { ListAtStart, NoResults, HasResults, + HasContext, } /// Boolean expression tree over condition atoms. @@ -49,6 +50,8 @@ pub struct EvalContext { pub results_len: usize, /// Whether the original input (query passed to the TUI) was empty. pub original_input_empty: bool, + /// Whether we use a search context of a command from the history. + pub has_context: bool, } // --------------------------------------------------------------------------- @@ -69,6 +72,7 @@ impl ConditionAtom { ConditionAtom::ListAtStart => ctx.results_len == 0 || ctx.selected_index == 0, ConditionAtom::NoResults => ctx.results_len == 0, ConditionAtom::HasResults => ctx.results_len > 0, + ConditionAtom::HasContext => ctx.has_context, } } @@ -83,6 +87,7 @@ impl ConditionAtom { "list-at-start" => Ok(ConditionAtom::ListAtStart), "no-results" => Ok(ConditionAtom::NoResults), "has-results" => Ok(ConditionAtom::HasResults), + "has-context" => Ok(ConditionAtom::HasContext), _ => Err(format!("unknown condition: {s}")), } } @@ -98,6 +103,7 @@ impl ConditionAtom { ConditionAtom::ListAtStart => "list-at-start", ConditionAtom::NoResults => "no-results", ConditionAtom::HasResults => "has-results", + ConditionAtom::HasContext => "has-context", } } } @@ -394,6 +400,7 @@ mod tests { selected_index: selected, results_len: len, original_input_empty, + has_context: false, } } @@ -457,6 +464,14 @@ mod tests { } #[test] + fn atom_has_context() { + let mut context = ctx(0, 0, 0, 0, 0); + assert!(!ConditionAtom::HasContext.evaluate(&context)); + context.has_context = true; + assert!(ConditionAtom::HasContext.evaluate(&context)); + } + + #[test] fn atom_parse_round_trip() { let conditions = [ "cursor-at-start", diff --git a/crates/atuin/src/command/client/search/keybindings/defaults.rs b/crates/atuin/src/command/client/search/keybindings/defaults.rs index 64dca691..f19bf377 100644 --- a/crates/atuin/src/command/client/search/keybindings/defaults.rs +++ b/crates/atuin/src/command/client/search/keybindings/defaults.rs @@ -405,6 +405,13 @@ pub fn default_prefix_keymap() -> Keymap { km.bind(key("d"), Action::Delete); km.bind(key("a"), Action::CursorStart); + km.bind_conditional( + key("c"), + vec![ + KeyRule::when(ConditionAtom::HasContext, Action::ClearContext), + KeyRule::always(Action::SwitchContext), + ], + ); km } @@ -530,6 +537,7 @@ mod tests { selected_index: selected, results_len: len, original_input_empty: false, + has_context: false, } } @@ -1250,6 +1258,7 @@ mod tests { selected_index: 0, results_len: 10, original_input_empty: true, + has_context: false, }; assert_eq!( set.emacs.resolve(&key("esc"), &ctx_original_empty), @@ -1265,6 +1274,7 @@ mod tests { selected_index: 0, results_len: 10, original_input_empty: false, + has_context: false, }; assert_eq!( set.emacs.resolve(&key("esc"), &ctx_original_not_empty), diff --git a/crates/atuin/src/command/client/search/keybindings/keymap.rs b/crates/atuin/src/command/client/search/keybindings/keymap.rs index bbf034b2..8c7fcfa8 100644 --- a/crates/atuin/src/command/client/search/keybindings/keymap.rs +++ b/crates/atuin/src/command/client/search/keybindings/keymap.rs @@ -127,6 +127,7 @@ mod tests { selected_index: selected, results_len: len, original_input_empty: false, + has_context: false, } } diff --git a/docs/docs/configuration/advanced-key-binding.md b/docs/docs/configuration/advanced-key-binding.md index 1fe9c1e4..7f73b5d6 100644 --- a/docs/docs/configuration/advanced-key-binding.md +++ b/docs/docs/configuration/advanced-key-binding.md @@ -206,6 +206,8 @@ Note: `select-next` and `select-previous` respect the `invert` setting. When `in | `cycle-filter-mode` | Cycle through filter modes (global, host, session, directory) | | `cycle-search-mode` | Cycle through search modes (fuzzy, prefix, fulltext, skim) | | `toggle-tab` | Toggle between the search tab and inspector tab | +| `switch-context` | Switch to the [context](../guide/advanced-usage.md#context-switch) of the currently selected command | +| `clear-context` | Return to the initial [context](../guide/advanced-usage.md#context-switch) | The difference between `accept` and `return-selection`: `accept` runs the command immediately when the TUI closes, while `return-selection` places it on your command line for further editing before you press enter. The `enter_accept` setting controls which of these the default `enter` key uses. @@ -251,6 +253,7 @@ Conditions let a single key do different things depending on the current state. | `list-at-end` | The selection is at the last entry | | `no-results` | The search returned zero results | | `has-results` | The search returned at least one result | +| `has-context` | The context comes from a previously selected command (`switch-context`) | ### Boolean expressions diff --git a/docs/docs/configuration/config.md b/docs/docs/configuration/config.md index 49e29a79..31980ed1 100644 --- a/docs/docs/configuration/config.md +++ b/docs/docs/configuration/config.md @@ -139,13 +139,14 @@ Default: `global` The default filter to use when searching -| Mode | Description | -| ---------------- | ------------------------------------------------------------ | -| global (default) | Search history from all hosts, all sessions, all directories | -| host | Search history just from this host | -| session | Search history just from the current session | -| directory | Search history just from the current directory (global) | -| workspace | Search history just from the current git repository (>17.0) | +| Mode | Description | +|------------------|--------------------------------------------------------------------------------------| +| global (default) | Search from the full history | +| host | Search history from this host | +| session | Search history from the current session | +| directory | Search history from the current directory | +| workspace | Search history from the current git repository | +| session-preload | Search from the current session and the global history from before the session start | Filter modes can still be toggled via ctrl-r diff --git a/docs/docs/configuration/key-binding.md b/docs/docs/configuration/key-binding.md index f292999f..942a2400 100644 --- a/docs/docs/configuration/key-binding.md +++ b/docs/docs/configuration/key-binding.md @@ -202,31 +202,32 @@ $env.config = ( ## Atuin UI shortcuts | Shortcut | Action | -| ----------------------------------------- | ----------------------------------------------------------------------------- | -| enter | Execute selected item | +|-------------------------------------------|-------------------------------------------------------------------------------| +| enter | Execute selected item | | tab | Select item and edit | | ctrl + r | Cycle through filter modes | | ctrl + s | Cycle through search modes | | alt + 1 to alt + 9 | Select item by the number located near it | | ctrl + c / ctrl + d / ctrl + g / esc | Return original | | ctrl + y | Copy selected item to clipboard | -| ctrl + ← / alt + b | Move the cursor to the previous word | -| ctrl + → / alt + f | Move the cursor to the next word | -| ctrl + b / ← | Move the cursor to the left | -| ctrl + f / → | Move the cursor to the right | +| ctrl + ← / alt + b | Move the cursor to the previous word | +| ctrl + → / alt + f | Move the cursor to the next word | +| ctrl + b / ← | Move the cursor to the left | +| ctrl + f / → | Move the cursor to the right | | ctrl + a / home | Move the cursor to the start of the line | | ctrl + e / end | Move the cursor to the end of the line | | ctrl + backspace / ctrl + alt + backspace | Remove the previous word / remove the word just before the cursor | | ctrl + delete / ctrl + alt + delete | Remove the next word or the word just after the cursor | | ctrl + w | Remove the word before the cursor even if it spans across the word boundaries | | ctrl + u | Clear the current line | -| ctrl + n / ctrl + j / ↑ | Select the next item on the list | -| ctrl + p / ctrl + k / ↓ | Select the previous item on the list | +| ctrl + n / ctrl + j / ↑ | Select the next item on the list | +| ctrl + p / ctrl + k / ↓ | Select the previous item on the list | | ctrl + o | Open the [inspector](#inspector) | | page down | Scroll search results one page down | | page up | Scroll search results one page up | -| ↓ (with no entry selected) | Return original or return query depending on [settings](config.md#exit_mode) | -| ↓ | Select the next item on the list | +| ↓ (with no entry selected) | Return original or return query depending on [settings](config.md#exit_mode) | +| ↓ | Select the next item on the list | +| ctrl + a, c | Switch to the context of the currently selected command / return to default | ### Vim mode diff --git a/docs/docs/guide/advanced-usage.md b/docs/docs/guide/advanced-usage.md new file mode 100644 index 00000000..0d5a1359 --- /dev/null +++ b/docs/docs/guide/advanced-usage.md @@ -0,0 +1,49 @@ +# Advanced Usage + +Atuin offers you several options to help navigate through the results. + +## Filter mode + +The command history can be filtered in different ways, letting you narrow the search scope. + +You can cycle through the different modes by pressing **ctrl-r**. + +The available modes are: + +| Mode | Description | +|------------------|--------------------------------------------------------------------------------------| +| global (default) | Search from the full history | +| host | Search history from this host | +| session | Search history from the current session | +| directory | Search history from the current directory | +| workspace | Search history from the current git repository | +| session-preload | Search from the current session and the global history from before the session start | + +See the [`filter_mode` config reference](../configuration/config.md#filter_mode) for more details. + +## Search mode + +Atuin offers different modes to interpret your search query. + +You can cycle through the different modes by pressing **ctrl-s**. + +The available modes are: + +| Mode | Description | +|-----------------|----------------------------------------------------------------------------------------------------------------| +| fuzzy (default) | Search for commands in a fuzzy way, similar to the [fzf syntax](https://github.com/junegunn/fzf#search-syntax) | +| prefix | Commands that start with your query | +| fulltext | Commands that contain your query as a substring | +| skim | Search for commands using the [skim syntax](https://github.com/lotabout/skim#search-syntax) | + +See the [`search_mode` config reference](../configuration/config.md#search_mode) for more details. + +## Context switch + +Atuin uses the current context (host, session, directory) to filter the history when you use a filter mode other than *global*. + +You can switch this context to the one of the currently selected command by pressing **ctrl-a** then **c**. + +This will set the filter mode to *session* and clear the search query, which will show you all the commands executed in the same shell session. + +Pressing this key combination again will return to the initial context. You can customize this behavior by setting [custom key bindings](../configuration/advanced-key-binding.md) to the `switch-context` and `clear-context` commands. `switch-context` can be called several times to navigate through multiple command contexts, while `clear-context` will always return to the initial context. diff --git a/docs/docs/guide/basic-usage.md b/docs/docs/guide/basic-usage.md index 0b40a0aa..f6df1c94 100644 --- a/docs/docs/guide/basic-usage.md +++ b/docs/docs/guide/basic-usage.md @@ -26,6 +26,8 @@ While searching in the TUI, you can adjust the "filter mode" by repeatedly press 3. The current directory only 4. The current shell session only +See the [advanced usage](advanced-usage.md) page for more options. + ## Common config adjustment For a full set of config values, please see the [config reference page](../configuration/config.md). diff --git a/docs/mkdocs.yml b/docs/mkdocs.yml index 1cbbf30d..4ca51c60 100644 --- a/docs/mkdocs.yml +++ b/docs/mkdocs.yml @@ -63,6 +63,7 @@ nav: - Setting up sync: guide/sync.md - Import existing history: guide/import.md - Basic usage: guide/basic-usage.md + - Advanced usage: guide/advanced-usage.md - Deleting history: guide/delete-history.md - Syncing dotfiles: guide/dotfiles.md - Theming: guide/theming.md |
