aboutsummaryrefslogtreecommitdiff
path: root/src/main.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.rs')
-rw-r--r--src/main.rs111
1 files changed, 33 insertions, 78 deletions
diff --git a/src/main.rs b/src/main.rs
index 01e5fbd..e5e7a53 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,19 +1,11 @@
-use std::process::{Command, Stdio};
+use rustyline::error::ReadlineError;
+use rustyline::Editor;
mod builtins;
+mod parser;
mod prompt;
-fn sigint_handler(dummy: i32) {
- println!("sigint_handler: {}", dummy);
-}
-
fn main() {
-
- unsafe {
- // capture Ctrl+C (SIGINT)
- libc::signal(libc::SIGINT, sigint_handler as libc::sighandler_t);
- }
-
match std::fs::read_to_string("/etc/motd") {
Ok(motd) => print!("{}", motd),
Err(_) => {}
@@ -22,77 +14,40 @@ fn main() {
let prompt = prompt::Prompt::new().unwrap();
let mut cwd = std::env::current_dir().unwrap();
+ // `()` can be used when no completer is required
+ let mut rl = Editor::<()>::new();
+ /*if rl.load_history("history.txt").is_err() {
+ println!("No previous history.");
+ }*/
loop {
- prompt.print(&cwd);
-
- let mut input = String::new();
- match std::io::stdin().read_line(&mut input) {
- Ok(0) => return, // EOF
- Ok(_) => {} // okay
- Err(e) => {
- eprintln!("error reading line: {}", e);
- return;
- }
- };
-
- let mut commands = input.trim().split(" | ").peekable();
- let mut previous_command: std::option::Option<std::process::Child> = None;
-
- while let Some(command) = commands.next() {
- let mut parts = command.trim().split_whitespace();
- let command = match parts.next() {
- Some(cmd) => cmd,
- None => break,
- };
-
- let args = parts;
-
- match command {
- "cd" => {
- cwd = builtins::cd(args);
- previous_command = None;
- }
- "exit" => return,
-
- command => {
- let stdin = match previous_command {
- None => Stdio::inherit(),
- Some(cmd) => Stdio::from(cmd.stdout.unwrap()),
- };
- let stdout = match commands.peek().is_some() {
- true => Stdio::piped(),
- false => Stdio::inherit(),
- };
-
- let child = Command::new(command)
- .args(args)
- .stdin(stdin)
- .stdout(stdout)
- .spawn();
- match child {
- Ok(c) => previous_command = Some(c),
- Err(e) => {
- previous_command = None;
- eprintln!("{}", e);
- }
+ let readline = rl.readline(&prompt.print(&cwd));
+ match readline {
+ Ok(line) => {
+ rl.add_history_entry(line.as_str());
+ let commands = parser::parse(&line);
+ match commands[0] {
+ "cd" => {
+ cwd = builtins::cd(commands[1]);
+ }
+ _ => {
+ builtins::run(commands[0], &commands[1..]);
}
}
+ //println!("Line: {}", line);
}
- }
-
- if let Some(mut final_command) = previous_command {
- match final_command.wait() {
- Ok(ret) => match ret.code() {
- Some(code) => {
- if cfg!(debug_assertions) {
- println!("exit code [{}]", code);
- }
- }
- None => println!("Process termed by signal"),
- },
- Err(e) => eprintln!("error waiting on final command: {}", e),
+ Err(ReadlineError::Interrupted) => {
+ println!("CTRL-C");
+ continue;
+ }
+ Err(ReadlineError::Eof) => {
+ println!("CTRL-D");
+ break;
+ }
+ Err(err) => {
+ println!("Error: {:?}", err);
+ break;
}
}
- } // loop
-
+ }
+ //rl.save_history("history.txt").unwrap();
}