diff --git a/src/dirs.rs b/src/dirs.rs index 617b539..e49c4af 100644 --- a/src/dirs.rs +++ b/src/dirs.rs @@ -13,6 +13,7 @@ const APP_ORG: &str = "valeth"; static CONFIG: OnceLock = OnceLock::new(); static DATA: OnceLock = OnceLock::new(); static CACHE: OnceLock = OnceLock::new(); +static SELECTED_PROJECT_FILE: OnceLock = OnceLock::new(); pub fn config_path() -> &'static PathBuf { @@ -27,6 +28,10 @@ pub fn cache_path() -> &'static PathBuf { CACHE.get_or_init(|| init("XDG_CACHE_HOME", ".cache").unwrap()) } +pub fn selected_project_file() -> &'static PathBuf { + SELECTED_PROJECT_FILE.get_or_init(|| cache_path().join("selected-project")) +} + fn init(xdg_var: &str, fallback_home_path: &str) -> Result { let path = xdg_path_with_fallback(xdg_var, fallback_home_path)?; diff --git a/src/integrations/nushell.nu b/src/integrations/nushell.nu new file mode 100644 index 0000000..6d9910e --- /dev/null +++ b/src/integrations/nushell.nu @@ -0,0 +1,11 @@ +def --wrapped --env p [...rest: string] { + let selected_project = "{%SELECTED_PROJECT_FILE%}" | path expand + + run-external {%PROJ_EXE%} ...$rest + + # The file will not exist if the prompt was aborted + if ($selected_project | path exists) { + let dir = open $selected_project + cd $dir + } +} diff --git a/src/main.rs b/src/main.rs index fdcd45b..926e907 100644 --- a/src/main.rs +++ b/src/main.rs @@ -10,6 +10,28 @@ use anyhow::{ensure, Result}; use clap::{Parser, Subcommand}; +#[derive(Debug, Clone, clap::ValueEnum)] +enum ShellType { + Nu, +} + +impl ShellType { + pub fn integration(&self) -> String { + let template = match self { + Self::Nu => include_str!("./integrations/nushell.nu"), + }; + + let file_path = dbg!(dirs::selected_project_file().to_str().unwrap()); + let current_exe = std::env::current_exe().unwrap(); + let current_exe = current_exe.to_str().unwrap(); + + template + .replace("{%SELECTED_PROJECT_FILE%}", file_path) + .replace("{%PROJ_EXE%}", current_exe) + } +} + + #[derive(Debug, Parser)] pub struct Args { #[command(subcommand)] @@ -23,6 +45,9 @@ enum Command { /// List existing projects List, + + /// Initialize shell integration + Init { shell: ShellType }, } @@ -71,12 +96,20 @@ fn handle_subcommands(mut projects: Projects, cmd: &Command) -> Result<()> { Command::List => { list_projects(&projects)?; } + Command::Init { shell } => { + print_shell_integration(shell); + } } Ok(()) } +fn print_shell_integration(shell: &ShellType) { + println!("{}", shell.integration()); +} + + fn add_project

(projects: &mut Projects, path: P) -> Result<()> where P: Into, @@ -105,9 +138,9 @@ fn list_projects(projects: &Projects) -> Result<()> { } fn clear_selected_project_file() -> Result<()> { - let cache_file = dirs::cache_path().join("selected-project"); + let cache_file = dirs::selected_project_file(); - if fs::exists(&cache_file)? { + if fs::exists(cache_file)? { fs::remove_file(cache_file)?; } @@ -115,13 +148,15 @@ fn clear_selected_project_file() -> Result<()> { } fn write_selected_project_file(path: PathBuf) -> Result<()> { - let cache_file = dirs::cache_path().join("selected-project"); + let cache_file = dirs::selected_project_file(); + let mut file = fs::OpenOptions::new() .write(true) .create(true) .truncate(true) .open(cache_file)?; write!(file, "{}", path.display())?; + Ok(()) }