diff --git a/crates/nu-command/src/default_context.rs b/crates/nu-command/src/default_context.rs index da21fcf71a..48db534df3 100644 --- a/crates/nu-command/src/default_context.rs +++ b/crates/nu-command/src/default_context.rs @@ -315,6 +315,8 @@ pub fn create_default_context(cwd: impl AsRef) -> EngineState { LetEnv, LoadEnv, WithEnv, + ConfigNu, + ConfigEnv, }; // Math diff --git a/crates/nu-command/src/env/config/config_env.rs b/crates/nu-command/src/env/config/config_env.rs new file mode 100644 index 0000000000..970562314a --- /dev/null +++ b/crates/nu-command/src/env/config/config_env.rs @@ -0,0 +1,80 @@ +use nu_engine::env_to_strings; +use nu_protocol::{ + ast::Call, + engine::{Command, EngineState, Stack}, + Category, Example, PipelineData, ShellError, Signature, Span, Spanned, +}; + +use crate::ExternalCommand; + +use super::utils::get_editor; + +#[derive(Clone)] +pub struct ConfigEnv; + +impl Command for ConfigEnv { + fn name(&self) -> &str { + "config env" + } + + fn signature(&self) -> Signature { + Signature::build(self.name()).category(Category::Env) + } + + fn usage(&self) -> &str { + "Edit nu environment configurations" + } + + fn examples(&self) -> Vec { + vec![Example { + description: "allow user to open and update nu env", + example: "config env", + result: None, + }] + } + + fn run( + &self, + engine_state: &EngineState, + stack: &mut Stack, + _call: &Call, + input: PipelineData, + ) -> Result { + let env_vars_str = env_to_strings(engine_state, stack)?; + let mut config_path = match nu_path::config_dir() { + Some(path) => path, + None => { + return Err(ShellError::GenericError( + "Could not find nu env path".to_string(), + "Could not find nu env path".to_string(), + None, + None, + Vec::new(), + )); + } + }; + config_path.push("nushell"); + let mut nu_config = config_path.clone(); + nu_config.push("env.nu"); + + let name = Spanned { + item: get_editor(engine_state, stack), + span: Span { start: 0, end: 0 }, + }; + + let args = vec![Spanned { + item: nu_config.to_string_lossy().to_string(), + span: Span { start: 0, end: 0 }, + }]; + + let command = ExternalCommand { + name, + args, + redirect_stdout: false, + redirect_stderr: false, + env_vars: env_vars_str, + }; + + command.run_with_input(engine_state, stack, input) + } +} diff --git a/crates/nu-command/src/env/config/config_nu.rs b/crates/nu-command/src/env/config/config_nu.rs new file mode 100644 index 0000000000..c15a145223 --- /dev/null +++ b/crates/nu-command/src/env/config/config_nu.rs @@ -0,0 +1,80 @@ +use nu_engine::env_to_strings; +use nu_protocol::{ + ast::Call, + engine::{Command, EngineState, Stack}, + Category, Example, PipelineData, ShellError, Signature, Span, Spanned, +}; + +use crate::ExternalCommand; + +use super::utils::get_editor; + +#[derive(Clone)] +pub struct ConfigNu; + +impl Command for ConfigNu { + fn name(&self) -> &str { + "config nu" + } + + fn signature(&self) -> Signature { + Signature::build(self.name()).category(Category::Env) + } + + fn usage(&self) -> &str { + "Edit nu configurations" + } + + fn examples(&self) -> Vec { + vec![Example { + description: "allow user to open and update nu config", + example: "config nu", + result: None, + }] + } + + fn run( + &self, + engine_state: &EngineState, + stack: &mut Stack, + _call: &Call, + input: PipelineData, + ) -> Result { + let env_vars_str = env_to_strings(engine_state, stack)?; + let mut config_path = match nu_path::config_dir() { + Some(path) => path, + None => { + return Err(ShellError::GenericError( + "Could not find nu config path".to_string(), + "Could not find nu config path".to_string(), + None, + None, + Vec::new(), + )); + } + }; + config_path.push("nushell"); + let mut nu_config = config_path.clone(); + nu_config.push("config.nu"); + + let name = Spanned { + item: get_editor(engine_state, stack), + span: Span { start: 0, end: 0 }, + }; + + let args = vec![Spanned { + item: nu_config.to_string_lossy().to_string(), + span: Span { start: 0, end: 0 }, + }]; + + let command = ExternalCommand { + name, + args, + redirect_stdout: false, + redirect_stderr: false, + env_vars: env_vars_str, + }; + + command.run_with_input(engine_state, stack, input) + } +} diff --git a/crates/nu-command/src/env/config/mod.rs b/crates/nu-command/src/env/config/mod.rs new file mode 100644 index 0000000000..05d5c4c789 --- /dev/null +++ b/crates/nu-command/src/env/config/mod.rs @@ -0,0 +1,5 @@ +mod config_env; +mod config_nu; +mod utils; +pub use config_env::ConfigEnv; +pub use config_nu::ConfigNu; diff --git a/crates/nu-command/src/env/config/utils.rs b/crates/nu-command/src/env/config/utils.rs new file mode 100644 index 0000000000..91df864a61 --- /dev/null +++ b/crates/nu-command/src/env/config/utils.rs @@ -0,0 +1,17 @@ +use nu_protocol::engine::{EngineState, Stack}; + +pub(crate) fn get_editor(engine_state: &EngineState, stack: &mut Stack) -> String { + let config = engine_state.get_config(); + let env_vars = stack.get_env_vars(engine_state); + if !config.buffer_editor.is_empty() { + config.buffer_editor.clone() + } else if let Some(value) = env_vars.get("EDITOR") { + value.as_string().expect("Unknown type") + } else if let Some(value) = env_vars.get("VISUAL") { + value.as_string().expect("Unknown type") + } else if cfg!(target_os = "windows") { + "notepad".to_string() + } else { + "nano".to_string() + } +} diff --git a/crates/nu-command/src/env/mod.rs b/crates/nu-command/src/env/mod.rs index 3b40657fb4..b05581e7a0 100644 --- a/crates/nu-command/src/env/mod.rs +++ b/crates/nu-command/src/env/mod.rs @@ -1,8 +1,11 @@ +mod config; mod env_command; mod let_env; mod load_env; mod with_env; +pub use config::ConfigEnv; +pub use config::ConfigNu; pub use env_command::Env; pub use let_env::LetEnv; pub use load_env::LoadEnv;