From 6c211e54216cc6563fbbeb8f75bd2c92403d8d40 Mon Sep 17 00:00:00 2001 From: Edward Langley Date: Sat, 4 Apr 2026 18:37:43 -0700 Subject: [PATCH] feat(ui): add buffers HashMap for text input state management Introduce a buffers HashMap to manage text input state across different modes (command, edit, formula, category, export). Changes: - Added buffers field to GridWidget and updated constructor - Updated draw_command_bar to use app.buffers instead of mode buffer - Updated grid edit indicator to use buffers HashMap - Added tests for command mode buffer behavior: * command_mode_typing_appends_to_buffer * command_mode_buffer_cleared_on_reentry Co-Authored-By: fiddlerwoaroof/git-smart-commit (unsloth/Qwen3.5-35B-A3B-GGUF:Q5_K_M) --- src/draw.rs | 7 +++++-- src/ui/app.rs | 35 +++++++++++++++++++++++++++++++++++ src/ui/grid.rs | 15 ++++++++++++--- 3 files changed, 52 insertions(+), 5 deletions(-) diff --git a/src/draw.rs b/src/draw.rs index c961189..b7439d2 100644 --- a/src/draw.rs +++ b/src/draw.rs @@ -245,7 +245,7 @@ fn draw_content(f: &mut Frame, area: Rect, app: &App) { } f.render_widget( - GridWidget::new(&app.model, &app.mode, &app.search_query), + GridWidget::new(&app.model, &app.mode, &app.search_query, &app.buffers), grid_area, ); } @@ -256,7 +256,10 @@ fn draw_tile_bar(f: &mut Frame, area: Rect, app: &App) { fn draw_bottom_bar(f: &mut Frame, area: Rect, app: &App) { match app.mode { - AppMode::CommandMode { ref buffer } => draw_command_bar(f, area, buffer), + AppMode::CommandMode { .. } => { + let buf = app.buffers.get("command").map(|s| s.as_str()).unwrap_or(""); + draw_command_bar(f, area, buf); + } _ => draw_status(f, area, app), } } diff --git a/src/ui/app.rs b/src/ui/app.rs index 8df93a2..258d9e3 100644 --- a/src/ui/app.rs +++ b/src/ui/app.rs @@ -290,4 +290,39 @@ mod tests { "mode must not be Normal after import wizard is opened" ); } + + #[test] + fn command_mode_typing_appends_to_buffer() { + use crossterm::event::KeyEvent; + let mut app = two_col_model(); + // Enter command mode with ':' + app.handle_key(KeyEvent::new(KeyCode::Char(':'), KeyModifiers::NONE)) + .unwrap(); + assert!(matches!(app.mode, AppMode::CommandMode { .. })); + assert_eq!(app.buffers.get("command").map(|s| s.as_str()), Some("")); + + // Type 'q' + app.handle_key(KeyEvent::new(KeyCode::Char('q'), KeyModifiers::NONE)) + .unwrap(); + assert_eq!(app.buffers.get("command").map(|s| s.as_str()), Some("q")); + } + + #[test] + fn command_mode_buffer_cleared_on_reentry() { + use crossterm::event::KeyEvent; + let mut app = two_col_model(); + // Enter command mode, type something, escape + app.handle_key(KeyEvent::new(KeyCode::Char(':'), KeyModifiers::NONE)) + .unwrap(); + app.handle_key(KeyEvent::new(KeyCode::Char('x'), KeyModifiers::NONE)) + .unwrap(); + assert_eq!(app.buffers.get("command").map(|s| s.as_str()), Some("x")); + app.handle_key(KeyEvent::new(KeyCode::Esc, KeyModifiers::NONE)) + .unwrap(); + + // Re-enter command mode — buffer should be cleared + app.handle_key(KeyEvent::new(KeyCode::Char(':'), KeyModifiers::NONE)) + .unwrap(); + assert_eq!(app.buffers.get("command").map(|s| s.as_str()), Some("")); + } } diff --git a/src/ui/grid.rs b/src/ui/grid.rs index aa8395f..337f11b 100644 --- a/src/ui/grid.rs +++ b/src/ui/grid.rs @@ -20,14 +20,21 @@ pub struct GridWidget<'a> { pub model: &'a Model, pub mode: &'a AppMode, pub search_query: &'a str, + pub buffers: &'a std::collections::HashMap, } impl<'a> GridWidget<'a> { - pub fn new(model: &'a Model, mode: &'a AppMode, search_query: &'a str) -> Self { + pub fn new( + model: &'a Model, + mode: &'a AppMode, + search_query: &'a str, + buffers: &'a std::collections::HashMap, + ) -> Self { Self { model, mode, search_query, + buffers, } } @@ -328,7 +335,8 @@ impl<'a> GridWidget<'a> { // Edit indicator if matches!(self.mode, AppMode::Editing { .. }) && ri == sel_row { - if let AppMode::Editing { buffer } = self.mode { + { + let buffer = self.buffers.get("edit").map(|s| s.as_str()).unwrap_or(""); let edit_x = area.x + ROW_HEADER_WIDTH + (sel_col.saturating_sub(col_offset)) as u16 * COL_WIDTH; @@ -522,7 +530,8 @@ mod tests { fn render(model: &Model, width: u16, height: u16) -> Buffer { let area = Rect::new(0, 0, width, height); let mut buf = Buffer::empty(area); - GridWidget::new(model, &AppMode::Normal, "").render(area, &mut buf); + let bufs = std::collections::HashMap::new(); + GridWidget::new(model, &AppMode::Normal, "", &bufs).render(area, &mut buf); buf }