use anyhow::Result; use helix_core::Position; use helix_view::args::parse_file; use std::path::PathBuf; #[derive(Default)] pub struct Args { pub display_help: bool, pub display_version: bool, pub health: bool, pub health_arg: Option, pub load_tutor: bool, pub fetch_grammars: bool, pub build_grammars: bool, pub verbosity: u64, pub files: Vec<(PathBuf, Position)>, } impl Args { pub fn parse_args() -> Result { let mut args = Args::default(); let mut argv = std::env::args().peekable(); argv.next(); // skip the program, we don't care about that while let Some(arg) = argv.next() { match arg.as_str() { "--" => break, // stop parsing at this point treat the remaining as files "--version" => args.display_version = true, "--help" => args.display_help = true, "--tutor" => args.load_tutor = true, "--health" => { args.health = true; args.health_arg = argv.next_if(|opt| !opt.starts_with('-')); } "-g" | "--grammar" => match argv.next().as_deref() { Some("fetch") => args.fetch_grammars = true, Some("build") => args.build_grammars = true, _ => { anyhow::bail!("--grammar must be followed by either 'fetch' or 'build'") } }, arg if arg.starts_with("--") => { anyhow::bail!("unexpected double dash argument: {}", arg) } arg if arg.starts_with('-') => { let arg = arg.get(1..).unwrap().chars(); for chr in arg { match chr { 'v' => args.verbosity += 1, 'V' => args.display_version = true, 'h' => args.display_help = true, _ => anyhow::bail!("unexpected short arg {}", chr), } } } arg => args.files.push(parse_file(arg)), } } // push the remaining args, if any to the files for arg in argv { args.files.push(parse_file(&arg)); } Ok(args) } }