use std::{env, io, path::PathBuf};
use clap::{Parser, Subcommand};
use crossterm::{
cursor, execute,
terminal::{self, EnterAlternateScreen, LeaveAlternateScreen},
};
use tiny_dc::{
app::{App, ListMode},
index::{DirectoryIndex, DEFAULT_INDEX_FILE_NAME},
};
#[derive(Parser, Debug)]
#[command(version, about, long_about = None)]
#[command(propagate_version = true)]
struct Cli {
#[arg(short, long, global = true, value_name = "FILE_PATH")]
index_file: Option<PathBuf>,
#[command(subcommand)]
directory_command: Option<DirectoryCommand>,
}
#[derive(Subcommand, Debug)]
enum DirectoryCommand {
Push { path: PathBuf },
Z { queries: Vec<String> },
}
fn main() -> anyhow::Result<()> {
let cli = Cli::parse();
let index_file_path = match cli.index_file {
Some(path) => path,
None => {
let home_dir = env::var("HOME")?;
let index_file_path = format!("{home_dir}/{DEFAULT_INDEX_FILE_NAME}");
PathBuf::from(index_file_path)
}
};
let mut directory_index = DirectoryIndex::try_from(index_file_path)?;
if let Some(directory_command) = cli.directory_command {
match directory_command {
DirectoryCommand::Push { path } => {
directory_index.push(path)?;
}
DirectoryCommand::Z { queries } => {
if let Some(path) = directory_index.z(queries)? {
println!("{}", path.display());
} else {
let current_dir = env::current_dir()?;
println!("{}", current_dir.display());
}
}
}
} else {
execute!(io::stderr(), EnterAlternateScreen)?;
execute!(io::stderr(), cursor::Hide)?;
terminal::enable_raw_mode()?;
let result = run_app_ui(directory_index);
terminal::disable_raw_mode()?;
execute!(io::stderr(), cursor::Show)?;
execute!(io::stderr(), LeaveAlternateScreen)?;
match result {
Ok(path) => {
println!("{}", path.display());
}
Err(err) => {
eprintln!("Error: {}", err);
}
}
}
Ok(())
}
fn run_app_ui(directory_index: DirectoryIndex) -> anyhow::Result<PathBuf> {
let mut app = App::try_new(ListMode::default(), directory_index)?;
let backend = ratatui::backend::CrosstermBackend::new(io::stderr());
let mut terminal = ratatui::Terminal::new(backend)?;
app.run(&mut terminal)
}