summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRory Dudley2024-02-19 01:40:58 -0700
committerRory Dudley2024-02-19 01:40:58 -0700
commit2e5cc53499947c32b01ea5e1787ed505bc286969 (patch)
treedd50886fb13b8c281f29b580ef5042795fdfa07f
parent670f3864e08003b89a362f381a12d509611db870 (diff)
downloaddwarvish-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.rs53
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)