diff options
| author | Benedikt Peetz <benedikt.peetz@b-peetz.de> | 2026-06-13 00:50:54 +0200 |
|---|---|---|
| committer | Benedikt Peetz <benedikt.peetz@b-peetz.de> | 2026-06-13 00:50:54 +0200 |
| commit | 6723829a3398b3c9dd6dc6ae79124f46000606ee (patch) | |
| tree | a1ec535eddd711a4557e4bcc5b94382c3623504c /crates/turtle/src/command | |
| parent | chore(treewide): Cleanup themes (diff) | |
| download | atuin-6723829a3398b3c9dd6dc6ae79124f46000606ee.zip | |
chore(treewide): Remove `cargo` warnings to 0
There are still the `clippy` warnings, but they are for a future date.
Diffstat (limited to '')
| -rw-r--r-- | crates/turtle/src/command/client.rs | 4 | ||||
| -rw-r--r-- | crates/turtle/src/command/client/daemon.rs | 51 | ||||
| -rw-r--r-- | crates/turtle/src/command/client/history.rs | 15 | ||||
| -rw-r--r-- | crates/turtle/src/command/client/search.rs | 2 | ||||
| -rw-r--r-- | crates/turtle/src/command/client/search/engines.rs | 6 | ||||
| -rw-r--r-- | crates/turtle/src/command/client/search/engines/db.rs | 2 | ||||
| -rw-r--r-- | crates/turtle/src/command/client/search/engines/skim.rs | 2 | ||||
| -rw-r--r-- | crates/turtle/src/command/client/search/inspector.rs | 8 | ||||
| -rw-r--r-- | crates/turtle/src/command/client/search/interactive.rs | 158 | ||||
| -rw-r--r-- | crates/turtle/src/command/client/search/keybindings/defaults.rs | 32 | ||||
| -rw-r--r-- | crates/turtle/src/command/client/search/keybindings/key.rs | 24 | ||||
| -rw-r--r-- | crates/turtle/src/command/mod.rs | 12 |
12 files changed, 142 insertions, 174 deletions
diff --git a/crates/turtle/src/command/client.rs b/crates/turtle/src/command/client.rs index 0c97f945..2ec5abe7 100644 --- a/crates/turtle/src/command/client.rs +++ b/crates/turtle/src/command/client.rs @@ -35,7 +35,7 @@ fn cleanup_old_logs(log_dir: &Path, prefix: &str, retention_days: u64) { && let Ok(modified) = metadata.modified() && modified < cutoff { - let _ = fs::remove_file(&path); + drop(fs::remove_file(&path)); } } } @@ -107,7 +107,7 @@ impl Cmd { pub(crate) fn run(self) -> Result<()> { // Daemonize before creating the async runtime – fork() inside a live // tokio runtime corrupts its internal state. - #[cfg(all(unix, feature = "daemon"))] + #[cfg(unix)] if let Self::Daemon(ref cmd) = self && cmd.should_daemonize() { diff --git a/crates/turtle/src/command/client/daemon.rs b/crates/turtle/src/command/client/daemon.rs index 41cb04fe..4960dacd 100644 --- a/crates/turtle/src/command/client/daemon.rs +++ b/crates/turtle/src/command/client/daemon.rs @@ -120,7 +120,7 @@ impl PidfileGuard { impl Drop for PidfileGuard { fn drop(&mut self) { - let _ = self.file.unlock(); + drop(self.file.unlock()); } } @@ -232,7 +232,7 @@ async fn probe(settings: &Settings) -> Probe { async fn request_shutdown(settings: &Settings) { if let Ok(mut client) = connect_client(settings).await { - let _ = client.shutdown().await; + drop(client.shutdown().await); } } @@ -365,7 +365,7 @@ pub(crate) async fn ensure_daemon_running(settings: &Settings) -> Result<()> { remove_stale_socket_if_present(settings)?; spawn_daemon_process()?; - let _ = wait_until_ready(settings, timeout).await?; + drop(wait_until_ready(settings, timeout).await?); drop(startup_lock); Ok(()) @@ -451,7 +451,7 @@ pub(crate) async fn end_history( // End succeeded on the running daemon, so avoid replaying it. // We only restart to make subsequent hook calls target the expected version. - let _ = restart_daemon(settings).await; + drop(restart_daemon(settings).await); return Ok(()); } Err(err) if !settings.daemon.autostart => return Err(err), @@ -679,11 +679,13 @@ fn force_cleanup(settings: &Settings) { #[cfg(unix)] fn kill_process(pid: u32) { // Use kill command to send SIGTERM for graceful shutdown - let _ = Command::new("kill") - .args(["-TERM", &pid.to_string()]) - .stdout(Stdio::null()) - .stderr(Stdio::null()) - .status(); + drop( + Command::new("kill") + .args(["-TERM", &pid.to_string()]) + .stdout(Stdio::null()) + .stderr(Stdio::null()) + .status(), + ); } #[cfg(test)] @@ -725,35 +727,4 @@ mod tests { let lock = daemon_startup_lock_path(pidfile); assert_eq!(lock, PathBuf::from("/tmp/atuin-daemon.pid.startup.lock")); } - - #[test] - fn test_pidfile_guard_acquire_and_drop() { - let tmp = tempfile::tempdir().unwrap(); - let pidfile = tmp.path().join("daemon.pid"); - - { - let _guard = PidfileGuard::acquire(&pidfile).unwrap(); - // Guard holds an exclusive lock — on Windows other handles cannot - // read the file, so we verify contents after the guard is dropped. - } - - let contents = std::fs::read_to_string(&pidfile).unwrap(); - let lines: Vec<&str> = contents.lines().collect(); - assert_eq!(lines.len(), 2); - assert_eq!(lines[0], std::process::id().to_string()); - assert_eq!(lines[1], DAEMON_VERSION); - - // After guard is dropped, lock should be released — acquiring again must succeed. - let _guard2 = PidfileGuard::acquire(&pidfile).unwrap(); - } - - #[test] - fn test_pidfile_guard_prevents_double_acquire() { - let tmp = tempfile::tempdir().unwrap(); - let pidfile = tmp.path().join("daemon.pid"); - - let _guard = PidfileGuard::acquire(&pidfile).unwrap(); - let result = PidfileGuard::acquire(&pidfile); - assert!(result.is_err()); - } } diff --git a/crates/turtle/src/command/client/history.rs b/crates/turtle/src/command/client/history.rs index 2ddcb3a6..e574a2e9 100644 --- a/crates/turtle/src/command/client/history.rs +++ b/crates/turtle/src/command/client/history.rs @@ -14,7 +14,7 @@ use super::daemon as daemon_cmd; use colored::Colorize; use serde::Serialize; -use crate::atuin_daemon::history::{HistoryEventKind, TailHistoryReply}; +use crate::atuin_daemon::generated::history::{HistoryEventKind, TailHistoryReply}; use crate::atuin_client::{ database::{ClientSqlite, current_context}, @@ -166,11 +166,11 @@ pub(crate) enum ListMode { impl ListMode { pub(crate) const fn from_flags(human: bool, cmd_only: bool) -> Self { if human { - ListMode::Human + Self::Human } else if cmd_only { - ListMode::CmdOnly + Self::CmdOnly } else { - ListMode::Regular + Self::Regular } } } @@ -183,7 +183,7 @@ pub(crate) fn print_list( reverse: bool, tz: Timezone, ) { - let w = std::io::stdout(); + let w = io::stdout(); let mut w = w.lock(); let fmt_str = match list_mode { @@ -202,6 +202,7 @@ pub(crate) fn print_list( ListMode::CmdOnly => std::iter::once(ParseSegment::Key("command")).collect(), }; + #[allow(trivial_casts)] let iterator = if reverse { Box::new(h.iter().rev()) as Box<dyn Iterator<Item = &History>> } else { @@ -743,10 +744,10 @@ fn normalize_optional_field(value: &str) -> Option<String> { impl Cmd { async fn handle_tail(settings: &Settings) -> Result<()> { - let tty = std::io::stdout().is_terminal(); + let tty = io::stdout().is_terminal(); let mut client = daemon::tail_client(settings).await?; let mut stream = client.tail_history().await?; - let stdout = std::io::stdout(); + let stdout = io::stdout(); while let Some(reply) = stream.message().await? { let event = TailEvent::from_proto(reply)?; diff --git a/crates/turtle/src/command/client/search.rs b/crates/turtle/src/command/client/search.rs index bba48b8a..5c51caea 100644 --- a/crates/turtle/src/command/client/search.rs +++ b/crates/turtle/src/command/client/search.rs @@ -166,7 +166,7 @@ impl Cmd { |query| { query .split(' ') - .map(std::string::ToString::to_string) + .map(ToString::to_string) .collect() }, ) diff --git a/crates/turtle/src/command/client/search/engines.rs b/crates/turtle/src/command/client/search/engines.rs index 94834221..9fbff278 100644 --- a/crates/turtle/src/command/client/search/engines.rs +++ b/crates/turtle/src/command/client/search/engines.rs @@ -14,9 +14,9 @@ pub(crate) mod skim; pub(crate) fn engine(search_mode: SearchMode, settings: &Settings) -> Box<dyn SearchEngine> { match search_mode { - SearchMode::Skim => Box::new(skim::Search::new()) as Box<_>, - SearchMode::DaemonFuzzy => Box::new(daemon::Search::new(settings)) as Box<_>, - mode => Box::new(db::Search(mode)) as Box<_>, + SearchMode::Skim => Box::new(skim::Search::new()), + SearchMode::DaemonFuzzy => Box::new(daemon::Search::new(settings)), + mode => Box::new(db::Search(mode)), } } diff --git a/crates/turtle/src/command/client/search/engines/db.rs b/crates/turtle/src/command/client/search/engines/db.rs index e6657b17..0eb86878 100644 --- a/crates/turtle/src/command/client/search/engines/db.rs +++ b/crates/turtle/src/command/client/search/engines/db.rs @@ -49,7 +49,7 @@ impl SearchEngine for Search { let mut parser = FzfParser::new(); let query = parser.parse(search_input); let mut ranges: Vec<Range<usize>> = Vec::new(); - let _ = fzf.distance_and_ranges(query, command, &mut ranges); + fzf.distance_and_ranges(query, command, &mut ranges); // convert ranges to all indices ranges.into_iter().flatten().collect() diff --git a/crates/turtle/src/command/client/search/engines/skim.rs b/crates/turtle/src/command/client/search/engines/skim.rs index a6a77573..739e790b 100644 --- a/crates/turtle/src/command/client/search/engines/skim.rs +++ b/crates/turtle/src/command/client/search/engines/skim.rs @@ -117,7 +117,7 @@ async fn fuzzy_search( continue; }; let (seconds, nanos) = timestamp.to_unix(); - let Ok(session_start) = time::OffsetDateTime::from_unix_timestamp_nanos( + let Ok(session_start) = OffsetDateTime::from_unix_timestamp_nanos( i128::from(seconds) * 1_000_000_000 + i128::from(nanos), ) else { warn!( diff --git a/crates/turtle/src/command/client/search/inspector.rs b/crates/turtle/src/command/client/search/inspector.rs index f7b40a26..6c2c59fe 100644 --- a/crates/turtle/src/command/client/search/inspector.rs +++ b/crates/turtle/src/command/client/search/inspector.rs @@ -195,7 +195,7 @@ fn sort_duration_over_time(durations: &[(String, i64)]) -> Vec<(String, i64)> { } fn draw_stats_charts(f: &mut Frame<'_>, parent: Rect, stats: &HistoryStats) { - let exits: Vec<Bar> = stats + let exits: Vec<Bar<'_>> = stats .exits .iter() .map(|(exit, count)| { @@ -219,7 +219,7 @@ fn draw_stats_charts(f: &mut Frame<'_>, parent: Rect, stats: &HistoryStats) { .label_style(Style::default()) .data(BarGroup::default().bars(&exits)); - let day_of_week: Vec<Bar> = stats + let day_of_week: Vec<Bar<'_>> = stats .day_of_week .iter() .map(|(day, count)| { @@ -244,7 +244,7 @@ fn draw_stats_charts(f: &mut Frame<'_>, parent: Rect, stats: &HistoryStats) { .data(BarGroup::default().bars(&day_of_week)); let duration_over_time = sort_duration_over_time(&stats.duration_over_time); - let duration_over_time: Vec<Bar> = duration_over_time + let duration_over_time: Vec<Bar<'_>> = duration_over_time .iter() .map(|(date, duration)| { let d = Duration::from_nanos(u64_or_zero(*duration)); @@ -398,7 +398,7 @@ mod tests { let prev = stats.previous.clone().unwrap(); let next = stats.next.clone().unwrap(); - let _ = terminal.draw(|f| draw_ultracompact(f, chunk, &history, &stats)); + drop(terminal.draw(|f| draw_ultracompact(f, chunk, &history, &stats))); let mut lines = [" "; 5].map(|l| Line::from(l)); for (n, entry) in [prev, history, next].iter().enumerate() { let mut l = lines[n].to_string(); diff --git a/crates/turtle/src/command/client/search/interactive.rs b/crates/turtle/src/command/client/search/interactive.rs index 2c6af8cf..49d483b0 100644 --- a/crates/turtle/src/command/client/search/interactive.rs +++ b/crates/turtle/src/command/client/search/interactive.rs @@ -97,7 +97,7 @@ impl InspectingState { } } -pub(crate) fn to_compactness(f: &Frame, settings: &Settings) -> Compactness { +pub(crate) fn to_compactness(f: &Frame<'_>, settings: &Settings) -> Compactness { if match settings.style { crate::atuin_client::settings::Style::Auto => f.area().height < 14, crate::atuin_client::settings::Style::Compact => true, @@ -232,7 +232,7 @@ impl State { && let Some(style) = cursor_style { self.current_cursor = cursor_style; - let _ = execute!(stdout(), Self::cast_cursor_style(style)); + drop(execute!(stdout(), Self::cast_cursor_style(style))); } } @@ -804,7 +804,7 @@ impl State { fn draw( &mut self, - f: &mut Frame, + f: &mut Frame<'_>, results: &[History], stats: Option<HistoryStats>, inspecting: Option<&History>, @@ -823,7 +823,7 @@ impl State { #[expect(clippy::bool_to_int_with_if)] fn draw_inner( &mut self, - f: &mut Frame, + f: &mut Frame<'_>, area: Rect, results: &[History], stats: Option<HistoryStats>, @@ -1051,12 +1051,12 @@ impl State { #[expect(clippy::cast_possible_truncation, clippy::too_many_arguments)] fn draw_preview( &self, - f: &mut Frame, + f: &mut Frame<'_>, style: StyleState, input_chunk: Rect, compactness: Compactness, preview_chunk: Rect, - preview: Paragraph, + preview: Paragraph<'_>, prefix_width: u16, ) { let input = self.build_input(style, prefix_width); @@ -1088,7 +1088,6 @@ impl State { title.alignment(Alignment::Left) } - #[expect(clippy::unused_self)] fn build_help(&self, settings: &Settings) -> Paragraph<'_> { match self.tab_index { // search @@ -1272,7 +1271,7 @@ impl TerminalWriter { fn new() -> std::io::Result<Self> { let stdout = stdout(); if stdout.is_terminal() { - return Ok(TerminalWriter::Stdout(stdout)); + return Ok(Self::Stdout(stdout)); } // If stdout is not a terminal (e.g., captured by command substitution), @@ -1280,7 +1279,7 @@ impl TerminalWriter { // This allows usage like: VAR=$(atuin search -i) #[cfg(unix)] { - Ok(TerminalWriter::Tty( + Ok(Self::Tty( std::fs::File::options() .read(true) .write(true) @@ -1293,17 +1292,17 @@ impl TerminalWriter { impl Write for TerminalWriter { fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> { match self { - TerminalWriter::Stdout(stdout) => stdout.write(buf), + Self::Stdout(stdout) => stdout.write(buf), #[cfg(unix)] - TerminalWriter::Tty(file) => file.write(buf), + Self::Tty(file) => file.write(buf), } } fn flush(&mut self) -> std::io::Result<()> { match self { - TerminalWriter::Stdout(stdout) => stdout.flush(), + Self::Stdout(stdout) => stdout.flush(), #[cfg(unix)] - TerminalWriter::Tty(file) => file.flush(), + Self::Tty(file) => file.flush(), } } } @@ -1395,27 +1394,32 @@ fn restore_popup_area(saved: &SavedScreen, popup_rect: Rect, scroll_offset: u16) // beforehand. We write `popup_rect.width` spaces instead of // ClearType::CurrentLine so that only the popup area is cleared, not // the entire terminal line. - let _ = execute!( + drop(execute!( stdout, MoveTo(popup_rect.x, target_row), - ratatui::crossterm::style::SetAttribute(ratatui::crossterm::style::Attribute::Reset), - ); - let _ = write!(stdout, "{:width$}", "", width = popup_rect.width as usize); - let _ = execute!(stdout, MoveTo(popup_rect.x, target_row)); + crossterm::style::SetAttribute(crossterm::style::Attribute::Reset), + )); + drop(write!( + stdout, + "{:width$}", + "", + width = popup_rect.width as usize + )); + drop(execute!(stdout, MoveTo(popup_rect.x, target_row))); if let Some(row_bytes) = saved.rows_data.get(source_row) { - let _ = stdout.write_all(row_bytes); + drop(stdout.write_all(row_bytes)); } } - let _ = execute!( + drop(execute!( stdout, MoveTo( saved.cursor_col, saved.cursor_row.saturating_sub(scroll_offset) ) - ); - let _ = stdout.flush(); + )); + drop(stdout.flush()); } struct Stdout { @@ -1534,11 +1538,7 @@ fn compute_popup_placement( // for now, it works. But it'd be great if it were more easily readable, and // modular. I'd like to add some more stats and stuff at some point -#[expect( - clippy::cast_possible_truncation, - clippy::too_many_lines, - clippy::cognitive_complexity -)] +#[expect(clippy::too_many_lines, clippy::cognitive_complexity)] pub(crate) async fn history( query: &[String], settings: &Settings, @@ -1589,11 +1589,11 @@ pub(crate) async fn history( if scroll > 0 { use ratatui::crossterm::cursor::MoveTo; let mut stdout = stdout(); - let _ = execute!(stdout, MoveTo(0, term_rows - 1)); + drop(execute!(stdout, MoveTo(0, term_rows - 1))); for _ in 0..scroll { - let _ = writeln!(stdout); + drop(writeln!(stdout)); } - let _ = stdout.flush(); + drop(stdout.flush()); } (saved, popup_rect, scroll) @@ -1619,20 +1619,20 @@ pub(crate) async fn history( let mut raw_stdout = std::io::stdout(); // Queue all commands without flushing so the terminal receives them // as a single write — no intermediate cursor positions are visible. - let _ = queue!( + drop(queue!( raw_stdout, - ratatui::crossterm::style::SetAttribute(ratatui::crossterm::style::Attribute::Reset) - ); + crossterm::style::SetAttribute(crossterm::style::Attribute::Reset) + )); for row in popup_rect.y..popup_rect.y.saturating_add(popup_rect.height) { - let _ = queue!(raw_stdout, MoveTo(popup_rect.x, row)); - let _ = write!( + drop(queue!(raw_stdout, MoveTo(popup_rect.x, row))); + drop(write!( raw_stdout, "{:width$}", "", width = popup_rect.width as usize - ); + )); } - let _ = raw_stdout.flush(); + drop(raw_stdout.flush()); } let backend = CrosstermBackend::new(stdout); @@ -1996,7 +1996,7 @@ mod tests { strategy: PreviewStrategy::Auto, }, show_preview: true, - ..Settings::now() + ..Settings::new().unwrap() }; let settings_preview_auto_h2 = Settings { @@ -2005,7 +2005,7 @@ mod tests { }, show_preview: true, max_preview_height: 2, - ..Settings::now() + ..Settings::new().unwrap() }; let settings_preview_h4 = Settings { @@ -2014,7 +2014,7 @@ mod tests { }, show_preview: true, max_preview_height: 4, - ..Settings::now() + ..Settings::new().unwrap() }; let settings_preview_fixed = Settings { @@ -2023,25 +2023,25 @@ mod tests { }, show_preview: true, max_preview_height: 15, - ..Settings::now() + ..Settings::new().unwrap() }; let cmd_60: History = History::capture() - .timestamp(time::OffsetDateTime::now_utc()) + .timestamp(OffsetDateTime::now_utc()) .command("for i in $(seq -w 10); do echo \"item number $i - abcd\"; done") .cwd("/") .build() .into(); let cmd_124: History = History::capture() - .timestamp(time::OffsetDateTime::now_utc()) + .timestamp(OffsetDateTime::now_utc()) .command("echo 'Aurea prima sata est aetas, quae vindice nullo, sponte sua, sine lege fidem rectumque colebat. Poena metusque aberant'") .cwd("/") .build() .into(); let cmd_200: History = History::capture() - .timestamp(time::OffsetDateTime::now_utc()) + .timestamp(OffsetDateTime::now_utc()) .command("CREATE USER atuin WITH ENCRYPTED PASSWORD 'supersecretpassword'; CREATE DATABASE atuin WITH OWNER = atuin; \\c atuin; REVOKE ALL PRIVILEGES ON SCHEMA public FROM PUBLIC; echo 'All done. 200 characters'") .cwd("/") .build() @@ -2145,7 +2145,7 @@ mod tests { // Test when there's no results, scrolling up or down doesn't underflow #[test] fn state_scroll_up_underflow() { - let settings = Settings::now(); + let settings = Settings::new().unwrap(); let mut state = State { history_count: 0, results_state: ListState::default(), @@ -2190,7 +2190,7 @@ mod tests { use crate::atuin_client::settings::Keys; use ratatui::crossterm::event::{KeyCode, KeyEvent, KeyModifiers}; - let mut settings = Settings::now(); + let mut settings = Settings::new().unwrap(); settings.keys = Keys { scroll_exits: true, exit_past_line_start: false, @@ -2316,7 +2316,7 @@ mod tests { fn test_vim_gg_multikey_sequence() { use ratatui::crossterm::event::{KeyCode, KeyEvent, KeyModifiers}; - let settings = Settings::now(); + let settings = Settings::new().unwrap(); let mut state = State { history_count: 100, @@ -2374,7 +2374,7 @@ mod tests { fn test_vim_g_key_clears_on_other_input() { use ratatui::crossterm::event::{KeyCode, KeyEvent, KeyModifiers}; - let settings = Settings::now(); + let settings = Settings::new().unwrap(); let mut state = State { history_count: 100, @@ -2428,7 +2428,7 @@ mod tests { fn test_vim_big_g_jump_to_bottom() { use ratatui::crossterm::event::{KeyCode, KeyEvent, KeyModifiers}; - let settings = Settings::now(); + let settings = Settings::new().unwrap(); let mut state = State { history_count: 100, @@ -2475,10 +2475,11 @@ mod tests { } #[test] + #[allow(clippy::similar_names)] fn test_vim_ctrl_u_d_half_page_scroll() { use ratatui::crossterm::event::{KeyCode, KeyEvent, KeyModifiers}; - let settings = Settings::now(); + let settings = Settings::new().unwrap(); let mut state = State { history_count: 100, @@ -2534,10 +2535,11 @@ mod tests { } #[test] + #[allow(clippy::similar_names)] fn test_vim_ctrl_f_b_full_page_scroll() { use ratatui::crossterm::event::{KeyCode, KeyEvent, KeyModifiers}; - let settings = Settings::now(); + let settings = Settings::new().unwrap(); let mut state = State { history_count: 100, @@ -2598,7 +2600,7 @@ mod tests { /// Helper to build a State for executor tests. fn make_executor_state(results_len: usize, selected: usize) -> State { - let settings = Settings::now(); + let settings = Settings::new().unwrap(); let mut state = State { history_count: results_len as i64, results_state: ListState::default(), @@ -2642,7 +2644,7 @@ mod tests { use crate::command::client::search::keybindings::Action; let mut state = make_executor_state(100, 50); - let settings = Settings::now(); + let settings = Settings::new().unwrap(); let result = state.execute_action(&Action::SelectNext, &settings); assert!(matches!(result, super::InputAction::Continue)); // Non-inverted: SelectNext = scroll_down = selected - 1 @@ -2654,7 +2656,7 @@ mod tests { use crate::command::client::search::keybindings::Action; let mut state = make_executor_state(100, 50); - let mut settings = Settings::now(); + let mut settings = Settings::new().unwrap(); settings.invert = true; let result = state.execute_action(&Action::SelectNext, &settings); assert!(matches!(result, super::InputAction::Continue)); @@ -2667,7 +2669,7 @@ mod tests { use crate::command::client::search::keybindings::Action; let mut state = make_executor_state(100, 50); - let settings = Settings::now(); + let settings = Settings::new().unwrap(); let result = state.execute_action(&Action::SelectPrevious, &settings); assert!(matches!(result, super::InputAction::Continue)); // Non-inverted: SelectPrevious = scroll_up = selected + 1 @@ -2679,7 +2681,7 @@ mod tests { use crate::command::client::search::keybindings::Action; let mut state = make_executor_state(100, 0); - let settings = Settings::now(); + let settings = Settings::new().unwrap(); let result = state.execute_action(&Action::VimEnterNormal, &settings); assert!(matches!(result, super::InputAction::Continue)); assert_eq!(state.keymap_mode, KeymapMode::VimNormal); @@ -2691,7 +2693,7 @@ mod tests { let mut state = make_executor_state(100, 0); state.keymap_mode = KeymapMode::VimNormal; - let settings = Settings::now(); + let settings = Settings::new().unwrap(); let result = state.execute_action(&Action::VimEnterInsert, &settings); assert!(matches!(result, super::InputAction::Continue)); assert_eq!(state.keymap_mode, KeymapMode::VimInsert); @@ -2702,7 +2704,7 @@ mod tests { use crate::command::client::search::keybindings::Action; let mut state = make_executor_state(100, 5); - let mut settings = Settings::now(); + let mut settings = Settings::new().unwrap(); settings.enter_accept = true; let result = state.execute_action(&Action::Accept, &settings); assert!(matches!(result, super::InputAction::Accept(5))); @@ -2714,7 +2716,7 @@ mod tests { use crate::command::client::search::keybindings::Action; let mut state = make_executor_state(100, 5); - let settings = Settings::now(); + let settings = Settings::new().unwrap(); let result = state.execute_action(&Action::ReturnSelection, &settings); assert!(matches!(result, super::InputAction::Accept(5))); assert!(!state.accept); @@ -2725,7 +2727,7 @@ mod tests { use crate::command::client::search::keybindings::Action; let mut state = make_executor_state(100, 5); - let settings = Settings::now(); + let settings = Settings::new().unwrap(); let result = state.execute_action(&Action::AcceptNth(3), &settings); assert!(matches!(result, super::InputAction::Accept(8))); } @@ -2735,7 +2737,7 @@ mod tests { use crate::command::client::search::keybindings::Action; let mut state = make_executor_state(100, 50); - let settings = Settings::now(); + let settings = Settings::new().unwrap(); let result = state.execute_action(&Action::ScrollToTop, &settings); assert!(matches!(result, super::InputAction::Continue)); // Non-inverted: visual top = highest index @@ -2747,7 +2749,7 @@ mod tests { use crate::command::client::search::keybindings::Action; let mut state = make_executor_state(100, 50); - let mut settings = Settings::now(); + let mut settings = Settings::new().unwrap(); settings.invert = true; let result = state.execute_action(&Action::ScrollToTop, &settings); assert!(matches!(result, super::InputAction::Continue)); @@ -2760,7 +2762,7 @@ mod tests { use crate::command::client::search::keybindings::Action; let mut state = make_executor_state(100, 50); - let settings = Settings::now(); + let settings = Settings::new().unwrap(); let result = state.execute_action(&Action::ScrollToBottom, &settings); assert!(matches!(result, super::InputAction::Continue)); // Non-inverted: visual bottom = index 0 @@ -2772,7 +2774,7 @@ mod tests { use crate::command::client::search::keybindings::Action; let mut state = make_executor_state(100, 0); - let settings = Settings::now(); + let settings = Settings::new().unwrap(); assert_eq!(state.tab_index, 0); state.execute_action(&Action::ToggleTab, &settings); assert_eq!(state.tab_index, 1); @@ -2785,7 +2787,7 @@ mod tests { use crate::command::client::search::keybindings::Action; let mut state = make_executor_state(100, 0); - let settings = Settings::now(); + let settings = Settings::new().unwrap(); assert!(!state.prefix); state.execute_action(&Action::EnterPrefixMode, &settings); assert!(state.prefix); @@ -2797,7 +2799,7 @@ mod tests { use crate::command::client::search::keybindings::Action; let mut state = make_executor_state(100, 0); - let mut settings = Settings::now(); + let mut settings = Settings::new().unwrap(); settings.exit_mode = ExitMode::ReturnOriginal; let result = state.execute_action(&Action::Exit, &settings); @@ -2813,7 +2815,7 @@ mod tests { use crate::command::client::search::keybindings::Action; let mut state = make_executor_state(100, 0); - let settings = Settings::now(); + let settings = Settings::new().unwrap(); let result = state.execute_action(&Action::ReturnOriginal, &settings); assert!(matches!(result, super::InputAction::ReturnOriginal)); } @@ -2823,7 +2825,7 @@ mod tests { use crate::command::client::search::keybindings::Action; let mut state = make_executor_state(100, 7); - let settings = Settings::now(); + let settings = Settings::new().unwrap(); let result = state.execute_action(&Action::Copy, &settings); assert!(matches!(result, super::InputAction::Copy(7))); } @@ -2833,7 +2835,7 @@ mod tests { use crate::command::client::search::keybindings::Action; let mut state = make_executor_state(100, 7); - let settings = Settings::now(); + let settings = Settings::new().unwrap(); let result = state.execute_action(&Action::Delete, &settings); assert!(matches!(result, super::InputAction::Delete(7))); } @@ -2843,7 +2845,7 @@ mod tests { use crate::command::client::search::keybindings::Action; let mut state = make_executor_state(100, 7); - let settings = Settings::now(); + let settings = Settings::new().unwrap(); let result = state.execute_action(&Action::SwitchContext, &settings); assert!(matches!(result, super::InputAction::SwitchContext(Some(7)))); } @@ -2853,7 +2855,7 @@ mod tests { use crate::command::client::search::keybindings::Action; let mut state = make_executor_state(100, 7); - let settings = Settings::now(); + let settings = Settings::new().unwrap(); let result = state.execute_action(&Action::ClearContext, &settings); assert!(matches!(result, super::InputAction::SwitchContext(None))); } @@ -2863,7 +2865,7 @@ mod tests { use crate::command::client::search::keybindings::Action; let mut state = make_executor_state(100, 50); - let settings = Settings::now(); + let settings = Settings::new().unwrap(); let result = state.execute_action(&Action::Noop, &settings); assert!(matches!(result, super::InputAction::Continue)); assert_eq!(state.results_state.selected(), 50); @@ -2875,7 +2877,7 @@ mod tests { let mut state = make_executor_state(100, 5); state.tab_index = 1; - let settings = Settings::now(); + let settings = Settings::new().unwrap(); let result = state.execute_action(&Action::Accept, &settings); assert!(matches!(result, super::InputAction::AcceptInspecting)); } @@ -2885,7 +2887,7 @@ mod tests { use crate::command::client::search::keybindings::Action; let mut state = make_executor_state(100, 0); - let settings = Settings::now(); + let settings = Settings::new().unwrap(); let original_mode = state.search_mode; let result = state.execute_action(&Action::CycleSearchMode, &settings); assert!(matches!(result, super::InputAction::Continue)); @@ -2901,7 +2903,7 @@ mod tests { state.search.input.insert('h'); state.search.input.insert('i'); state.keymap_mode = KeymapMode::VimNormal; - let settings = Settings::now(); + let settings = Settings::new().unwrap(); let result = state.execute_action(&Action::VimSearchInsert, &settings); assert!(matches!(result, super::InputAction::Continue)); // Should clear input and switch to insert mode @@ -2914,7 +2916,7 @@ mod tests { use crate::command::client::search::keybindings::Action; let mut state = make_executor_state(100, 0); - let settings = Settings::now(); + let settings = Settings::new().unwrap(); // Insert some text state.search.input.insert('h'); @@ -2946,7 +2948,7 @@ mod tests { use crate::command::client::search::keybindings::Action; let mut state = make_executor_state(100, 0); - let settings = Settings::now(); + let settings = Settings::new().unwrap(); // Insert "hello" state.search.input.insert('h'); @@ -2970,7 +2972,7 @@ mod tests { use ratatui::crossterm::event::{KeyCode, KeyEvent, KeyModifiers}; use std::collections::HashMap; - let mut settings = Settings::now(); + let mut settings = Settings::new().unwrap(); // Configure tab to return-query settings.keymap.emacs = HashMap::from([( "tab".to_string(), diff --git a/crates/turtle/src/command/client/search/keybindings/defaults.rs b/crates/turtle/src/command/client/search/keybindings/defaults.rs index 6627c84d..82219b33 100644 --- a/crates/turtle/src/command/client/search/keybindings/defaults.rs +++ b/crates/turtle/src/command/client/search/keybindings/defaults.rs @@ -527,7 +527,11 @@ impl KeymapSet { #[cfg(test)] mod tests { - use super::*; + use super::{ + Action, HashMap, KeymapSet, Settings, default_emacs_keymap, default_inspector_keymap, + default_prefix_keymap, default_vim_insert_keymap, default_vim_normal_keymap, key, + parse_binding_config, + }; use crate::command::client::search::keybindings::conditions::EvalContext; fn make_ctx(cursor: usize, width: usize, selected: usize, len: usize) -> EvalContext { @@ -543,7 +547,7 @@ mod tests { } fn default_settings() -> Settings { - Settings::utc() + Settings::new().unwrap() } // -- Emacs keymap tests -- @@ -977,7 +981,7 @@ mod tests { fn parse_simple_binding_config() { use crate::atuin_client::settings::KeyBindingConfig; let cfg = KeyBindingConfig::Simple("accept".to_string()); - let binding = super::parse_binding_config(&cfg).unwrap(); + let binding = parse_binding_config(&cfg).unwrap(); assert_eq!(binding.rules.len(), 1); assert!(binding.rules[0].condition.is_none()); assert_eq!(binding.rules[0].action, Action::Accept); @@ -996,7 +1000,7 @@ mod tests { action: "cursor-left".to_string(), }, ]); - let binding = super::parse_binding_config(&cfg).unwrap(); + let binding = parse_binding_config(&cfg).unwrap(); assert_eq!(binding.rules.len(), 2); assert!(binding.rules[0].condition.is_some()); assert_eq!(binding.rules[0].action, Action::Exit); @@ -1008,7 +1012,7 @@ mod tests { fn parse_binding_config_invalid_action() { use crate::atuin_client::settings::KeyBindingConfig; let cfg = KeyBindingConfig::Simple("not-a-real-action".to_string()); - assert!(super::parse_binding_config(&cfg).is_err()); + assert!(parse_binding_config(&cfg).is_err()); } #[test] @@ -1018,7 +1022,7 @@ mod tests { when: Some("not-a-real-condition".to_string()), action: "exit".to_string(), }]); - assert!(super::parse_binding_config(&cfg).is_err()); + assert!(parse_binding_config(&cfg).is_err()); } #[test] @@ -1213,22 +1217,6 @@ mod tests { } #[test] - fn keys_has_non_default_values_detection() { - use crate::atuin_client::settings::Keys; - - let standard = Keys::standard_defaults(); - assert!(!standard.has_non_default_values()); - - let mut modified = Keys::standard_defaults(); - modified.scroll_exits = false; - assert!(modified.has_non_default_values()); - - let mut modified = Keys::standard_defaults(); - modified.prefix = "x".to_string(); - assert!(modified.has_non_default_values()); - } - - #[test] fn original_input_empty_condition_in_config() { use crate::atuin_client::settings::{KeyBindingConfig, KeyRuleConfig}; use std::collections::HashMap; diff --git a/crates/turtle/src/command/client/search/keybindings/key.rs b/crates/turtle/src/command/client/search/keybindings/key.rs index 35107a24..841656d2 100644 --- a/crates/turtle/src/command/client/search/keybindings/key.rs +++ b/crates/turtle/src/command/client/search/keybindings/key.rs @@ -16,6 +16,10 @@ pub(crate) struct SingleKey { /// The key code portion of a key press. #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[expect( + variant_size_differences, + reason = "It's not that much. So should be ok?" +)] pub(crate) enum KeyCodeValue { Char(char), Enter, @@ -59,7 +63,7 @@ impl SingleKey { // we store the uppercase char directly and clear the shift flag // since the case already encodes it. if shift && !ctrl && !alt && !super_key && c.is_ascii_uppercase() { - return Some(SingleKey { + return Some(Self { code: KeyCodeValue::Char(c), ctrl: false, alt: false, @@ -74,7 +78,7 @@ impl SingleKey { KeyCode::Tab => KeyCodeValue::Tab, // BackTab is sent by many terminals for Shift+Tab KeyCode::BackTab => { - return Some(SingleKey { + return Some(Self { code: KeyCodeValue::Tab, ctrl, alt, @@ -98,7 +102,7 @@ impl SingleKey { _ => return None, }; - Some(SingleKey { + Some(Self { code, ctrl, alt, @@ -185,7 +189,7 @@ impl SingleKey { let c = chars[0]; // An uppercase letter implies shift (unless shift already specified) if c.is_ascii_uppercase() && !ctrl && !alt && !super_key { - return Ok(SingleKey { + return Ok(Self { code: KeyCodeValue::Char(c), ctrl: false, alt: false, @@ -200,7 +204,7 @@ impl SingleKey { } }; - Ok(SingleKey { + Ok(Self { code, ctrl, alt, @@ -272,9 +276,9 @@ impl KeyInput { if parts.len() > 1 { let keys: Result<Vec<SingleKey>, String> = parts.iter().map(|p| SingleKey::parse(p)).collect(); - Ok(KeyInput::Sequence(keys?)) + Ok(Self::Sequence(keys?)) } else { - Ok(KeyInput::Single(SingleKey::parse(s)?)) + Ok(Self::Single(SingleKey::parse(s)?)) } } } @@ -282,8 +286,8 @@ impl KeyInput { impl fmt::Display for KeyInput { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { - KeyInput::Single(k) => write!(f, "{k}"), - KeyInput::Sequence(keys) => { + Self::Single(k) => write!(f, "{k}"), + Self::Sequence(keys) => { for (i, k) in keys.iter().enumerate() { if i > 0 { write!(f, " ")?; @@ -305,7 +309,7 @@ impl Serialize for KeyInput { impl<'de> Deserialize<'de> for KeyInput { fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> { let s = String::deserialize(deserializer)?; - KeyInput::parse(&s).map_err(serde::de::Error::custom) + Self::parse(&s).map_err(serde::de::Error::custom) } } diff --git a/crates/turtle/src/command/mod.rs b/crates/turtle/src/command/mod.rs index 78de2d03..9a648254 100644 --- a/crates/turtle/src/command/mod.rs +++ b/crates/turtle/src/command/mod.rs @@ -101,11 +101,11 @@ fn semantic_command_capture_sink() -> Option<crate::atuin_pty_proxy::CommandCapt }); Some(Box::new(move |capture| { - let _ = tx.try_send(capture); + drop(tx.try_send(capture)); })) } -#[cfg(all(feature = "daemon", feature = "pty-proxy", unix))] +#[cfg(unix)] #[inline] fn is_truthy_env(name: &str) -> bool { std::env::var(name) @@ -114,14 +114,16 @@ fn is_truthy_env(name: &str) -> bool { .is_some_and(|value| !value.trim().is_empty() && value.trim() != "false") } -#[cfg(all(feature = "daemon", feature = "pty-proxy", unix))] +#[cfg(unix)] async fn send_semantic_command_captures( settings: &crate::atuin_client::settings::Settings, batch: Vec<crate::atuin_pty_proxy::CommandCapture>, ) { + use crate::atuin_daemon::generated; + let captures = batch .into_iter() - .map(|capture| crate::atuin_daemon::semantic::CommandCapture { + .map(|capture| generated::semantic::CommandCapture { prompt: capture.prompt, command: capture.command, output: capture.output, @@ -134,6 +136,6 @@ async fn send_semantic_command_captures( .collect(); if let Ok(mut client) = crate::atuin_daemon::SemanticClient::from_settings(settings).await { - let _ = client.record_commands(captures).await; + drop(client.record_commands(captures).await); } } |
