diff --git a/crates/nu-cli/src/cli.rs b/crates/nu-cli/src/cli.rs index 0a07c33e42..9391cfd026 100644 --- a/crates/nu-cli/src/cli.rs +++ b/crates/nu-cli/src/cli.rs @@ -641,8 +641,43 @@ async fn process_line( && which::which(name).is_err() && args.list.is_empty() { - ctx.shell_manager.set_path(name.to_string()); - return LineResult::Success(line.to_string()); + // Here we work differently if we're in Windows because of the expected Windows behavior + #[cfg(windows)] + { + if name.ends_with(':') { + // This looks like a drive shortcut. We need to a) switch drives and b) go back to the previous directory we were viewing on that drive + // But first, we need to save where we are now + let current_path = ctx.shell_manager.path(); + + let split_path: Vec<_> = current_path.split(':').collect(); + if split_path.len() > 1 { + ctx.windows_drives_previous_cwd + .lock() + .insert(split_path[0].to_string(), current_path); + } + + let name = name.to_uppercase(); + let new_drive: Vec<_> = name.split(':').collect(); + + if let Some(val) = + ctx.windows_drives_previous_cwd.lock().get(new_drive[0]) + { + ctx.shell_manager.set_path(val.to_string()); + return LineResult::Success(line.to_string()); + } else { + ctx.shell_manager.set_path(name.to_string()); + return LineResult::Success(line.to_string()); + } + } else { + ctx.shell_manager.set_path(name.to_string()); + return LineResult::Success(line.to_string()); + } + } + #[cfg(not(windows))] + { + ctx.shell_manager.set_path(name.to_string()); + return LineResult::Success(line.to_string()); + } } } } diff --git a/crates/nu-cli/src/context.rs b/crates/nu-cli/src/context.rs index b2ff0c7188..5d9909611d 100644 --- a/crates/nu-cli/src/context.rs +++ b/crates/nu-cli/src/context.rs @@ -82,6 +82,9 @@ pub struct Context { pub current_errors: Arc>>, pub ctrl_c: Arc, pub(crate) shell_manager: ShellManager, + + #[cfg(windows)] + pub windows_drives_previous_cwd: Arc>>, } impl Context { @@ -102,15 +105,33 @@ impl Context { pub(crate) fn basic() -> Result> { let registry = CommandRegistry::new(); - Ok(Context { - registry: registry.clone(), - host: Arc::new(parking_lot::Mutex::new(Box::new( - crate::env::host::BasicHost, - ))), - current_errors: Arc::new(Mutex::new(vec![])), - ctrl_c: Arc::new(AtomicBool::new(false)), - shell_manager: ShellManager::basic(registry)?, - }) + + #[cfg(windows)] + { + Ok(Context { + registry: registry.clone(), + host: Arc::new(parking_lot::Mutex::new(Box::new( + crate::env::host::BasicHost, + ))), + current_errors: Arc::new(Mutex::new(vec![])), + ctrl_c: Arc::new(AtomicBool::new(false)), + shell_manager: ShellManager::basic(registry)?, + windows_drives_previous_cwd: Arc::new(Mutex::new(std::collections::HashMap::new())), + }) + } + + #[cfg(not(windows))] + { + Ok(Context { + registry: registry.clone(), + host: Arc::new(parking_lot::Mutex::new(Box::new( + crate::env::host::BasicHost, + ))), + current_errors: Arc::new(Mutex::new(vec![])), + ctrl_c: Arc::new(AtomicBool::new(false)), + shell_manager: ShellManager::basic(registry)?, + }) + } } pub(crate) fn error(&mut self, error: ShellError) {