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>
55 lines
1.5 KiB
Rust
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(())
|
|
}
|