feat(ui): simplify AppMode minibuffer handling and panel rendering

Refactor AppMode to use MinibufferConfig for all text-entry modes. Update
command implementations to use new mode constructors. Introduce
PanelContent trait and replace panel structs with content types. Adjust
rendering to use Panel::new and minibuffer configuration. Update imports
and add MinibufferConfig struct. No functional changes; all behavior
preserved.

Co-Authored-By: fiddlerwoaroof/git-smart-commit (bartowski/nvidia_Nemotron-Cascade-2-30B-A3B-GGUF)
This commit is contained in:
Edward Langley
2026-04-07 02:04:46 -07:00
parent de047ddf1a
commit 4b11b6e321
9 changed files with 376 additions and 320 deletions

View File

@ -7,6 +7,8 @@ use std::time::{Duration, Instant};
use std::rc::Rc;
use ratatui::style::Color;
use crate::command::cmd::CmdContext;
use crate::command::keymap::{Keymap, KeymapSet};
use crate::import::wizard::ImportWizard;
@ -29,40 +31,126 @@ pub struct DrillState {
pub pending_edits: std::collections::HashMap<(usize, String), String>,
}
/// Display configuration for the bottom-bar minibuffer.
/// Carried structurally by text-entry `AppMode` variants.
#[derive(Debug, Clone, PartialEq)]
pub struct MinibufferConfig {
pub buffer_key: &'static str,
pub prompt: String,
pub color: Color,
}
#[derive(Debug, Clone, PartialEq)]
pub enum AppMode {
Normal,
Editing {
buffer: String,
minibuf: MinibufferConfig,
},
FormulaEdit {
buffer: String,
minibuf: MinibufferConfig,
},
FormulaPanel,
CategoryPanel,
/// Quick-add a new category: Enter adds and stays open, Esc closes.
CategoryAdd {
buffer: String,
minibuf: MinibufferConfig,
},
/// Quick-add items to `category`: Enter adds and stays open, Esc closes.
ItemAdd {
category: String,
buffer: String,
minibuf: MinibufferConfig,
},
ViewPanel,
TileSelect,
ImportWizard,
ExportPrompt {
buffer: String,
minibuf: MinibufferConfig,
},
/// Vim-style `:` command line
CommandMode {
buffer: String,
minibuf: MinibufferConfig,
},
Help,
Quit,
}
impl AppMode {
/// Extract the minibuffer config from text-entry modes, if present.
pub fn minibuffer(&self) -> Option<&MinibufferConfig> {
match self {
Self::Editing { minibuf, .. }
| Self::FormulaEdit { minibuf, .. }
| Self::CommandMode { minibuf, .. }
| Self::CategoryAdd { minibuf, .. }
| Self::ItemAdd { minibuf, .. }
| Self::ExportPrompt { minibuf, .. } => Some(minibuf),
_ => None,
}
}
pub fn editing() -> Self {
Self::Editing {
minibuf: MinibufferConfig {
buffer_key: "edit",
prompt: "edit: ".into(),
color: Color::Green,
},
}
}
pub fn formula_edit() -> Self {
Self::FormulaEdit {
minibuf: MinibufferConfig {
buffer_key: "formula",
prompt: "formula: ".into(),
color: Color::Cyan,
},
}
}
pub fn command_mode() -> Self {
Self::CommandMode {
minibuf: MinibufferConfig {
buffer_key: "command",
prompt: ":".into(),
color: Color::Yellow,
},
}
}
pub fn category_add() -> Self {
Self::CategoryAdd {
minibuf: MinibufferConfig {
buffer_key: "category",
prompt: "new category: ".into(),
color: Color::Yellow,
},
}
}
pub fn item_add(category: String) -> Self {
let prompt = format!("add item to {category}: ");
Self::ItemAdd {
category,
minibuf: MinibufferConfig {
buffer_key: "item",
prompt,
color: Color::Green,
},
}
}
pub fn export_prompt() -> Self {
Self::ExportPrompt {
minibuf: MinibufferConfig {
buffer_key: "export",
prompt: "export path: ".into(),
color: Color::Yellow,
},
}
}
}
pub struct App {
pub model: Model,
pub file_path: Option<PathBuf>,