Files
logViewer/crates/tui/src/main.rs
dailz bab3d9078a feat(tui): replace O(N) scanning with progressive loading and VisualHeightIndex
Replace synchronous file loading with AppLoadingState state machine (Empty/Loading/Ready/Error) for instant interactivity. Add ViewportCache for on-demand viewport computation, replacing global wrap/level caches. Integrate background indexer polling and file watcher events into the TUI event loop. Add loading UI with progress percentage, estimated line numbers with ~ prefix, and error state display. Eliminate all O(N) linear scans using VisualHeightIndex binary search.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-14 09:07:18 +08:00

55 lines
1.5 KiB
Rust

use clap::Parser;
mod app;
mod color;
mod ui;
#[derive(Parser)]
#[command(name = "log-viewer", about = "A log viewer TUI")]
struct Cli {
/// Log files to open
files: Vec<String>,
}
fn main() -> anyhow::Result<()> {
let cli = Cli::parse();
crossterm::terminal::enable_raw_mode()?;
let mut stdout = std::io::stdout();
crossterm::execute!(stdout, crossterm::terminal::EnterAlternateScreen)?;
let backend = ratatui::backend::CrosstermBackend::new(stdout);
let mut terminal = ratatui::Terminal::new(backend)?;
let mut app = app::App::new();
app.color_config = log_viewer_core::config::ColorConfig::load();
if let Some(file) = cli.files.first()
&& let Err(e) = app.load_file(file)
{
eprintln!("Error loading file: {e}");
std::process::exit(1);
}
while !app.should_quit {
app.poll_background_indexer();
app.poll_file_watcher();
terminal.draw(|frame| ui::render(frame, &mut app))?;
if crossterm::event::poll(std::time::Duration::from_millis(100))? {
match crossterm::event::read()? {
crossterm::event::Event::Key(key) => app.handle_key(key),
crossterm::event::Event::Resize(_w, _h) => {}
_ => {}
}
}
}
crossterm::terminal::disable_raw_mode()?;
crossterm::execute!(
terminal.backend_mut(),
crossterm::terminal::LeaveAlternateScreen
)?;
terminal.show_cursor()?;
Ok(())
}