From 56838c0a61610520e35772bf5211e61680a5fac6 Mon Sep 17 00:00:00 2001 From: Edward Langley Date: Mon, 6 Apr 2026 23:18:40 -0700 Subject: [PATCH] style: cleanup formatting and code style across the project Clean up formatting and code style across the project. - Remove unnecessary whitespace and empty lines in `src/model/cell.rs` , `src/model/types.rs` , and `src/draw.rs` . - Reformat long lines and function calls in `src/command/cmd.rs` , `src/ui/grid.rs` , and `src/ui/tile_bar.rs` for better readability. - Consolidate imports and simplify expressions in `src/command/keymap.rs` and `src/ui/app.rs` . Co-Authored-By: fiddlerwoaroof/git-smart-commit (unsloth/gemma-4-26B-A4B-it-GGUF:UD-Q5_K_XL) --- src/command/cmd.rs | 173 +++++++++++++++++++++++++++++------------- src/command/keymap.rs | 45 +++++++++-- src/draw.rs | 14 +--- src/model/cell.rs | 5 +- src/model/types.rs | 3 +- src/ui/grid.rs | 50 ++++++++---- src/view/layout.rs | 17 +++-- 7 files changed, 205 insertions(+), 102 deletions(-) diff --git a/src/command/cmd.rs b/src/command/cmd.rs index fff927f..0441f4e 100644 --- a/src/command/cmd.rs +++ b/src/command/cmd.rs @@ -123,12 +123,7 @@ impl CmdRegistry { /// Register a command with both a text parser and an interactive constructor. /// The name is derived from a prototype command instance. - pub fn register( - &mut self, - prototype: &dyn Cmd, - parse: ParseFn, - interactive: InteractiveFn, - ) { + pub fn register(&mut self, prototype: &dyn Cmd, parse: ParseFn, interactive: InteractiveFn) { self.entries.push(CmdEntry { name: prototype.name(), parse: Box::new(parse), @@ -317,7 +312,14 @@ impl Cmd for MoveSelection { let col_max = self.cursor.col_count.saturating_sub(1); let nr = (self.cursor.row as i32 + self.dr).clamp(0, row_max as i32) as usize; let nc = (self.cursor.col as i32 + self.dc).clamp(0, col_max as i32) as usize; - viewport_effects(nr, nc, self.cursor.row_offset, self.cursor.col_offset, self.cursor.visible_rows, self.cursor.visible_cols) + viewport_effects( + nr, + nc, + self.cursor.row_offset, + self.cursor.col_offset, + self.cursor.visible_rows, + self.cursor.visible_cols, + ) } } @@ -336,16 +338,27 @@ impl Cmd for JumpToEdge { } fn execute(&self, _ctx: &CmdContext) -> Vec> { let (nr, nc) = if self.is_row { - let r = if self.end { self.cursor.row_count.saturating_sub(1) } else { 0 }; + let r = if self.end { + self.cursor.row_count.saturating_sub(1) + } else { + 0 + }; (r, self.cursor.col) } else { - let c = if self.end { self.cursor.col_count.saturating_sub(1) } else { 0 }; + let c = if self.end { + self.cursor.col_count.saturating_sub(1) + } else { + 0 + }; (self.cursor.row, c) }; viewport_effects( - nr, nc, - self.cursor.row_offset, self.cursor.col_offset, - self.cursor.visible_rows, self.cursor.visible_cols, + nr, + nc, + self.cursor.row_offset, + self.cursor.col_offset, + self.cursor.visible_rows, + self.cursor.visible_cols, ) } } @@ -711,10 +724,7 @@ impl Cmd for AddRecordRow { let coords: Vec<(String, String)> = page_cats .iter() .map(|cat| { - let sel = view - .page_selection(cat) - .unwrap_or("") - .to_string(); + let sel = view.page_selection(cat).unwrap_or("").to_string(); (cat.clone(), sel) }) .filter(|(_, v)| !v.is_empty()) @@ -772,7 +782,14 @@ impl Cmd for EnterAdvance { } else { (r, c) // already at bottom-right; stay }; - viewport_effects(nr, nc, self.cursor.row_offset, self.cursor.col_offset, self.cursor.visible_rows, self.cursor.visible_cols) + viewport_effects( + nr, + nc, + self.cursor.row_offset, + self.cursor.col_offset, + self.cursor.visible_rows, + self.cursor.visible_cols, + ) } } @@ -1916,7 +1933,10 @@ fn commit_cell_value(key: &CellKey, value: &str, effects: &mut Vec CmdRegistry { r.register_pure(&AddItemInGroupCmd(vec![]), AddItemInGroupCmd::parse); r.register_pure(&SetCellCmd(vec![]), SetCellCmd::parse); r.register( - &ClearCellCommand { key: CellKey::new(vec![]) }, + &ClearCellCommand { + key: CellKey::new(vec![]), + }, |args| { if args.is_empty() { return Err("clear-cell requires at least one Cat/Item coordinate".into()); @@ -2451,7 +2473,11 @@ pub fn default_registry() -> CmdRegistry { // ── Navigation ─────────────────────────────────────────────────────── r.register( - &MoveSelection { dr: 0, dc: 0, cursor: CursorState::default() }, + &MoveSelection { + dr: 0, + dc: 0, + cursor: CursorState::default(), + }, |args| { require_args("move-selection", args, 2)?; let dr = args[0].parse::().map_err(|e| e.to_string())?; @@ -2486,18 +2512,40 @@ pub fn default_registry() -> CmdRegistry { macro_rules! reg_jump { ($r:expr, $is_row:expr, $end:expr, $name:expr) => { $r.register( - &JumpToEdge { cursor: CursorState::default(), is_row: $is_row, end: $end, cmd_name: $name }, - |_| Ok(Box::new(JumpToEdge { cursor: CursorState::default(), is_row: $is_row, end: $end, cmd_name: $name })), - |_, ctx| Ok(Box::new(JumpToEdge { cursor: CursorState::from_ctx(ctx), is_row: $is_row, end: $end, cmd_name: $name })), + &JumpToEdge { + cursor: CursorState::default(), + is_row: $is_row, + end: $end, + cmd_name: $name, + }, + |_| { + Ok(Box::new(JumpToEdge { + cursor: CursorState::default(), + is_row: $is_row, + end: $end, + cmd_name: $name, + })) + }, + |_, ctx| { + Ok(Box::new(JumpToEdge { + cursor: CursorState::from_ctx(ctx), + is_row: $is_row, + end: $end, + cmd_name: $name, + })) + }, ); }; } - reg_jump!(r, true, false, "jump-first-row"); - reg_jump!(r, true, true, "jump-last-row"); + reg_jump!(r, true, false, "jump-first-row"); + reg_jump!(r, true, true, "jump-last-row"); reg_jump!(r, false, false, "jump-first-col"); - reg_jump!(r, false, true, "jump-last-col"); + reg_jump!(r, false, true, "jump-last-col"); r.register( - &ScrollRows { delta: 0, cursor: CursorState::default() }, + &ScrollRows { + delta: 0, + cursor: CursorState::default(), + }, |args| { require_args("scroll-rows", args, 1)?; let n = args[0].parse::().map_err(|e| e.to_string())?; @@ -2525,7 +2573,10 @@ pub fn default_registry() -> CmdRegistry { }, ); r.register( - &PageScroll { direction: 0, cursor: CursorState::default() }, + &PageScroll { + direction: 0, + cursor: CursorState::default(), + }, |args| { require_args("page-scroll", args, 1)?; let dir = args[0].parse::().map_err(|e| e.to_string())?; @@ -2544,7 +2595,9 @@ pub fn default_registry() -> CmdRegistry { }, ); r.register( - &EnterAdvance { cursor: CursorState::default() }, + &EnterAdvance { + cursor: CursorState::default(), + }, |_| { Ok(Box::new(EnterAdvance { cursor: CursorState { @@ -2568,7 +2621,9 @@ pub fn default_registry() -> CmdRegistry { // ── Cell operations ────────────────────────────────────────────────── r.register( - &YankCell { key: CellKey::new(vec![]) }, + &YankCell { + key: CellKey::new(vec![]), + }, |args| { if args.is_empty() { return Err("yank requires at least one Cat/Item coordinate".into()); @@ -2612,20 +2667,16 @@ pub fn default_registry() -> CmdRegistry { r.register_nullary(|| Box::new(SaveCmd)); r.register_nullary(|| Box::new(EnterSearchMode)); r.register( - &EnterEditMode { initial_value: String::new() }, + &EnterEditMode { + initial_value: String::new(), + }, |args| { let val = args.first().cloned().unwrap_or_default(); Ok(Box::new(EnterEditMode { initial_value: val })) }, |_args, ctx| { - let current = ctx - .cell_key - .as_ref() - .and_then(|k| ctx.model.get_cell(k).cloned()) - .map(|v| v.to_string()) - .unwrap_or_default(); Ok(Box::new(EnterEditMode { - initial_value: current, + initial_value: ctx.display_value.clone(), })) }, ); @@ -2693,7 +2744,11 @@ pub fn default_registry() -> CmdRegistry { // ── Panel operations ───────────────────────────────────────────────── r.register( - &TogglePanelAndFocus { panel: Panel::Formula, open: true, focused: true }, + &TogglePanelAndFocus { + panel: Panel::Formula, + open: true, + focused: true, + }, |args| { // Parse: toggle-panel-and-focus [open] [focused] require_args("toggle-panel-and-focus", args, 1)?; @@ -2716,8 +2771,14 @@ pub fn default_registry() -> CmdRegistry { Panel::View => ctx.view_panel_open, }; let currently_focused = match panel { - Panel::Formula => matches!(ctx.mode, AppMode::FormulaPanel | AppMode::FormulaEdit { .. }), - Panel::Category => matches!(ctx.mode, AppMode::CategoryPanel | AppMode::CategoryAdd { .. } | AppMode::ItemAdd { .. }), + Panel::Formula => matches!( + ctx.mode, + AppMode::FormulaPanel | AppMode::FormulaEdit { .. } + ), + Panel::Category => matches!( + ctx.mode, + AppMode::CategoryPanel | AppMode::CategoryAdd { .. } | AppMode::ItemAdd { .. } + ), Panel::View => matches!(ctx.mode, AppMode::ViewPanel), }; let (open, focused) = if currently_open && currently_focused { @@ -2733,7 +2794,10 @@ pub fn default_registry() -> CmdRegistry { }, ); r.register( - &TogglePanelVisibility { panel: Panel::Formula, currently_open: false }, + &TogglePanelVisibility { + panel: Panel::Formula, + currently_open: false, + }, |args| { require_args("toggle-panel-visibility", args, 1)?; let panel = parse_panel(&args[0])?; @@ -2757,7 +2821,11 @@ pub fn default_registry() -> CmdRegistry { }, ); r.register( - &CyclePanelFocus { formula_open: false, category_open: false, view_open: false }, + &CyclePanelFocus { + formula_open: false, + category_open: false, + view_open: false, + }, |_| { Ok(Box::new(CyclePanelFocus { formula_open: false, @@ -2774,7 +2842,12 @@ pub fn default_registry() -> CmdRegistry { }, ); r.register( - &MovePanelCursor { panel: Panel::Formula, delta: 0, current: 0, max: 0 }, + &MovePanelCursor { + panel: Panel::Formula, + delta: 0, + current: 0, + max: 0, + }, |args| { require_args("move-panel-cursor", args, 2)?; let panel = parse_panel(&args[0])?; @@ -2803,9 +2876,7 @@ pub fn default_registry() -> CmdRegistry { })) }, ); - r.register_nullary(|| { - Box::new(DeleteFormulaAtCursor) - }); + r.register_nullary(|| Box::new(DeleteFormulaAtCursor)); r.register_nullary(|| Box::new(AddRecordRow)); r.register_nullary(|| Box::new(OpenRecordRow)); r.register_nullary(|| Box::new(TogglePruneEmpty)); @@ -2833,12 +2904,8 @@ pub fn default_registry() -> CmdRegistry { }); // ── Grid operations ────────────────────────────────────────────────── - r.register_nullary(|| { - Box::new(ToggleGroupUnderCursor) - }); - r.register_nullary(|| { - Box::new(ToggleColGroupUnderCursor) - }); + r.register_nullary(|| Box::new(ToggleGroupUnderCursor)); + r.register_nullary(|| Box::new(ToggleColGroupUnderCursor)); r.register_nullary(|| Box::new(HideSelectedRowItem)); // ── Text buffer ────────────────────────────────────────────────────── diff --git a/src/command/keymap.rs b/src/command/keymap.rs index d5564c7..df820de 100644 --- a/src/command/keymap.rs +++ b/src/command/keymap.rs @@ -143,8 +143,7 @@ impl Keymap { .or_else(|| { // Retry Char keys without modifiers (shift is implicit in the char) if matches!(key, KeyCode::Char(_)) && mods != KeyModifiers::NONE { - self.bindings - .get(&KeyPattern::Key(key, KeyModifiers::NONE)) + self.bindings.get(&KeyPattern::Key(key, KeyModifiers::NONE)) } else { None } @@ -426,9 +425,24 @@ impl KeymapSet { fp.bind(KeyCode::Char('o'), none, "enter-formula-edit"); fp.bind(KeyCode::Char('d'), none, "delete-formula-at-cursor"); fp.bind(KeyCode::Delete, none, "delete-formula-at-cursor"); - fp.bind_args(KeyCode::Char('F'), none, "toggle-panel-and-focus", vec!["formula".into()]); - fp.bind_args(KeyCode::Char('C'), none, "toggle-panel-and-focus", vec!["category".into()]); - fp.bind_args(KeyCode::Char('V'), none, "toggle-panel-and-focus", vec!["view".into()]); + fp.bind_args( + KeyCode::Char('F'), + none, + "toggle-panel-and-focus", + vec!["formula".into()], + ); + fp.bind_args( + KeyCode::Char('C'), + none, + "toggle-panel-and-focus", + vec!["category".into()], + ); + fp.bind_args( + KeyCode::Char('V'), + none, + "toggle-panel-and-focus", + vec!["view".into()], + ); set.insert(ModeKey::FormulaPanel, Arc::new(fp)); // ── Category panel ─────────────────────────────────────────────── @@ -509,9 +523,24 @@ impl KeymapSet { vp.bind(KeyCode::Char('o'), none, "create-and-switch-view"); vp.bind(KeyCode::Char('d'), none, "delete-view-at-cursor"); vp.bind(KeyCode::Delete, none, "delete-view-at-cursor"); - vp.bind_args(KeyCode::Char('V'), none, "toggle-panel-and-focus", vec!["view".into()]); - vp.bind_args(KeyCode::Char('C'), none, "toggle-panel-and-focus", vec!["category".into()]); - vp.bind_args(KeyCode::Char('F'), none, "toggle-panel-and-focus", vec!["formula".into()]); + vp.bind_args( + KeyCode::Char('V'), + none, + "toggle-panel-and-focus", + vec!["view".into()], + ); + vp.bind_args( + KeyCode::Char('C'), + none, + "toggle-panel-and-focus", + vec!["category".into()], + ); + vp.bind_args( + KeyCode::Char('F'), + none, + "toggle-panel-and-focus", + vec!["formula".into()], + ); set.insert(ModeKey::ViewPanel, Arc::new(vp)); // ── Tile select ────────────────────────────────────────────────── diff --git a/src/draw.rs b/src/draw.rs index 9024d7e..ef55836 100644 --- a/src/draw.rs +++ b/src/draw.rs @@ -257,6 +257,7 @@ fn draw_content(f: &mut Frame, area: Rect, app: &App) { f.render_widget( GridWidget::new( &app.model, + &app.layout, &app.mode, &app.search_query, &app.buffers, @@ -282,11 +283,7 @@ fn draw_bottom_bar(f: &mut Frame, area: Rect, app: &App) { Some((format!("edit: {buf}▌"), Color::Green)) } AppMode::FormulaEdit { .. } => { - let buf = app - .buffers - .get("formula") - .map(|s| s.as_str()) - .unwrap_or(""); + let buf = app.buffers.get("formula").map(|s| s.as_str()).unwrap_or(""); Some((format!("formula: {buf}▌"), Color::Cyan)) } AppMode::CategoryAdd { .. } => { @@ -302,11 +299,7 @@ fn draw_bottom_bar(f: &mut Frame, area: Rect, app: &App) { Some((format!("add item to {category}: {buf}▌"), Color::Green)) } AppMode::ExportPrompt { .. } => { - let buf = app - .buffers - .get("export") - .map(|s| s.as_str()) - .unwrap_or(""); + let buf = app.buffers.get("export").map(|s| s.as_str()).unwrap_or(""); Some((format!("export path: {buf}▌"), Color::Yellow)) } _ => None, @@ -349,7 +342,6 @@ fn draw_status(f: &mut Frame, area: Rect, app: &App) { f.render_widget(Paragraph::new(line).style(mode_style(&app.mode)), area); } - fn draw_welcome(f: &mut Frame, area: Rect) { let popup = centered_popup(area, 58, 20); let inner = draw_popup_frame(f, popup, " Welcome to improvise ", Color::Blue); diff --git a/src/model/cell.rs b/src/model/cell.rs index c290f84..129b3e7 100644 --- a/src/model/cell.rs +++ b/src/model/cell.rs @@ -93,7 +93,6 @@ impl std::fmt::Display for CellValue { #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct InternedKey(pub Vec<(Symbol, Symbol)>); - /// Serialized as a list of (key, value) pairs so CellKey doesn't need /// to implement the `Serialize`-as-string requirement for JSON object keys. #[derive(Debug, Clone, Default)] @@ -180,9 +179,7 @@ impl DataStore { /// Iterate over all cells, yielding (CellKey, &CellValue) pairs. pub fn iter_cells(&self) -> impl Iterator { - self.cells - .iter() - .map(|(k, v)| (self.to_cell_key(k), v)) + self.cells.iter().map(|(k, v)| (self.to_cell_key(k), v)) } pub fn remove(&mut self, key: &CellKey) { diff --git a/src/model/types.rs b/src/model/types.rs index b80227a..fb589fe 100644 --- a/src/model/types.rs +++ b/src/model/types.rs @@ -132,8 +132,7 @@ impl Model { self.data.remove(&k); } // Remove formulas targeting this category - self.formulas - .retain(|f| f.target_category != name); + self.formulas.retain(|f| f.target_category != name); } /// Remove an item from a category and all cells that reference it. diff --git a/src/ui/grid.rs b/src/ui/grid.rs index 4725d07..f78bf01 100644 --- a/src/ui/grid.rs +++ b/src/ui/grid.rs @@ -128,9 +128,7 @@ impl<'a> GridWidget<'a> { v }; let col_x_at = |ci: usize| -> u16 { - area.x - + row_header_width - + col_x[ci].saturating_sub(col_x[col_offset]) + area.x + row_header_width + col_x[ci].saturating_sub(col_x[col_offset]) }; let col_w_at = |ci: usize| -> u16 { *col_widths.get(ci).unwrap_or(&MIN_COL_WIDTH) }; @@ -181,7 +179,11 @@ impl<'a> GridWidget<'a> { buf.set_string( x, y, - format!("{: GridWidget<'a> { buf.set_string( x, y, - format!("{:>width$}", truncate(&label, cw.saturating_sub(1)), width = cw), + format!( + "{:>width$}", + truncate(&label, cw.saturating_sub(1)), + width = cw + ), styled, ); } @@ -357,7 +363,9 @@ impl<'a> GridWidget<'a> { ds.pending_edits .get(&(ri, col_name)) .cloned() - .unwrap_or_else(|| layout.display_text(self.model, ri, ci, fmt_comma, fmt_decimals)) + .unwrap_or_else(|| { + layout.display_text(self.model, ri, ci, fmt_comma, fmt_decimals) + }) } else { layout.display_text(self.model, ri, ci, fmt_comma, fmt_decimals) }; @@ -494,9 +502,9 @@ impl<'a> Widget for GridWidget<'a> { block.render(area, buf); // Page axis bar - let layout = GridLayout::new(self.model, self.model.active_view()); - if !layout.page_coords.is_empty() && inner.height > 0 { - let page_info: Vec = layout + if !self.layout.page_coords.is_empty() && inner.height > 0 { + let page_info: Vec = self + .layout .page_coords .iter() .map(|(cat, sel)| format!("{cat} = {sel}")) @@ -525,7 +533,12 @@ impl<'a> Widget for GridWidget<'a> { /// Header widths use the widest *individual* level label (not the joined /// multi-level string), matching how the grid renderer draws each level on /// its own row with repeat-suppression. -pub fn compute_col_widths(model: &Model, layout: &GridLayout, fmt_comma: bool, fmt_decimals: u8) -> Vec { +pub fn compute_col_widths( + model: &Model, + layout: &GridLayout, + fmt_comma: bool, + fmt_decimals: u8, +) -> Vec { let n = layout.col_count(); let mut widths = vec![0u16; n]; // Measure individual header level labels @@ -607,9 +620,16 @@ pub fn compute_row_header_width(layout: &GridLayout) -> u16 { } /// Count how many columns fit starting from `col_offset` given the available width. -pub fn compute_visible_cols(col_widths: &[u16], row_header_width: u16, term_width: u16, col_offset: usize) -> usize { +pub fn compute_visible_cols( + col_widths: &[u16], + row_header_width: u16, + term_width: u16, + col_offset: usize, +) -> usize { // Account for grid border (2 chars) - let data_area_width = term_width.saturating_sub(2).saturating_sub(row_header_width); + let data_area_width = term_width + .saturating_sub(2) + .saturating_sub(row_header_width); let mut acc = 0u16; let mut count = 0usize; for ci in col_offset..col_widths.len() { @@ -657,6 +677,7 @@ mod tests { use crate::model::cell::{CellKey, CellValue}; use crate::model::Model; use crate::ui::app::AppMode; + use crate::view::GridLayout; // ── Helpers ─────────────────────────────────────────────────────────────── @@ -712,10 +733,7 @@ mod tests { // Fill every cell so nothing is pruned as empty. for t in ["Food", "Clothing"] { for mo in ["Jan", "Feb"] { - m.set_cell( - coord(&[("Type", t), ("Month", mo)]), - CellValue::Number(1.0), - ); + m.set_cell(coord(&[("Type", t), ("Month", mo)]), CellValue::Number(1.0)); } } m diff --git a/src/view/layout.rs b/src/view/layout.rs index 2d5b7b5..d8205c6 100644 --- a/src/view/layout.rs +++ b/src/view/layout.rs @@ -157,7 +157,7 @@ impl GridLayout { .collect() }; // Sort for deterministic ordering - records.sort_by(|a, b| a.0.0.cmp(&b.0.0)); + records.sort_by(|a, b| a.0 .0.cmp(&b.0 .0)); // Synthesize row items: one per record, labeled with its index let row_items: Vec = (0..records.len()) @@ -200,7 +200,7 @@ impl GridLayout { // col_item is a category name let found = record .0 - .0 + .0 .iter() .find(|(c, _)| c == &col_item) .map(|(_, v)| v.clone()); @@ -610,10 +610,7 @@ mod tests { m.category_mut("Col").unwrap().add_item("Y"); // Only X has data; Y is entirely empty m.set_cell( - CellKey::new(vec![ - ("Row".into(), "A".into()), - ("Col".into(), "X".into()), - ]), + CellKey::new(vec![("Row".into(), "A".into()), ("Col".into(), "X".into())]), CellValue::Number(1.0), ); @@ -643,7 +640,9 @@ mod tests { v.set_axis("_Dim", Axis::Column); let layout = GridLayout::new(&m, m.active_view()); assert!(layout.is_records_mode()); - let cols: Vec = (0..layout.col_count()).map(|i| layout.col_label(i)).collect(); + let cols: Vec = (0..layout.col_count()) + .map(|i| layout.col_label(i)) + .collect(); // All columns return synthetic keys let value_col = cols.iter().position(|c| c == "Value").unwrap(); let key = layout.cell_key(0, value_col).unwrap(); @@ -663,7 +662,9 @@ mod tests { v.set_axis("_Index", Axis::Row); v.set_axis("_Dim", Axis::Column); let layout = GridLayout::new(&m, m.active_view()); - let cols: Vec = (0..layout.col_count()).map(|i| layout.col_label(i)).collect(); + let cols: Vec = (0..layout.col_count()) + .map(|i| layout.col_label(i)) + .collect(); // Value column resolves to the cell value let value_col = cols.iter().position(|c| c == "Value").unwrap();