Windows needs to remember auto-cd paths when changing drives (#1500)

* Windows needs to remember auto-cd paths when changing drives

* Windows needs to remember auto-cd paths when changing drives
This commit is contained in:
Jonathan Turner 2020-03-18 15:10:45 +13:00 committed by GitHub
parent 1c4cb30d64
commit 390deb4ff7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 67 additions and 11 deletions

View file

@ -641,9 +641,44 @@ async fn process_line(
&& which::which(name).is_err()
&& args.list.is_empty()
{
// 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());
}
}
}
}
let input_stream = if redirect_stdin {

View file

@ -82,6 +82,9 @@ pub struct Context {
pub current_errors: Arc<Mutex<Vec<ShellError>>>,
pub ctrl_c: Arc<AtomicBool>,
pub(crate) shell_manager: ShellManager,
#[cfg(windows)]
pub windows_drives_previous_cwd: Arc<Mutex<std::collections::HashMap<String, String>>>,
}
impl Context {
@ -102,6 +105,23 @@ impl Context {
pub(crate) fn basic() -> Result<Context, Box<dyn Error>> {
let registry = CommandRegistry::new();
#[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(
@ -112,6 +132,7 @@ impl Context {
shell_manager: ShellManager::basic(registry)?,
})
}
}
pub(crate) fn error(&mut self, error: ShellError) {
self.with_errors(|errors| errors.push(error))