use std::{env, ffi::OsStr, fs::read_dir}; use clap::Parser; use clap_complete::{engine::ArgValueCompleter, CompletionCandidate}; /// This is a Nix flake update manager. #[derive(Parser, Debug)] #[command(author, version, about)] pub struct CliArgs { /// The command to execute. #[arg(add = ArgValueCompleter::new(get_fupdate_commands))] pub command: Vec, } fn get_fupdate_commands(current: &OsStr) -> Vec { let mut output = vec![]; let path = env::var("PATH").unwrap_or_default(); let Some(current) = current.to_str() else { return output; }; for directory in path.split(':') { if let Ok(mut read) = read_dir(directory) { for value in read.by_ref().flatten() { let file_name = value.file_name(); let name = file_name.to_string_lossy(); let Some(stripped) = name.strip_prefix("fupdate-") else { continue; }; if stripped.starts_with(current) { output.push(CompletionCandidate::new( value .file_name() .to_string_lossy() .strip_prefix("fupdate-") .expect("Exists"), )); } } } } output }