From 5d3ca8997365c1c0366cac8c69afa072b1b0cabb Mon Sep 17 00:00:00 2001
From: Michael Aaron Murphy <mmstickman@gmail.com>
Date: Sat, 17 Jun 2017 19:53:56 -0400
Subject: [PATCH] Implement Implicit cd

---
 README.md        | 2 ++
 src/shell/job.rs | 7 +++----
 src/shell/mod.rs | 8 +++++++-
 3 files changed, 12 insertions(+), 5 deletions(-)

diff --git a/README.md b/README.md
index 0fd2a73a..bef4c03b 100644
--- a/README.md
+++ b/README.md
@@ -17,6 +17,7 @@ Ion is a shell for UNIX platforms, and is the default shell in Redox. It is stil
 - [x] While Loops
 - [x] If Conditionals
 - [x] Functions
+- [x] Optionally-Typed Function Parameters
 - [x] Executing Scripts with an @args Array
 - [x] Aliases
 - [x] Variables (**$variable**)
@@ -36,6 +37,7 @@ Ion is a shell for UNIX platforms, and is the default shell in Redox. It is stil
 - [x] Multiline Comments and Commands
 - [x] Tab Completion (Needs Improvements)
 - [x] vi and emacs keybindings (`set -o (vi|emacs)`)
+- [x] Implicit cd
 
 ## Unimplemented Features
 
diff --git a/src/shell/job.rs b/src/shell/job.rs
index c8dbc116..53d2bbcf 100644
--- a/src/shell/job.rs
+++ b/src/shell/job.rs
@@ -34,15 +34,14 @@ impl Job {
         let mut expanded = SmallVec::new();
         expanded.grow(self.args.len());
         {
-            let mut iterator = self.args.drain();
-            expanded.push(iterator.next().unwrap());
-            for arg in iterator.flat_map(|argument| expand_string(&argument, expanders, false)) {
-                
+            for arg in self.args.drain().flat_map(|argument| expand_string(&argument, expanders, false)) {
+
                 expanded.push(arg);
             }
         }
 
         self.args = expanded;
+        self.command = self.args[0].clone().into();
     }
 
     pub fn build_command(&mut self) -> Command {
diff --git a/src/shell/mod.rs b/src/shell/mod.rs
index f5816e18..0f6b1be2 100644
--- a/src/shell/mod.rs
+++ b/src/shell/mod.rs
@@ -19,6 +19,7 @@ use std::fs::File;
 use std::io::{self, ErrorKind, Read, Write};
 use std::env;
 use std::mem;
+use std::path::Path;
 use std::process;
 use std::time::SystemTime;
 use std::iter::FromIterator;
@@ -436,7 +437,12 @@ impl<'a> Shell<'a> {
                 let _ = writeln!(stderr, "ion: function pipelining is not implemented yet");
                 Some(FAILURE)
             }
-        // If not a shell command or a shell function execute the pipeline and set the exit_status
+        } else if Path::new(&pipeline.jobs[0].command).is_dir() {
+            // This branch implements implicit cd support.
+            let mut new_args: SmallVec<[&str; 4]> = SmallVec::new();
+            new_args.push("cd");
+            new_args.extend(pipeline.jobs[0].args.iter().map(|x| x as &str));
+            Some((*builtins.get("cd").unwrap().main)(&new_args, self))
         } else {
             Some(execute_pipeline(pipeline))
         };
-- 
GitLab