diff --git a/src/app.rs b/src/app.rs index 8cdec92..527e185 100644 --- a/src/app.rs +++ b/src/app.rs @@ -494,11 +494,10 @@ impl App { pub fn selected_target_dir(&self) -> Option { if self.selected_indices.len() == 1 { let i = self.selected_indices[0]; - if let Some(e) = self.entries.get(i) { - if e.is_dir() { + if let Some(e) = self.entries.get(i) + && e.is_dir() { return Some(e.path.clone()); } - } } Some(self.current_path.clone()) } diff --git a/src/config.rs b/src/config.rs index 9cede57..443e7c3 100644 --- a/src/config.rs +++ b/src/config.rs @@ -2,9 +2,11 @@ use serde::{Deserialize, Serialize}; use std::path::PathBuf; #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +#[derive(Default)] pub enum AppliesTo { File, Dir, + #[default] Both, } @@ -25,9 +27,6 @@ impl AppliesTo { } } -impl Default for AppliesTo { - fn default() -> Self { AppliesTo::Both } -} #[derive(Serialize, Deserialize, Clone, Default, Debug)] pub struct CustomMenuItem { @@ -49,22 +48,19 @@ impl Config { /// Preferred path: config.json next to the running binary. /// Falls back to ~/.config/tui-fm/config.json if the exe path can't be determined. fn config_path() -> Option { - if let Ok(exe) = std::env::current_exe() { - if let Some(dir) = exe.parent() { + if let Ok(exe) = std::env::current_exe() + && let Some(dir) = exe.parent() { return Some(dir.join("config.json")); } - } dirs::config_dir().map(|d| d.join("tui-fm").join("config.json")) } pub fn load() -> Self { - if let Some(path) = Self::config_path() { - if let Ok(data) = std::fs::read_to_string(&path) { - if let Ok(config) = serde_json::from_str::(&data) { + if let Some(path) = Self::config_path() + && let Ok(data) = std::fs::read_to_string(&path) + && let Ok(config) = serde_json::from_str::(&data) { return config; } - } - } Config::default() } diff --git a/src/events.rs b/src/events.rs index a25aa57..baba877 100644 --- a/src/events.rs +++ b/src/events.rs @@ -46,9 +46,8 @@ fn handle_key(app: &mut App, key: crossterm::event::KeyEvent) -> bool { match key.code { KeyCode::Esc => { app.context_menu = None; return false; } KeyCode::Up => { - if let Some(ref mut m) = app.context_menu { - if m.selected > 0 { m.selected -= 1; } - } + if let Some(ref mut m) = app.context_menu + && m.selected > 0 { m.selected -= 1; } return false; } KeyCode::Down => { @@ -170,8 +169,8 @@ fn handle_key(app: &mut App, key: crossterm::event::KeyEvent) -> bool { app.path_input_sel_anchor = None; } KeyCode::Backspace => { - if !delete_selection(app) { - if app.path_input_cursor > 0 { + if !delete_selection(app) + && app.path_input_cursor > 0 { let remove_pos = app.path_input_cursor - 1; let new: String = app.path_input.chars().enumerate() .filter(|&(i, _)| i != remove_pos) @@ -180,19 +179,17 @@ fn handle_key(app: &mut App, key: crossterm::event::KeyEvent) -> bool { app.path_input = new; app.path_input_cursor -= 1; } - } app.path_input_sel_anchor = None; } KeyCode::Delete => { - if !delete_selection(app) { - if app.path_input_cursor < char_count { + if !delete_selection(app) + && app.path_input_cursor < char_count { let new: String = app.path_input.chars().enumerate() .filter(|&(i, _)| i != app.path_input_cursor) .map(|(_, c)| c) .collect(); app.path_input = new; } - } app.path_input_sel_anchor = None; } KeyCode::Left => { @@ -284,12 +281,11 @@ fn handle_key(app: &mut App, key: crossterm::event::KeyEvent) -> bool { app.navigate_up(); } KeyCode::F(2) => { - if let Some(&i) = app.selected_indices.first() { - if let Some(e) = app.entries.get(i) { + if let Some(&i) = app.selected_indices.first() + && let Some(e) = app.entries.get(i) { app.rename_original = Some(e.path.clone()); app.dialog = DialogMode::Rename(e.name.clone()); } - } } KeyCode::Delete => { if !app.selected_indices.is_empty() { @@ -298,15 +294,12 @@ fn handle_key(app: &mut App, key: crossterm::event::KeyEvent) -> bool { } } KeyCode::Enter => { - if app.focus == Focus::FileView { - if let Some(&i) = app.selected_indices.first() { - if let Some(e) = app.entries.get(i).cloned() { - if e.is_dir() { + if app.focus == Focus::FileView + && let Some(&i) = app.selected_indices.first() + && let Some(e) = app.entries.get(i).cloned() + && e.is_dir() { app.navigate_to(e.path.clone()); } - } - } - } } KeyCode::Up => { if app.focus == Focus::FileView { @@ -395,12 +388,11 @@ fn execute_context_menu(app: &mut App) { app.paste_into(&dst.clone()); } ContextMenuItem::Rename => { - if let Some(&i) = app.selected_indices.first() { - if let Some(e) = app.entries.get(i) { + if let Some(&i) = app.selected_indices.first() + && let Some(e) = app.entries.get(i) { app.rename_original = Some(e.path.clone()); app.dialog = DialogMode::Rename(e.name.clone()); } - } } ContextMenuItem::Properties => app.compute_properties(), ContextMenuItem::NewFile => app.dialog = DialogMode::NewFile(String::new()), @@ -838,7 +830,7 @@ fn handle_left_click(app: &mut App, col: u16, row: u16) { let char_count = app.path_input.chars().count(); let input_w = inner_w.saturating_sub(hint_width + 1 + 6); let avail = input_w.saturating_sub(label_display_w) as usize; - let scroll_start = if app.path_input_cursor > avail { app.path_input_cursor - avail } else { 0 }; + let scroll_start = app.path_input_cursor.saturating_sub(avail); let new_cursor = (scroll_start + click_offset).min(char_count); app.path_input_cursor = new_cursor; } @@ -883,11 +875,10 @@ fn handle_left_click(app: &mut App, col: u16, row: u16) { if is_double { app.last_click_entry = None; - if let Some(e) = app.entries.get(idx).cloned() { - if e.is_dir() { + if let Some(e) = app.entries.get(idx).cloned() + && e.is_dir() { app.navigate_to(e.path.clone()); } - } } else { app.select_only(idx); } @@ -899,22 +890,20 @@ fn handle_right_click(app: &mut App, col: u16, row: u16) { // Right-click on sidebar favorite if col < layout.sidebar.x + layout.sidebar.width { - if let Some(item) = hit_test_sidebar(app, col, row, &layout) { - if let SidebarItem::Favorite(_, path) = item { + if let Some(item) = hit_test_sidebar(app, col, row, &layout) + && let SidebarItem::Favorite(_, path) = item { let menu = app.build_context_menu(col, row, true, Some(path)); app.context_menu = Some(menu); return; } - } return; } // Right-click on file - if let Some(idx) = hit_test_file_view(app, col, row, &layout) { - if !app.selected_indices.contains(&idx) { + if let Some(idx) = hit_test_file_view(app, col, row, &layout) + && !app.selected_indices.contains(&idx) { app.select_only(idx); } - } let menu = app.build_context_menu(col, row, false, None); app.context_menu = Some(menu); @@ -985,8 +974,8 @@ fn handle_mouse_move(app: &mut App, col: u16, row: u16) { } // When NewSubmenu is highlighted, check if the mouse moves into the flyout - if let Some(ns_pos) = menu.items.iter().position(|i| matches!(i, ContextMenuItem::NewSubmenu)) { - if menu.selected == ns_pos { + if let Some(ns_pos) = menu.items.iter().position(|i| matches!(i, ContextMenuItem::NewSubmenu)) + && menu.selected == ns_pos { let (term_w, _) = app.term_size; let sub_x = (mx + MENU_W).min(term_w.saturating_sub(SUB_W)); let sub_y = my + 1 + ns_pos as u16; @@ -998,10 +987,8 @@ fn handle_mouse_move(app: &mut App, col: u16, row: u16) { if row > sub_y && row < sub_y + 3 { menu.sub_selected = Some((row - sub_y - 1) as usize); } - return; } } - } } /// Handle mouse drag for text selection in the path input bar. @@ -1032,7 +1019,7 @@ fn handle_mouse_drag(app: &mut App, col: u16, row: u16) { let click_offset = (col - text_start_x) as usize; let char_count = app.path_input.chars().count(); let avail = inner_w.saturating_sub(hint_width + 1 + 6).saturating_sub(label_display_w) as usize; - let scroll_start = if app.path_input_cursor > avail { app.path_input_cursor - avail } else { 0 }; + let scroll_start = app.path_input_cursor.saturating_sub(avail); app.path_input_cursor = (scroll_start + click_offset).min(char_count); } } diff --git a/src/ui.rs b/src/ui.rs index 271243c..1693d9e 100644 --- a/src/ui.rs +++ b/src/ui.rs @@ -444,7 +444,7 @@ fn draw_bottom_bar(f: &mut Frame, app: &App, area: Rect) { ]; if focused { - let scroll_start = if cursor_pos > avail { cursor_pos - avail } else { 0 }; + let scroll_start = cursor_pos.saturating_sub(avail); if let Some((sel_start, sel_end)) = sel_range { // Render with selection highlight @@ -517,7 +517,7 @@ fn scroll_input_text(text: &str, cursor: usize, avail: usize) -> (String, usize) if char_count <= avail { return (text.to_string(), cursor); } - let start = if cursor > avail { cursor - avail } else { 0 }; + let start = cursor.saturating_sub(avail); let end = (start + avail).min(char_count); let slice: String = text.chars().skip(start).take(end - start).collect(); let cursor_in_display = cursor.saturating_sub(start);