diff options
| author | Ellie Huxtable <ellie@atuin.sh> | 2026-01-22 15:56:10 -0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-01-22 15:56:10 -0800 |
| commit | 1fb16c0ab6821f66014948a59a34807c55cf38db (patch) | |
| tree | c28f55bc3d83aec25ecb0da893bda8eea6daffa2 /crates | |
| parent | feat: add custom column support (#3089) (diff) | |
| download | atuin-1fb16c0ab6821f66014948a59a34807c55cf38db.zip | |
feat: left arrow/backspace on empty to start edit (#3090)
resolves #1906
<!-- Thank you for making a PR! Bug fixes are always welcome, but if
you're adding a new feature or changing an existing one, we'd really
appreciate if you open an issue, post on the forum, or drop in on
Discord -->
## Checks
- [ ] I am happy for maintainers to push small adjustments to this PR,
to speed up the review cycle
- [ ] I have checked that there are no existing pull requests for the
same thing
Diffstat (limited to 'crates')
| -rw-r--r-- | crates/atuin/src/command/client/search/interactive.rs | 53 |
1 files changed, 38 insertions, 15 deletions
diff --git a/crates/atuin/src/command/client/search/interactive.rs b/crates/atuin/src/command/client/search/interactive.rs index 3a69b973..2b0522fc 100644 --- a/crates/atuin/src/command/client/search/interactive.rs +++ b/crates/atuin/src/command/client/search/interactive.rs @@ -306,6 +306,9 @@ impl State { { Some(InputAction::Accept(self.results_state.selected())) } + KeyCode::Left | KeyCode::Backspace if self.search.input.as_str().is_empty() => { + Some(InputAction::Accept(self.results_state.selected())) + } KeyCode::Char('o') if ctrl => { self.tab_index = (self.tab_index + 1) % TAB_TITLES.len(); Some(InputAction::Continue) @@ -1747,42 +1750,62 @@ mod tests { "Tab should always accept" ); - // Test left arrow with accept_past_line_start disabled (should continue) + // Test left arrow with empty search should accept (new default behavior) let left_event = KeyEvent::new(KeyCode::Left, KeyModifiers::NONE); let result = state.handle_key_input(&settings, &left_event); assert!( - matches!(result, super::InputAction::Continue), - "Left arrow should continue when disabled" + matches!(result, super::InputAction::Accept(_)), + "Left arrow should accept when search is empty" ); - // Test left arrow with accept_past_line_start enabled (should accept at start of line) - settings.keys.accept_past_line_start = true; - let result = state.handle_key_input(&settings, &left_event); + // Test backspace with empty search should accept (new default behavior) + let backspace_event = KeyEvent::new(KeyCode::Backspace, KeyModifiers::NONE); + let result = state.handle_key_input(&settings, &backspace_event); assert!( matches!(result, super::InputAction::Accept(_)), - "Left arrow should accept at start of line when enabled" + "Backspace should accept when search is empty" + ); + + // Test left/backspace with non-empty search at cursor start should NOT accept + state.search.input.insert('t'); + state.search.input.insert('e'); + state.search.input.insert('s'); + state.search.input.insert('t'); + state.search.input.start(); // Move cursor to start of non-empty search + + let left_event = KeyEvent::new(KeyCode::Left, KeyModifiers::NONE); + let result = state.handle_key_input(&settings, &left_event); + assert!( + matches!(result, super::InputAction::Continue), + "Left arrow should continue when search is not empty (even at cursor start)" ); - settings.keys.accept_past_line_start = false; let backspace_event = KeyEvent::new(KeyCode::Backspace, KeyModifiers::NONE); let result = state.handle_key_input(&settings, &backspace_event); assert!( matches!(result, super::InputAction::Continue), - "Backspace should continue when disabled" + "Backspace should continue when search is not empty (even at cursor start)" + ); + + // Test that accept_past_line_start flag still works with non-empty search at start + settings.keys.accept_past_line_start = true; + let result = state.handle_key_input(&settings, &left_event); + assert!( + matches!(result, super::InputAction::Accept(_)), + "Left arrow should accept at cursor start when flag enabled (even with non-empty search)" ); + settings.keys.accept_past_line_start = false; + // Test that accept_with_backspace flag still works with non-empty search at start settings.keys.accept_with_backspace = true; let result = state.handle_key_input(&settings, &backspace_event); assert!( matches!(result, super::InputAction::Accept(_)), - "Backspace should accept at start of line when enabled" + "Backspace should accept at cursor start when flag enabled (even with non-empty search)" ); + settings.keys.accept_with_backspace = false; - state.search.input.insert('t'); - state.search.input.insert('e'); - state.search.input.insert('s'); - state.search.input.insert('t'); - state.search.input.end(); + state.search.input.end(); // Move cursor back to end for remaining tests let right_event = KeyEvent::new(KeyCode::Right, KeyModifiers::NONE); let result = state.handle_key_input(&settings, &right_event); |
