14 Commits

Author SHA1 Message Date
9fc3f0b5d6 refactor: synthesize previous refactors 2026-04-01 01:01:19 -07:00
3f84ba03cb Revert "refactor: mystery model 3"
This reverts commit 4b721f7543.
2026-04-01 00:46:55 -07:00
4b721f7543 refactor: mystery model 3 2026-04-01 00:46:25 -07:00
6d88de3020 Revert "refactor: mystery model #2"
This reverts commit 87fd6a1620.
2026-04-01 00:41:25 -07:00
87fd6a1620 refactor: mystery model #2 2026-04-01 00:40:22 -07:00
a57d3ed294 Revert "refactor: mystery model #1"
This reverts commit bbebc3344c.
2026-04-01 00:32:12 -07:00
bbebc3344c refactor: mystery model #1 2026-04-01 00:32:07 -07:00
ff08e3c2c2 chore: Revert refactors to give claude a clean slate 2026-04-01 00:26:55 -07:00
8c84256ebc refactor: merge using claude sonnet 2026-04-01 00:25:19 -07:00
d915908354 refactor: unsloth/Qwen3-Coder-Next-GGUF:Q5_K_M refactors the drawing helper 2026-04-01 00:20:19 -07:00
7731c7ceab Revert "refactor: unsloth/Qwen3.5-35B-A3B-GGUF:Q5_K_M"
This reverts commit 98d151f345.
2026-03-31 23:11:21 -07:00
98d151f345 refactor: unsloth/Qwen3.5-35B-A3B-GGUF:Q5_K_M 2026-03-31 23:10:52 -07:00
f1e6e61bca Revert "test: use gpt-oss-20b to do some minor refactoring"
This reverts commit bbd1f48b78.
2026-03-31 22:50:10 -07:00
bbd1f48b78 test: use gpt-oss-20b to do some minor refactoring 2026-03-31 22:50:07 -07:00

View File

@ -277,11 +277,61 @@ fn run_tui(
// ── Drawing ────────────────────────────────────────────────────────────────── // ── Drawing ──────────────────────────────────────────────────────────────────
fn fill_line(left: String, right: &str, width: u16) -> String {
let pad = " ".repeat((width as usize).saturating_sub(left.len() + right.len()));
format!("{left}{pad}{right}")
}
fn centered_popup(area: Rect, width: u16, height: u16) -> Rect {
let w = width.min(area.width);
let h = height.min(area.height);
let x = area.x + area.width.saturating_sub(w) / 2;
let y = area.y + area.height.saturating_sub(h) / 2;
Rect::new(x, y, w, h)
}
fn draw_popup_frame(f: &mut Frame, popup: Rect, title: &str, border_color: Color) -> Rect {
f.render_widget(Clear, popup);
let block = Block::default()
.borders(Borders::ALL)
.border_style(Style::default().fg(border_color))
.title(title);
let inner = block.inner(popup);
f.render_widget(block, popup);
inner
}
fn mode_name(mode: &AppMode) -> &'static str {
match mode {
AppMode::Normal => "NORMAL",
AppMode::Editing { .. } => "INSERT",
AppMode::FormulaEdit { .. } => "FORMULA",
AppMode::FormulaPanel => "FORMULAS",
AppMode::CategoryPanel => "CATEGORIES",
AppMode::CategoryAdd { .. } => "NEW CATEGORY",
AppMode::ItemAdd { .. } => "ADD ITEMS",
AppMode::ViewPanel => "VIEWS",
AppMode::TileSelect { .. } => "TILES",
AppMode::ImportWizard => "IMPORT",
AppMode::ExportPrompt { .. } => "EXPORT",
AppMode::CommandMode { .. } => "COMMAND",
AppMode::Help => "HELP",
AppMode::Quit => "QUIT",
}
}
fn mode_style(mode: &AppMode) -> Style {
match mode {
AppMode::Editing { .. } => Style::default().fg(Color::Black).bg(Color::Green),
AppMode::CommandMode { .. } => Style::default().fg(Color::Black).bg(Color::Yellow),
AppMode::TileSelect { .. } => Style::default().fg(Color::Black).bg(Color::Magenta),
_ => Style::default().fg(Color::Black).bg(Color::DarkGray),
}
}
fn draw(f: &mut Frame, app: &App) { fn draw(f: &mut Frame, app: &App) {
let size = f.area(); let size = f.area();
let is_cmd_mode = matches!(app.mode, AppMode::CommandMode { .. });
let main_chunks = Layout::default() let main_chunks = Layout::default()
.direction(Direction::Vertical) .direction(Direction::Vertical)
.constraints([ .constraints([
@ -295,12 +345,7 @@ fn draw(f: &mut Frame, app: &App) {
draw_title(f, main_chunks[0], app); draw_title(f, main_chunks[0], app);
draw_content(f, main_chunks[1], app); draw_content(f, main_chunks[1], app);
draw_tile_bar(f, main_chunks[2], app); draw_tile_bar(f, main_chunks[2], app);
draw_bottom_bar(f, main_chunks[3], app);
if is_cmd_mode {
draw_command_bar(f, main_chunks[3], app);
} else {
draw_status(f, main_chunks[3], app);
}
// Overlays (rendered last so they appear on top) // Overlays (rendered last so they appear on top)
if matches!(app.mode, AppMode::Help) { if matches!(app.mode, AppMode::Help) {
@ -315,7 +360,7 @@ fn draw(f: &mut Frame, app: &App) {
draw_export_prompt(f, size, app); draw_export_prompt(f, size, app);
} }
if app.is_empty_model() && matches!(app.mode, AppMode::Normal | AppMode::CommandMode { .. }) { if app.is_empty_model() && matches!(app.mode, AppMode::Normal | AppMode::CommandMode { .. }) {
draw_welcome(f, main_chunks[1], app); draw_welcome(f, main_chunks[1]);
} }
} }
@ -330,8 +375,7 @@ fn draw_title(f: &mut Frame, area: Rect, app: &App) {
.unwrap_or_default(); .unwrap_or_default();
let title = format!(" improvise · {}{}{} ", app.model.name, file, dirty); let title = format!(" improvise · {}{}{} ", app.model.name, file, dirty);
let right = " ?:help :q quit "; let right = " ?:help :q quit ";
let pad = " ".repeat((area.width as usize).saturating_sub(title.len() + right.len())); let line = fill_line(title, right, area.width);
let line = format!("{title}{pad}{right}");
f.render_widget( f.render_widget(
Paragraph::new(line).style( Paragraph::new(line).style(
Style::default() Style::default()
@ -346,6 +390,7 @@ fn draw_title(f: &mut Frame, area: Rect, app: &App) {
fn draw_content(f: &mut Frame, area: Rect, app: &App) { fn draw_content(f: &mut Frame, area: Rect, app: &App) {
let side_open = app.formula_panel_open || app.category_panel_open || app.view_panel_open; let side_open = app.formula_panel_open || app.category_panel_open || app.view_panel_open;
let grid_area;
if side_open { if side_open {
let side_w = 32u16; let side_w = 32u16;
let chunks = Layout::default() let chunks = Layout::default()
@ -353,10 +398,7 @@ fn draw_content(f: &mut Frame, area: Rect, app: &App) {
.constraints([Constraint::Min(40), Constraint::Length(side_w)]) .constraints([Constraint::Min(40), Constraint::Length(side_w)])
.split(area); .split(area);
f.render_widget( grid_area = chunks[0];
GridWidget::new(&app.model, &app.mode, &app.search_query),
chunks[0],
);
let side = chunks[1]; let side = chunks[1];
let panel_count = [ let panel_count = [
@ -394,35 +436,27 @@ fn draw_content(f: &mut Frame, area: Rect, app: &App) {
); );
} }
} else { } else {
f.render_widget( grid_area = area;
GridWidget::new(&app.model, &app.mode, &app.search_query),
area,
);
} }
f.render_widget(
GridWidget::new(&app.model, &app.mode, &app.search_query),
grid_area,
);
} }
fn draw_tile_bar(f: &mut Frame, area: Rect, app: &App) { fn draw_tile_bar(f: &mut Frame, area: Rect, app: &App) {
f.render_widget(TileBar::new(&app.model, &app.mode), area); f.render_widget(TileBar::new(&app.model, &app.mode), area);
} }
fn draw_status(f: &mut Frame, area: Rect, app: &App) { fn draw_bottom_bar(f: &mut Frame, area: Rect, app: &App) {
let mode_badge = match &app.mode { match app.mode {
AppMode::Normal => "NORMAL", AppMode::CommandMode { ref buffer } => draw_command_bar(f, area, buffer),
AppMode::Editing { .. } => "INSERT", _ => draw_status(f, area, app),
AppMode::FormulaEdit { .. } => "FORMULA", }
AppMode::FormulaPanel => "FORMULAS", }
AppMode::CategoryPanel => "CATEGORIES",
AppMode::CategoryAdd { .. } => "NEW CATEGORY",
AppMode::ItemAdd { .. } => "ADD ITEMS",
AppMode::ViewPanel => "VIEWS",
AppMode::TileSelect { .. } => "TILES",
AppMode::ImportWizard => "IMPORT",
AppMode::ExportPrompt { .. } => "EXPORT",
AppMode::CommandMode { .. } => "COMMAND",
AppMode::Help => "HELP",
AppMode::Quit => "QUIT",
};
fn draw_status(f: &mut Frame, area: Rect, app: &App) {
let search_part = if app.search_mode { let search_part = if app.search_mode {
format!(" /{}", app.search_query) format!(" /{}", app.search_query)
} else { } else {
@ -438,30 +472,16 @@ fn draw_status(f: &mut Frame, area: Rect, app: &App) {
let yank_indicator = if app.yanked.is_some() { " [yank]" } else { "" }; let yank_indicator = if app.yanked.is_some() { " [yank]" } else { "" };
let view_badge = format!(" {}{} ", app.model.active_view, yank_indicator); let view_badge = format!(" {}{} ", app.model.active_view, yank_indicator);
let left = format!(" {mode_badge}{search_part} {msg}"); let left = format!(" {}{search_part} {msg}", mode_name(&app.mode));
let right = view_badge; let line = fill_line(left, &view_badge, area.width);
let pad = " ".repeat((area.width as usize).saturating_sub(left.len() + right.len()));
let line = format!("{left}{pad}{right}");
let badge_style = match &app.mode { f.render_widget(Paragraph::new(line).style(mode_style(&app.mode)), area);
AppMode::Editing { .. } => Style::default().fg(Color::Black).bg(Color::Green),
AppMode::CommandMode { .. } => Style::default().fg(Color::Black).bg(Color::Yellow),
AppMode::TileSelect { .. } => Style::default().fg(Color::Black).bg(Color::Magenta),
_ => Style::default().fg(Color::Black).bg(Color::DarkGray),
};
f.render_widget(Paragraph::new(line).style(badge_style), area);
} }
fn draw_command_bar(f: &mut Frame, area: Rect, app: &App) { fn draw_command_bar(f: &mut Frame, area: Rect, buffer: &str) {
let buf = if let AppMode::CommandMode { buffer } = &app.mode {
buffer.as_str()
} else {
""
};
let line = format!(":{buf}");
f.render_widget( f.render_widget(
Paragraph::new(line).style(Style::default().fg(Color::White).bg(Color::Black)), Paragraph::new(format!(":{buffer}"))
.style(Style::default().fg(Color::White).bg(Color::Black)),
area, area,
); );
} }
@ -472,39 +492,17 @@ fn draw_export_prompt(f: &mut Frame, area: Rect, app: &App) {
} else { } else {
"" ""
}; };
let popup_w = 64u16.min(area.width); let popup = centered_popup(area, 64, 3);
let x = area.x + area.width.saturating_sub(popup_w) / 2; let inner = draw_popup_frame(f, popup, " Export CSV — path (Esc cancel) ", Color::Yellow);
let y = area.y + area.height / 2;
let popup_area = Rect::new(x, y, popup_w, 3);
f.render_widget(Clear, popup_area);
let block = Block::default()
.borders(Borders::ALL)
.border_style(Style::default().fg(Color::Yellow))
.title(" Export CSV — path (Esc cancel) ");
let inner = block.inner(popup_area);
f.render_widget(block, popup_area);
f.render_widget( f.render_widget(
Paragraph::new(format!("{buf}")).style(Style::default().fg(Color::Green)), Paragraph::new(format!("{buf}")).style(Style::default().fg(Color::Green)),
inner, inner,
); );
} }
fn draw_welcome(f: &mut Frame, area: Rect, _app: &App) { fn draw_welcome(f: &mut Frame, area: Rect) {
let w = 58u16.min(area.width.saturating_sub(4)); let popup = centered_popup(area, 58, 20);
let h = 20u16.min(area.height.saturating_sub(2)); let inner = draw_popup_frame(f, popup, " Welcome to improvise ", Color::Blue);
let x = area.x + area.width.saturating_sub(w) / 2;
let y = area.y + area.height.saturating_sub(h) / 2;
let popup = Rect::new(x, y, w, h);
f.render_widget(Clear, popup);
let block = Block::default()
.borders(Borders::ALL)
.border_style(Style::default().fg(Color::Blue))
.title(" Welcome to improvise ");
let inner = block.inner(popup);
f.render_widget(block, popup);
let lines: &[(&str, Style)] = &[ let lines: &[(&str, Style)] = &[
( (