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)
This commit is contained in:
@ -245,7 +245,7 @@ fn draw_content(f: &mut Frame, area: Rect, app: &App) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
f.render_widget(
|
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,
|
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) {
|
fn draw_bottom_bar(f: &mut Frame, area: Rect, app: &App) {
|
||||||
match app.mode {
|
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),
|
_ => draw_status(f, area, app),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -290,4 +290,39 @@ mod tests {
|
|||||||
"mode must not be Normal after import wizard is opened"
|
"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(""));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -20,14 +20,21 @@ pub struct GridWidget<'a> {
|
|||||||
pub model: &'a Model,
|
pub model: &'a Model,
|
||||||
pub mode: &'a AppMode,
|
pub mode: &'a AppMode,
|
||||||
pub search_query: &'a str,
|
pub search_query: &'a str,
|
||||||
|
pub buffers: &'a std::collections::HashMap<String, String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> GridWidget<'a> {
|
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<String, String>,
|
||||||
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
model,
|
model,
|
||||||
mode,
|
mode,
|
||||||
search_query,
|
search_query,
|
||||||
|
buffers,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -328,7 +335,8 @@ impl<'a> GridWidget<'a> {
|
|||||||
|
|
||||||
// Edit indicator
|
// Edit indicator
|
||||||
if matches!(self.mode, AppMode::Editing { .. }) && ri == sel_row {
|
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
|
let edit_x = area.x
|
||||||
+ ROW_HEADER_WIDTH
|
+ ROW_HEADER_WIDTH
|
||||||
+ (sel_col.saturating_sub(col_offset)) as u16 * COL_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 {
|
fn render(model: &Model, width: u16, height: u16) -> Buffer {
|
||||||
let area = Rect::new(0, 0, width, height);
|
let area = Rect::new(0, 0, width, height);
|
||||||
let mut buf = Buffer::empty(area);
|
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
|
buf
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user