diff options
author | Rory Dudley | 2024-02-19 01:40:58 -0700 |
---|---|---|
committer | Rory Dudley | 2024-02-19 01:40:58 -0700 |
commit | 2e5cc53499947c32b01ea5e1787ed505bc286969 (patch) | |
tree | dd50886fb13b8c281f29b580ef5042795fdfa07f | |
parent | 670f3864e08003b89a362f381a12d509611db870 (diff) | |
download | dwarvish-2e5cc53499947c32b01ea5e1787ed505bc286969.tar.gz |
Refresh path only if command is not found
This is a modified implementation of the 'refresh path on every
iteration of the loop' idea. It instead, only refreshes the path if the
command is not found. After the first refresh, if the command still is
not found, it throws and error.
Notes
Notes:
This is probably the most sane solution, however, it has an issue. It
can detect new files in the path just fine, but it cannot detect if a
file was removed from the path. It may be prudent to expand the error
handling when we fork, to see what kind of error the process is
returning, and handle it more apropriately.
Another solution may be to check the always check the existence of a
file in the path before returning it from the match closure. This will
overall slow down the REPL, however, since we'd now be making that check
twice.
-rw-r--r-- | src/main.rs | 53 |
1 files changed, 34 insertions, 19 deletions
diff --git a/src/main.rs b/src/main.rs index 272eec1..4d56375 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,21 +4,11 @@ use std::io; use std::io::Write; use std::path::Path; use std::process::Command; -use std::time::SystemTime; fn eval(paths: &[&str], prompt: &str) { let mut bins: Vec<String> = Vec::new(); loop { - let now = SystemTime::now(); - for path in paths { - let files = fs::read_dir(path).expect("Unable to read files in your path"); - for file in files { - bins.push(file.unwrap().path().display().to_string()); - } - } - println!("Refresh: {} ms", now.elapsed().unwrap().as_millis()); - // Output the prompt io::stdout().flush().unwrap(); print!("{}", prompt); @@ -46,7 +36,7 @@ fn eval(paths: &[&str], prompt: &str) { // Parse command and arguments let mut split = input.split(' '); - let mut cmd = match split.next() { + let cmd = match split.next() { Some(str) if str.trim().is_empty() => continue, Some(str) => str.trim(), None => continue, @@ -80,16 +70,41 @@ fn eval(paths: &[&str], prompt: &str) { // Check if the file exists, if given a pull or relative path // TODO: Check if file at the path is executable (i.e. +x) - if !Path::new(cmd).exists() { + let mut cmd = String::from(cmd); + if !Path::new(cmd.as_str()).exists() { + let b = bins.clone(); // Check if the command exists in $PATH if a full or relative path // was not given, or if the path does not exist - cmd = match bins.iter().find(|b| b.split("/").last().unwrap() == cmd) { - Some(cmd) => cmd, - None => { - println!("Command not found"); - continue; - } - }; + // + // If the command is not found the first time, try refreshing the + // path first, and only print an error if if it's not found after + // the path refresh + cmd = String::from( + match b + .clone() + .iter() + .find(|b| b.split("/").last().unwrap() == cmd) + { + Some(cmd) => cmd, + None => { + for path in paths { + let files = + fs::read_dir(path).expect("Unable to read files in your path"); + for file in files { + bins.push(file.unwrap().path().display().to_string()); + } + } + + match bins.iter().find(|b| b.split("/").last().unwrap() == cmd) { + Some(cmd) => cmd, + None => { + println!("dwvsh: error: command not found..."); + continue; + } + } + } + }, + ); } // Run the command (and wait for it to finish) |