summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRory Dudley2024-02-19 00:57:51 -0700
committerRory Dudley2024-02-19 00:57:51 -0700
commitb1a7db048e517ff262dc1dad0f0ea766af4bd021 (patch)
treebc7ebd313be07d9f5454fa4381f177984699cbe6
parent6cf0f1b12e880f3cd88f013a070406bfb303831a (diff)
downloaddwarvish-b1a7db048e517ff262dc1dad0f0ea766af4bd021.tar.gz
Support for inotifyinotify
This is a branch with some cursory support for using inotify to watch for changes in the user's $PATH.
-rw-r--r--Cargo.lock278
-rw-r--r--Cargo.toml2
-rw-r--r--src/main.rs105
3 files changed, 352 insertions, 33 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 1098731..c49c555 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -4,6 +4,12 @@ version = 3
[[package]]
name = "bitflags"
+version = "1.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
+
+[[package]]
+name = "bitflags"
version = "2.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf"
@@ -15,13 +21,28 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
+name = "crossbeam-channel"
+version = "0.5.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "176dc175b78f56c0f321911d9c8eb2b77a78a4860b9c19db83835fea1a46649b"
+dependencies = [
+ "crossbeam-utils",
+]
+
+[[package]]
+name = "crossbeam-utils"
+version = "0.8.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345"
+
+[[package]]
name = "ctrlc"
version = "3.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b467862cc8610ca6fc9a1532d7777cee0804e678ab45410897b9396495994a0b"
dependencies = [
"nix",
- "windows-sys",
+ "windows-sys 0.52.0",
]
[[package]]
@@ -29,6 +50,69 @@ name = "dwarvish"
version = "0.0.0"
dependencies = [
"ctrlc",
+ "notify",
+ "signals2",
+]
+
+[[package]]
+name = "filetime"
+version = "0.2.23"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1ee447700ac8aa0b2f2bd7bc4462ad686ba06baa6727ac149a2d6277f0d240fd"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "redox_syscall",
+ "windows-sys 0.52.0",
+]
+
+[[package]]
+name = "fsevent-sys"
+version = "4.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "76ee7a02da4d231650c7cea31349b889be2f45ddb3ef3032d2ec8185f6313fd2"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "inotify"
+version = "0.9.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f8069d3ec154eb856955c1c0fbffefbf5f3c40a104ec912d4797314c1801abff"
+dependencies = [
+ "bitflags 1.3.2",
+ "inotify-sys",
+ "libc",
+]
+
+[[package]]
+name = "inotify-sys"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e05c02b5e89bff3b946cedeca278abc628fe811e604f027c45a8aa3cf793d0eb"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "kqueue"
+version = "1.0.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7447f1ca1b7b563588a205fe93dea8df60fd981423a768bc1c0ded35ed147d0c"
+dependencies = [
+ "kqueue-sys",
+ "libc",
+]
+
+[[package]]
+name = "kqueue-sys"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ed9625ffda8729b85e45cf04090035ac368927b8cebc34898e7c120f52e4838b"
+dependencies = [
+ "bitflags 1.3.2",
+ "libc",
]
[[package]]
@@ -38,23 +122,155 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
[[package]]
+name = "log"
+version = "0.4.20"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
+
+[[package]]
+name = "mio"
+version = "0.8.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09"
+dependencies = [
+ "libc",
+ "log",
+ "wasi",
+ "windows-sys 0.48.0",
+]
+
+[[package]]
name = "nix"
version = "0.27.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053"
dependencies = [
- "bitflags",
+ "bitflags 2.4.2",
"cfg-if",
"libc",
]
[[package]]
+name = "notify"
+version = "6.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6205bd8bb1e454ad2e27422015fb5e4f2bcc7e08fa8f27058670d208324a4d2d"
+dependencies = [
+ "bitflags 2.4.2",
+ "crossbeam-channel",
+ "filetime",
+ "fsevent-sys",
+ "inotify",
+ "kqueue",
+ "libc",
+ "log",
+ "mio",
+ "walkdir",
+ "windows-sys 0.48.0",
+]
+
+[[package]]
+name = "redox_syscall"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa"
+dependencies = [
+ "bitflags 1.3.2",
+]
+
+[[package]]
+name = "same-file"
+version = "1.0.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
+dependencies = [
+ "winapi-util",
+]
+
+[[package]]
+name = "signals2"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dc108c224058c29e227807435200520695bbf24eb2522ceef234e2c4e1247c3c"
+
+[[package]]
+name = "walkdir"
+version = "2.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee"
+dependencies = [
+ "same-file",
+ "winapi-util",
+]
+
+[[package]]
+name = "wasi"
+version = "0.11.0+wasi-snapshot-preview1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
+
+[[package]]
+name = "winapi"
+version = "0.3.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
+dependencies = [
+ "winapi-i686-pc-windows-gnu",
+ "winapi-x86_64-pc-windows-gnu",
+]
+
+[[package]]
+name = "winapi-i686-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
+
+[[package]]
+name = "winapi-util"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596"
+dependencies = [
+ "winapi",
+]
+
+[[package]]
+name = "winapi-x86_64-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
+
+[[package]]
+name = "windows-sys"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
+dependencies = [
+ "windows-targets 0.48.5",
+]
+
+[[package]]
name = "windows-sys"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
dependencies = [
- "windows-targets",
+ "windows-targets 0.52.0",
+]
+
+[[package]]
+name = "windows-targets"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
+dependencies = [
+ "windows_aarch64_gnullvm 0.48.5",
+ "windows_aarch64_msvc 0.48.5",
+ "windows_i686_gnu 0.48.5",
+ "windows_i686_msvc 0.48.5",
+ "windows_x86_64_gnu 0.48.5",
+ "windows_x86_64_gnullvm 0.48.5",
+ "windows_x86_64_msvc 0.48.5",
]
[[package]]
@@ -63,53 +279,95 @@ version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd"
dependencies = [
- "windows_aarch64_gnullvm",
- "windows_aarch64_msvc",
- "windows_i686_gnu",
- "windows_i686_msvc",
- "windows_x86_64_gnu",
- "windows_x86_64_gnullvm",
- "windows_x86_64_msvc",
+ "windows_aarch64_gnullvm 0.52.0",
+ "windows_aarch64_msvc 0.52.0",
+ "windows_i686_gnu 0.52.0",
+ "windows_i686_msvc 0.52.0",
+ "windows_x86_64_gnu 0.52.0",
+ "windows_x86_64_gnullvm 0.52.0",
+ "windows_x86_64_msvc 0.52.0",
]
[[package]]
name = "windows_aarch64_gnullvm"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
+
+[[package]]
+name = "windows_aarch64_gnullvm"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea"
[[package]]
name = "windows_aarch64_msvc"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
+
+[[package]]
+name = "windows_aarch64_msvc"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef"
[[package]]
name = "windows_i686_gnu"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
+
+[[package]]
+name = "windows_i686_gnu"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313"
[[package]]
name = "windows_i686_msvc"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
+
+[[package]]
+name = "windows_i686_msvc"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a"
[[package]]
name = "windows_x86_64_gnu"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
+
+[[package]]
+name = "windows_x86_64_gnu"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd"
[[package]]
name = "windows_x86_64_gnullvm"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
+
+[[package]]
+name = "windows_x86_64_gnullvm"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e"
[[package]]
name = "windows_x86_64_msvc"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
+
+[[package]]
+name = "windows_x86_64_msvc"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04"
diff --git a/Cargo.toml b/Cargo.toml
index 00fdb24..54b8246 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -13,3 +13,5 @@ path = "src/main.rs"
[dependencies]
ctrlc = "3.4.2"
+notify = "6.1.1"
+signals2 = "0.3.3"
diff --git a/src/main.rs b/src/main.rs
index 7fc8991..c11b939 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,20 +1,71 @@
use ctrlc;
+use notify::RecursiveMode;
+use notify::Watcher;
+use signals2::*;
use std::fs;
use std::io;
use std::io::Write;
use std::path::Path;
use std::process::Command;
-
-fn eval(paths: &[&str], prompt: &str) {
- let mut bins: Vec<String> = Vec::new();
-
- for path in paths {
- let files = fs::read_dir(path).expect("Unable to read files in your path");
+use std::sync::Arc;
+use std::sync::RwLock;
+
+fn prefresh(paths: &Vec<String>, bins: &mut Arc<RwLock<Vec<Vec<String>>>>, index: Option<i32>) {
+ let mut bins = bins.write().unwrap();
+ let index = index.unwrap_or(-1);
+
+ if index == -1 {
+ for (i, path) in paths.iter().enumerate() {
+ let files = fs::read_dir(path).expect("Unable to read files in your path");
+ bins.push(Vec::new());
+ for file in files {
+ bins[i].push(file.unwrap().path().display().to_string());
+ }
+ }
+ } else {
+ let index = index as usize;
+ let files = fs::read_dir(paths[index].as_str()).expect("Unable to read files in your path");
+ bins[index].clear();
for file in files {
- bins.push(file.unwrap().path().display().to_string());
+ bins[index].push(file.unwrap().path().display().to_string());
}
}
+}
+
+fn eval(paths: Vec<String>, prompt: &str) {
+ // Setup search for our paths
+ let mut bins = Arc::new(RwLock::new(Vec::new()));
+ prefresh(&paths, &mut bins, None);
+
+ // Handle file changes on paths
+ let sig: Signal<(i32,)> = Signal::new();
+ let arcbins = Arc::clone(&bins);
+ let p = paths.clone();
+ sig.connect(move |i| {
+ let mut arcbins = arcbins.clone();
+ prefresh(&paths, &mut arcbins, Some(i));
+ });
+
+ let mut watcher =
+ notify::recommended_watcher(move |res: Result<notify::event::Event, notify::Error>| {
+ match res {
+ Ok(event) => {
+ if event.kind.is_create() || event.kind.is_remove() {
+ sig.emit(0);
+ }
+ }
+ Err(_) => {}
+ }
+ })
+ .unwrap();
+
+ for path in p {
+ watcher
+ .watch(Path::new(path.as_str()), RecursiveMode::Recursive)
+ .unwrap();
+ }
+ // Main REPL
loop {
// Output the prompt
io::stdout().flush().unwrap();
@@ -43,7 +94,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,
@@ -77,13 +128,21 @@ 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() {
- // 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,
+ let mut cmd = String::from(cmd);
+ if !Path::new(cmd.as_str()).exists() {
+ cmd = match bins
+ .read()
+ .unwrap()
+ .iter()
+ .flatten()
+ .map(|s| String::from(s))
+ .collect::<Vec<String>>()
+ .iter()
+ .find(|b| b.split("/").last().unwrap() == cmd)
+ {
+ Some(cmd) => String::from(cmd),
None => {
- println!("Command not found");
+ println!("dwvsh: error: command not found...");
continue;
}
};
@@ -104,19 +163,19 @@ fn eval(paths: &[&str], prompt: &str) {
fn main() {
// Define paths
// TODO: Hardcoded path should only be the fallback
- let paths = [
- "/bin",
- "/sbin",
- "/usr/bin",
- "/usr/sbin",
- "/usr/local/bin",
- "/usr/local/sbin",
+ let paths = vec![
+ "/bin".to_string(),
+ "/sbin".to_string(),
+ "/usr/bin".to_string(),
+ "/usr/sbin".to_string(),
+ "/usr/local/bin".to_string(),
+ "/usr/local/sbin".to_string(),
];
// Set the prompt
let prompt = "|> ";
- // Handle signals
+ // Handle SIGINT
ctrlc::set_handler(move || {
print!("\n{}", prompt);
io::stdout().flush().unwrap();
@@ -124,5 +183,5 @@ fn main() {
.expect("Unable to set <C-c> handler");
// Begin evaluating commands
- eval(&paths, prompt);
+ eval(paths, prompt);
}