aboutsummaryrefslogtreecommitdiffstats
path: root/crates/turtle/src/command/client
diff options
context:
space:
mode:
authorBenedikt Peetz <benedikt.peetz@b-peetz.de>2026-06-13 00:50:54 +0200
committerBenedikt Peetz <benedikt.peetz@b-peetz.de>2026-06-13 00:50:54 +0200
commit6723829a3398b3c9dd6dc6ae79124f46000606ee (patch)
treea1ec535eddd711a4557e4bcc5b94382c3623504c /crates/turtle/src/command/client
parentchore(treewide): Cleanup themes (diff)
downloadatuin-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 'crates/turtle/src/command/client')
-rw-r--r--crates/turtle/src/command/client/daemon.rs51
-rw-r--r--crates/turtle/src/command/client/history.rs15
-rw-r--r--crates/turtle/src/command/client/search.rs2
-rw-r--r--crates/turtle/src/command/client/search/engines.rs6
-rw-r--r--crates/turtle/src/command/client/search/engines/db.rs2
-rw-r--r--crates/turtle/src/command/client/search/engines/skim.rs2
-rw-r--r--crates/turtle/src/command/client/search/inspector.rs8
-rw-r--r--crates/turtle/src/command/client/search/interactive.rs158
-rw-r--r--crates/turtle/src/command/client/search/keybindings/defaults.rs32
-rw-r--r--crates/turtle/src/command/client/search/keybindings/key.rs24
10 files changed, 133 insertions, 167 deletions
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)
}
}