refactor(cli): migrate all command modules from console::style to Theme
Replace all console::style() calls in command modules with the centralized Theme API and render:: utility functions. This ensures consistent color behavior across the entire CLI, proper NO_COLOR/--color never support via the LoreRenderer singleton, and eliminates duplicated formatting code. Changes per module: - count.rs: Theme for table headers, render::format_number replacing local duplicate. Removed local format_number implementation. - doctor.rs: Theme::success/warning/error for check status symbols and messages. Unicode escapes for check/warning/cross symbols. - drift.rs: Theme::bold/error/success for drift detection headers and status messages. - embed.rs: Compact output format — headline with count, zero-suppressed detail lines, 'nothing to embed' short-circuit for no-op runs. - generate_docs.rs: Same compact pattern — headline + detail + hint for next step. No-op short-circuit when regenerated==0. - ingest.rs: Theme for project summaries, sync status, dry-run preview. All console::style -> Theme replacements. - list.rs: Replace comfy-table with render::LoreTable for issue/MR listing. Remove local colored_cell, colored_cell_hex, format_relative_time, truncate_with_ellipsis, and format_labels (all moved to render.rs). - list_tests.rs: Update test assertions to use render:: functions. - search.rs: Add render_snippet() for FTS5 <mark> tag highlighting via Theme::bold().underline(). Compact result layout with type badges. - show.rs: Theme for entity detail views, delegate format_date and wrap_text to render module. - stats.rs: Section-based layout using render::section_divider. Compact middle-dot format for document counts. Color-coded embedding coverage percentage (green >=95%, yellow >=50%, red <50%). - sync.rs: Compact sync summary — headline with counts and elapsed time, zero-suppressed detail lines, visually prominent error-only section. - sync_status.rs: Theme for run history headers, removed local format_number duplicate. - timeline.rs: Theme for headers/footers, render:: for date/truncate, standard format! padding replacing console::pad_str. - who.rs: Theme for all expert/workload/active/overlap/review output modes, render:: for relative time and truncation. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
use console::style;
|
||||
use crate::cli::render::{self, Theme};
|
||||
use rusqlite::Connection;
|
||||
use serde::Serialize;
|
||||
|
||||
@@ -166,27 +166,6 @@ fn format_duration(ms: i64) -> String {
|
||||
}
|
||||
}
|
||||
|
||||
fn format_number(n: i64) -> String {
|
||||
let is_negative = n < 0;
|
||||
let abs_n = n.unsigned_abs();
|
||||
let s = abs_n.to_string();
|
||||
let chars: Vec<char> = s.chars().collect();
|
||||
let mut result = String::new();
|
||||
|
||||
if is_negative {
|
||||
result.push('-');
|
||||
}
|
||||
|
||||
for (i, c) in chars.iter().enumerate() {
|
||||
if i > 0 && (chars.len() - i).is_multiple_of(3) {
|
||||
result.push(',');
|
||||
}
|
||||
result.push(*c);
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
struct SyncStatusJsonOutput {
|
||||
ok: bool,
|
||||
@@ -293,14 +272,14 @@ pub fn print_sync_status_json(result: &SyncStatusResult, elapsed_ms: u64) {
|
||||
}
|
||||
|
||||
pub fn print_sync_status(result: &SyncStatusResult) {
|
||||
println!("{}", style("Recent Sync Runs").bold().underlined());
|
||||
println!("{}", Theme::bold().underline().render("Recent Sync Runs"));
|
||||
println!();
|
||||
|
||||
if result.runs.is_empty() {
|
||||
println!(" {}", style("No sync runs recorded yet.").dim());
|
||||
println!(" {}", Theme::dim().render("No sync runs recorded yet."));
|
||||
println!(
|
||||
" {}",
|
||||
style("Run 'lore sync' or 'lore ingest' to start.").dim()
|
||||
Theme::dim().render("Run 'lore sync' or 'lore ingest' to start.")
|
||||
);
|
||||
} else {
|
||||
for run in &result.runs {
|
||||
@@ -310,16 +289,16 @@ pub fn print_sync_status(result: &SyncStatusResult) {
|
||||
|
||||
println!();
|
||||
|
||||
println!("{}", style("Cursor Positions").bold().underlined());
|
||||
println!("{}", Theme::bold().underline().render("Cursor Positions"));
|
||||
println!();
|
||||
|
||||
if result.cursors.is_empty() {
|
||||
println!(" {}", style("No cursors recorded yet.").dim());
|
||||
println!(" {}", Theme::dim().render("No cursors recorded yet."));
|
||||
} else {
|
||||
for cursor in &result.cursors {
|
||||
println!(
|
||||
" {} ({}):",
|
||||
style(&cursor.project_path).cyan(),
|
||||
Theme::info().render(&cursor.project_path),
|
||||
cursor.resource_type
|
||||
);
|
||||
|
||||
@@ -328,7 +307,10 @@ pub fn print_sync_status(result: &SyncStatusResult) {
|
||||
println!(" Last updated_at: {}", ms_to_iso(ts));
|
||||
}
|
||||
_ => {
|
||||
println!(" Last updated_at: {}", style("Not started").dim());
|
||||
println!(
|
||||
" Last updated_at: {}",
|
||||
Theme::dim().render("Not started")
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -340,40 +322,39 @@ pub fn print_sync_status(result: &SyncStatusResult) {
|
||||
|
||||
println!();
|
||||
|
||||
println!("{}", style("Data Summary").bold().underlined());
|
||||
println!("{}", Theme::bold().underline().render("Data Summary"));
|
||||
println!();
|
||||
|
||||
println!(
|
||||
" Issues: {}",
|
||||
style(format_number(result.summary.issue_count)).bold()
|
||||
Theme::bold().render(&render::format_number(result.summary.issue_count))
|
||||
);
|
||||
println!(
|
||||
" MRs: {}",
|
||||
style(format_number(result.summary.mr_count)).bold()
|
||||
Theme::bold().render(&render::format_number(result.summary.mr_count))
|
||||
);
|
||||
println!(
|
||||
" Discussions: {}",
|
||||
style(format_number(result.summary.discussion_count)).bold()
|
||||
Theme::bold().render(&render::format_number(result.summary.discussion_count))
|
||||
);
|
||||
|
||||
let user_notes = result.summary.note_count - result.summary.system_note_count;
|
||||
println!(
|
||||
" Notes: {} {}",
|
||||
style(format_number(user_notes)).bold(),
|
||||
style(format!(
|
||||
Theme::bold().render(&render::format_number(user_notes)),
|
||||
Theme::dim().render(&format!(
|
||||
"(excluding {} system)",
|
||||
format_number(result.summary.system_note_count)
|
||||
render::format_number(result.summary.system_note_count)
|
||||
))
|
||||
.dim()
|
||||
);
|
||||
}
|
||||
|
||||
fn print_run_line(run: &SyncRunInfo) {
|
||||
let status_styled = match run.status.as_str() {
|
||||
"succeeded" => style(&run.status).green(),
|
||||
"failed" => style(&run.status).red(),
|
||||
"running" => style(&run.status).yellow(),
|
||||
_ => style(&run.status).dim(),
|
||||
"succeeded" => Theme::success().render(&run.status),
|
||||
"failed" => Theme::error().render(&run.status),
|
||||
"running" => Theme::warning().render(&run.status),
|
||||
_ => Theme::dim().render(&run.status),
|
||||
};
|
||||
|
||||
let run_label = run
|
||||
@@ -386,9 +367,9 @@ fn print_run_line(run: &SyncRunInfo) {
|
||||
let time = format_full_datetime(run.started_at);
|
||||
|
||||
let mut parts = vec![
|
||||
format!("{}", style(run_label).bold()),
|
||||
format!("{status_styled}"),
|
||||
format!("{}", style(&run.command).dim()),
|
||||
Theme::bold().render(&run_label),
|
||||
status_styled,
|
||||
Theme::dim().render(&run.command),
|
||||
time,
|
||||
];
|
||||
|
||||
@@ -403,16 +384,13 @@ fn print_run_line(run: &SyncRunInfo) {
|
||||
}
|
||||
|
||||
if run.total_errors > 0 {
|
||||
parts.push(format!(
|
||||
"{}",
|
||||
style(format!("{} errors", run.total_errors)).red()
|
||||
));
|
||||
parts.push(Theme::error().render(&format!("{} errors", run.total_errors)));
|
||||
}
|
||||
|
||||
println!(" {}", parts.join(" | "));
|
||||
|
||||
if let Some(error) = &run.error {
|
||||
println!(" {}", style(error).red());
|
||||
println!(" {}", Theme::error().render(error));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -448,7 +426,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn format_number_adds_thousands_separators() {
|
||||
assert_eq!(format_number(1000), "1,000");
|
||||
assert_eq!(format_number(1234567), "1,234,567");
|
||||
assert_eq!(render::format_number(1000), "1,000");
|
||||
assert_eq!(render::format_number(1234567), "1,234,567");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user