use anyhow::Result;
mod keymap;
use clap::Parser;
use dotstate::{app::App, cli::Cli};
fn setup_panic_hook() {
let original_hook = std::panic::take_hook();
std::panic::set_hook(Box::new(move |panic_info| {
let _ = crossterm::terminal::disable_raw_mode();
let _ = crossterm::execute!(
std::io::stdout(),
crossterm::terminal::LeaveAlternateScreen,
crossterm::event::DisableMouseCapture
);
original_hook(panic_info);
}));
}
fn main() -> Result<()> {
setup_panic_hook();
let cli = Cli::parse();
if cli.command.is_some() {
let log_dir = dirs::cache_dir()
.unwrap_or_else(|| dirs::home_dir().unwrap_or_default())
.join("dotstate");
std::fs::create_dir_all(&log_dir)?;
let filter = tracing_subscriber::EnvFilter::try_from_default_env()
.unwrap_or_else(|_| tracing_subscriber::EnvFilter::new("info"));
let file_appender = tracing_appender::rolling::never(&log_dir, "dotstate.log");
let (non_blocking, guard) = tracing_appender::non_blocking(file_appender);
tracing_subscriber::fmt()
.with_env_filter(filter)
.with_target(false)
.with_writer(non_blocking)
.with_ansi(false)
.init();
use tracing::info;
info!("Starting dotstate CLI mode");
let result = cli.execute();
drop(guard);
return result;
}
let log_dir = dirs::cache_dir()
.unwrap_or_else(|| dirs::home_dir().unwrap_or_default())
.join("dotstate");
std::fs::create_dir_all(&log_dir)?;
let filter = tracing_subscriber::EnvFilter::try_from_default_env()
.unwrap_or_else(|_| tracing_subscriber::EnvFilter::new("info"));
let file_appender = tracing_appender::rolling::never(&log_dir, "dotstate.log");
let (non_blocking, guard) = tracing_appender::non_blocking(file_appender);
tracing_subscriber::fmt()
.with_env_filter(filter)
.with_target(false)
.with_writer(non_blocking)
.with_ansi(false) .init();
use tracing::info;
info!("Starting dotstate TUI mode");
info!("Log directory: {:?}", log_dir);
let config_path = dotstate::utils::get_config_path();
let config = dotstate::Config::load_or_create(&config_path)?;
let env_no_color = std::env::var_os("NO_COLOR").is_some();
let config_theme_type = config
.theme
.parse::<dotstate::styles::ThemeType>()
.unwrap_or_default();
let no_colors =
cli.no_colors || env_no_color || config_theme_type == dotstate::styles::ThemeType::NoColor;
if no_colors {
std::env::set_var("NO_COLOR", "1");
info!("Colors disabled via NO_COLOR env var, --no-colors flag, or theme=nocolor");
}
let theme_type = if no_colors {
dotstate::styles::ThemeType::NoColor
} else {
config_theme_type
};
dotstate::styles::init_theme(theme_type);
info!("Theme initialized: {:?}", theme_type);
let mut app = App::new()?;
let result = app.run();
info!("Shutting down dotstate");
drop(guard);
result
}