diff --git a/src/command.rs b/src/command.rs index 777537b029..29accfd519 100644 --- a/src/command.rs +++ b/src/command.rs @@ -1,6 +1,7 @@ use nu_cli::report_error; use nu_engine::{get_full_help, CallExt}; use nu_parser::parse; +use nu_parser::{escape_for_script_arg, escape_quote_string}; use nu_protocol::{ ast::{Call, Expr, Expression, PipelineElement}, engine::{Command, EngineState, Stack, StateWorkingSet}, @@ -9,6 +10,51 @@ use nu_protocol::{ }; use nu_utils::stdout_write_all_and_flush; +pub(crate) fn gather_commandline_args() -> (Vec, String, Vec) { + // Would be nice if we had a way to parse this. The first flags we see will be going to nushell + // then it'll be the script name + // then the args to the script + let mut args_to_nushell = Vec::from(["nu".into()]); + let mut script_name = String::new(); + let mut args = std::env::args(); + + // Mimic the behaviour of bash/zsh + if let Some(argv0) = args.next() { + if argv0.starts_with('-') { + args_to_nushell.push("--login".into()); + } + } + + while let Some(arg) = args.next() { + if !arg.starts_with('-') { + script_name = arg; + break; + } + + let flag_value = match arg.as_ref() { + "--commands" | "-c" | "--table-mode" | "-m" | "-e" | "--execute" | "--config" + | "--env-config" => args.next().map(|a| escape_quote_string(&a)), + #[cfg(feature = "plugin")] + "--plugin-config" => args.next().map(|a| escape_quote_string(&a)), + "--log-level" | "--log-target" | "--testbin" | "--threads" | "-t" => args.next(), + _ => None, + }; + + args_to_nushell.push(arg); + + if let Some(flag_value) = flag_value { + args_to_nushell.push(flag_value); + } + } + + let args_to_script = if !script_name.is_empty() { + args.map(|arg| escape_for_script_arg(&arg)).collect() + } else { + Vec::default() + }; + (args_to_nushell, script_name, args_to_script) +} + pub(crate) fn parse_commandline_args( commandline_args: &str, engine_state: &mut EngineState, diff --git a/src/main.rs b/src/main.rs index afe8f9b642..6fcb947c16 100644 --- a/src/main.rs +++ b/src/main.rs @@ -15,6 +15,7 @@ use crate::{ logger::{configure, logger}, terminal::acquire_terminal, }; +use command::gather_commandline_args; use log::Level; use miette::Result; #[cfg(feature = "plugin")] @@ -24,7 +25,6 @@ use nu_cli::{ report_error_new, }; use nu_command::create_default_context; -use nu_parser::{escape_for_script_arg, escape_quote_string}; use nu_protocol::{util::BufferedReader, PipelineData, RawStream}; use nu_utils::utils::perf; use signals::{ctrlc_protection, sigquit_protection}; @@ -64,54 +64,8 @@ fn main() -> Result<()> { ctrlc_protection(&mut engine_state, &ctrlc); sigquit_protection(&mut engine_state); - let mut args_to_nushell = vec![]; - let mut script_name = String::new(); - let mut args_to_script = vec![]; - - // Would be nice if we had a way to parse this. The first flags we see will be going to nushell - // then it'll be the script name - // then the args to the script - let mut args = std::env::args(); - let argv0 = args.next(); - - while let Some(arg) = args.next() { - if !script_name.is_empty() { - args_to_script.push(escape_for_script_arg(&arg)); - } else if arg.starts_with('-') { - // Cool, it's a flag - let flag_value = match arg.as_ref() { - "--commands" | "-c" | "--table-mode" | "-m" | "-e" | "--execute" => { - args.next().map(|a| escape_quote_string(&a)) - } - "--config" | "--env-config" => args.next().map(|a| escape_quote_string(&a)), - #[cfg(feature = "plugin")] - "--plugin-config" => args.next().map(|a| escape_quote_string(&a)), - "--log-level" | "--log-target" | "--testbin" | "--threads" | "-t" => args.next(), - _ => None, - }; - - args_to_nushell.push(arg); - - if let Some(flag_value) = flag_value { - args_to_nushell.push(flag_value); - } - } else { - // Our script file - script_name = arg; - } - } - - args_to_nushell.insert(0, "nu".into()); - - if let Some(argv0) = argv0 { - if argv0.starts_with('-') { - args_to_nushell.push("--login".into()); - } - } - - let nushell_commandline_args = args_to_nushell.join(" "); - - let parsed_nu_cli_args = parse_commandline_args(&nushell_commandline_args, &mut engine_state) + let (args_to_nushell, script_name, args_to_script) = gather_commandline_args(); + let parsed_nu_cli_args = parse_commandline_args(&args_to_nushell.join(" "), &mut engine_state) .unwrap_or_else(|_| std::process::exit(1)); if let Some(level) = parsed_nu_cli_args.log_level.map(|level| level.item) {