mod app;
mod banner;
mod effects;
mod hints;
pub mod icons;
mod palette;
mod popup;
mod running;
pub mod settings;
pub mod theme;
mod wizard;
use crate::TuiArgs;
use anyhow::Result;
use app::App;
use crossterm::event::{self, Event, KeyEventKind};
use helix_toolbox_catalog::Catalog;
use helix_toolbox_platform::LinuxInfo;
use std::time::Duration;
pub fn run(catalog: Catalog, platform: LinuxInfo, args: TuiArgs) -> Result<()> {
let path = settings::path();
let look = path.as_deref().map(settings::load).unwrap_or_default();
let app = App::new(catalog, platform, &args)
.remembering(look, path, &args)
.with_status_checks();
let mut terminal = ratatui::init();
let banner = banner::detect().and_then(|picker| banner::encode(&picker));
let mut app = app.with_banner(banner);
if app.first_run() {
app.open_wizard(true);
}
let result = event_loop(&mut terminal, &mut app);
ratatui::restore();
result
}
fn event_loop(terminal: &mut ratatui::DefaultTerminal, app: &mut App) -> Result<()> {
terminal.draw(|frame| app.draw(frame))?;
loop {
if !event::poll(Duration::from_millis(10))? {
if app.needs_redraw() {
terminal.draw(|frame| app.draw(frame))?;
}
continue;
}
match event::read()? {
Event::Key(key)
if key.kind == KeyEventKind::Press || key.kind == KeyEventKind::Repeat =>
{
if !app.handle_key(&key) {
return Ok(());
}
if let Some(request) = app.take_edit() {
ratatui::restore();
let closed = std::process::Command::new("sh")
.arg("-c")
.arg(format!("{} \"$1\"", request.editor))
.arg("sh")
.arg(&request.copy)
.status()
.map_err(|error| format!("{} cannot start: {error}", request.editor))
.and_then(|status| {
if status.success() {
Ok(())
} else {
Err(format!("{} exited with {status}", request.editor))
}
});
*terminal = ratatui::init();
terminal.clear()?;
app.edited(request, closed);
}
}
Event::Resize(..) => {}
_ => continue,
}
terminal.draw(|frame| app.draw(frame))?;
}
}