pub mod app;
mod event;
mod opener;
mod preview;
mod search;
mod theme;
mod ui;
pub use app::{App, AppResult};
pub use theme::Theme;
#[derive(Debug, Clone, Default)]
#[non_exhaustive]
pub struct TuiConfig {
pub scan_on_startup: Option<bool>,
pub cwd_file: Option<std::path::PathBuf>,
pub print_cwd: bool,
}
impl TuiConfig {
pub fn new() -> Self {
Self::default()
}
pub fn with_scan_on_startup(mut self, scan: bool) -> Self {
self.scan_on_startup = Some(scan);
self
}
pub fn with_cwd_file(mut self, path: Option<std::path::PathBuf>) -> Self {
self.cwd_file = path;
self
}
pub fn with_print_cwd(mut self, print: bool) -> Self {
self.print_cwd = print;
self
}
}
#[derive(Debug, Clone)]
pub struct ExitData {
pub last_cwd: std::path::PathBuf,
}
pub fn run(path: std::path::PathBuf) -> AppResult<()> {
run_with_config(path, TuiConfig::default())
}
pub fn run_with_config(path: std::path::PathBuf, config: TuiConfig) -> AppResult<()> {
use crossterm::event::{DisableMouseCapture, EnableMouseCapture};
use crossterm::execute;
let original_hook = std::panic::take_hook();
std::panic::set_hook(Box::new(move |panic_info| {
let _ = execute!(std::io::stdout(), DisableMouseCapture);
ratatui::restore();
original_hook(panic_info);
}));
let rt = tokio::runtime::Runtime::new()?;
let cwd_file = config.cwd_file.clone();
let print_cwd = config.print_cwd;
let terminal = ratatui::init();
let _ = execute!(std::io::stdout(), EnableMouseCapture);
let app = App::with_config(path, config);
let result = rt.block_on(async { app.run_and_return_exit_data(terminal).await });
let _ = execute!(std::io::stdout(), DisableMouseCapture);
ratatui::restore();
rt.shutdown_timeout(std::time::Duration::from_millis(100));
if let Ok(exit_data) = &result {
if let Some(cwd_path) = cwd_file {
let _ = std::fs::write(&cwd_path, exit_data.last_cwd.to_string_lossy().as_bytes());
}
if print_cwd {
println!("{}", exit_data.last_cwd.display());
}
}
result.map(|_| ())
}