From 058738c48cdbb60a7959140f1496e69638cf9830 Mon Sep 17 00:00:00 2001 From: JT <547158+jntrnr@users.noreply.github.com> Date: Wed, 5 Jan 2022 17:36:42 +1100 Subject: [PATCH] More shell fixes (#673) --- crates/nu-command/src/filesystem/cd.rs | 56 ++++++++++++++++++++++++-- crates/nu-command/src/shells/enter.rs | 16 +++++--- 2 files changed, 63 insertions(+), 9 deletions(-) diff --git a/crates/nu-command/src/filesystem/cd.rs b/crates/nu-command/src/filesystem/cd.rs index c31b600f2..f34967a97 100644 --- a/crates/nu-command/src/filesystem/cd.rs +++ b/crates/nu-command/src/filesystem/cd.rs @@ -1,7 +1,7 @@ -use nu_engine::CallExt; +use nu_engine::{current_dir, CallExt}; use nu_protocol::ast::Call; use nu_protocol::engine::{Command, EngineState, Stack}; -use nu_protocol::{Category, PipelineData, Signature, SyntaxShape, Value}; +use nu_protocol::{Category, PipelineData, ShellError, Signature, SyntaxShape, Value}; #[derive(Clone)] pub struct Cd; @@ -29,18 +29,66 @@ impl Command for Cd { _input: PipelineData, ) -> Result { let path_val: Option = call.opt(engine_state, stack, 0)?; + let cwd = current_dir(engine_state, stack)?; let (path, span) = match path_val { - Some(v) => (v.as_string()?, v.span()?), + Some(v) => { + let path = v.as_path()?; + if !path.exists() { + return Err(ShellError::DirectoryNotFound(v.span()?)); + } + + let path = nu_path::canonicalize_with(path, &cwd)?; + (path.to_string_lossy().to_string(), v.span()?) + } None => { let path = nu_path::expand_tilde("~"); (path.to_string_lossy().to_string(), call.head) } }; + let path_value = Value::String { val: path, span }; + let cwd = Value::String { + val: cwd.to_string_lossy().to_string(), + span: call.head, + }; + + let shells = stack.get_env_var(engine_state, "NUSHELL_SHELLS"); + let mut shells = if let Some(v) = shells { + v.as_list() + .map(|x| x.to_vec()) + .unwrap_or_else(|_| vec![cwd]) + } else { + vec![cwd] + }; + + let current_shell = stack.get_env_var(engine_state, "NUSHELL_CURRENT_SHELL"); + let current_shell = if let Some(v) = current_shell { + v.as_integer().unwrap_or_default() as usize + } else { + 0 + }; + + shells[current_shell] = path_value.clone(); + + stack.add_env_var( + "NUSHELL_SHELLS".into(), + Value::List { + vals: shells, + span: call.head, + }, + ); + stack.add_env_var( + "NUSHELL_CURRENT_SHELL".into(), + Value::Int { + val: current_shell as i64, + span: call.head, + }, + ); + //FIXME: this only changes the current scope, but instead this environment variable //should probably be a block that loads the information from the state in the overlay - stack.add_env_var("PWD".into(), Value::String { val: path, span }); + stack.add_env_var("PWD".into(), path_value); Ok(PipelineData::new(call.head)) } } diff --git a/crates/nu-command/src/shells/enter.rs b/crates/nu-command/src/shells/enter.rs index 4f95da7a0..2840c66e8 100644 --- a/crates/nu-command/src/shells/enter.rs +++ b/crates/nu-command/src/shells/enter.rs @@ -34,14 +34,20 @@ impl Command for Enter { _input: PipelineData, ) -> Result { let new_path: Value = call.req(engine_state, stack, 0)?; + let path_span = new_path.span()?; + + let new_path = new_path.as_path()?; + if !new_path.exists() { + return Err(ShellError::DirectoryNotFound(path_span)); + } let cwd = current_dir(engine_state, stack)?; + let new_path = nu_path::canonicalize_with(new_path, &cwd)?; - if let Ok(s) = new_path.as_path() { - if !s.exists() { - return Err(ShellError::DirectoryNotFound(new_path.span()?)); - } - } + let new_path = Value::String { + val: new_path.to_string_lossy().to_string(), + span: call.head, + }; let cwd = Value::String { val: cwd.to_string_lossy().to_string(),