diff --git a/Cargo.toml b/Cargo.toml index 403692b..3561d83 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,9 +9,18 @@ ratatui = { version = "0.30", features = ["crossterm"] } [lints.clippy] pedantic = "warn" -nursery = "warn" -restriction = "warn" unused_trait_names = "warn" missing_docs_in_private_items = "warn" empty_structs_with_brackets = "warn" -let_underscore_must_use = "warn" \ No newline at end of file +let_underscore_must_use = "warn" +arbitrary_source_item_ordering = "warn" +as_conversions = "warn" +default_constructed_unit_structs = "warn" +equatable_if_let = "warn" +indexing_slicing = "warn" +missing_assert_message = "warn" +panic_in_result_fn = "warn" +redundant_closure_for_method_calls = "warn" +str_to_string = "warn" +used_underscore_binding = "warn" +wildcard_enum_match_arm = "warn" \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 4ed7851..ac4a871 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,14 +1,14 @@ +mod terminal_guard; + +use core::time::Duration; use crossterm::event::{self, Event, KeyCode}; use crossterm::execute; use crossterm::terminal::{EnterAlternateScreen, enable_raw_mode}; use ratatui::Terminal; use ratatui::backend::CrosstermBackend; -use ratatui::layout::{Constraint, Direction, Layout}; use ratatui::style::Style; use ratatui::widgets::{Block, Borders, List, ListItem, ListState}; use std::io::{self, Read as _}; -use core::time::Duration; -mod terminal_guard; use terminal_guard::TerminalModeGuard; fn main() -> Result<(), Box> { @@ -20,14 +20,17 @@ fn main() -> Result<(), Box> { return Ok(()); } - let lines: Vec = input.lines().map(|s| s.to_string()).collect(); + let lines: Vec = input + .lines() + .map(std::string::ToString::to_string) + .collect(); let mut marked = vec![false; lines.len()]; enable_raw_mode()?; let mut stdout = std::io::stdout(); execute!(stdout, EnterAlternateScreen)?; - let mut _mode_guard = TerminalModeGuard::default(); + let mode_guard = TerminalModeGuard; let backend = CrosstermBackend::new(stdout); let mut terminal = Terminal::new(backend)?; @@ -40,17 +43,13 @@ fn main() -> Result<(), Box> { loop { terminal.draw(|f| { let size = f.area(); - let chunks = Layout::default() - .direction(Direction::Vertical) - .constraints([Constraint::Min(0)].as_ref()) - .split(size); let items: Vec = lines .iter() - .enumerate() - .map(|(i, l)| { - let prefix = if marked[i] { 'x' } else { ' ' }; - ListItem::new(format!("[{prefix}] {l}")) + .zip(marked.iter()) + .map(|(text, marked)| { + let prefix = if *marked { 'x' } else { ' ' }; + ListItem::new(format!("[{prefix}] {text}")) }) .collect(); @@ -62,7 +61,7 @@ fn main() -> Result<(), Box> { ) .highlight_style(Style::default().bold().yellow().on_dark_gray()); - f.render_stateful_widget(list, chunks[0], &mut state); + f.render_stateful_widget(list, size, &mut state); })?; if event::poll(Duration::from_millis(100))? { @@ -81,12 +80,14 @@ fn main() -> Result<(), Box> { } KeyCode::Char(' ') => { if let Some(i) = state.selected() { - assert!(i < marked.len()); - if !marked[i] { + let Some(marked_cell) = marked.get_mut(i) else { + return Err("Index out of bounds".into()); + }; + if !*marked_cell { let next = lines.len().min(i + 1); state.select(Some(next)); } - marked[i] = !marked[i]; + *marked_cell = !*marked_cell; } } KeyCode::Char('c') if key.modifiers.contains(event::KeyModifiers::CONTROL) => { @@ -95,7 +96,7 @@ fn main() -> Result<(), Box> { _ => {} }, Event::Mouse(s) => { - if let event::MouseEventKind::Down(event::MouseButton::Left) = s.kind { + if s.kind == event::MouseEventKind::Down(event::MouseButton::Left) { let area = terminal.size()?; if s.row > area.height && s.row < area.height + area.height { let idx = (s.row - area.height - 1) as usize; @@ -110,7 +111,7 @@ fn main() -> Result<(), Box> { } } - drop(_mode_guard); + drop(mode_guard); terminal.show_cursor()?; Ok(()) diff --git a/src/terminal_guard.rs b/src/terminal_guard.rs index 2910776..0cbfb99 100644 --- a/src/terminal_guard.rs +++ b/src/terminal_guard.rs @@ -1,3 +1,4 @@ +//! A guard that restores the terminal state on drop. use crossterm::cursor::Show; use crossterm::execute; use crossterm::terminal::{LeaveAlternateScreen, disable_raw_mode};