Add pwd watcher

Also optimize the main thread.
pull/36/head
Arijit Basu 3 years ago committed by Arijit Basu
parent 0a3cf7b5c1
commit 6d0ea06d7b

247
Cargo.lock generated

@ -28,7 +28,7 @@ checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
dependencies = [
"hermit-abi",
"libc",
"winapi",
"winapi 0.3.9",
]
[[package]]
@ -126,6 +126,12 @@ dependencies = [
"rustc_version",
]
[[package]]
name = "cfg-if"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
[[package]]
name = "cfg-if"
version = "1.0.0"
@ -143,7 +149,7 @@ dependencies = [
"num-traits",
"serde",
"time",
"winapi",
"winapi 0.3.9",
]
[[package]]
@ -205,7 +211,7 @@ version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dca26ee1f8d361640700bde38b2c37d8c22b3ce2d360e1fc1c74ea4b0aa7d775"
dependencies = [
"cfg-if",
"cfg-if 1.0.0",
"crossbeam-utils",
]
@ -215,7 +221,7 @@ version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94af6efb46fef72616855b036a624cf27ba656ffc9be1b9a3c931cfc7749a9a9"
dependencies = [
"cfg-if",
"cfg-if 1.0.0",
"crossbeam-epoch",
"crossbeam-utils",
]
@ -226,7 +232,7 @@ version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2584f639eb95fea8c798496315b297cf81b9b58b6d30ab066a75455333cf4b12"
dependencies = [
"cfg-if",
"cfg-if 1.0.0",
"crossbeam-utils",
"lazy_static",
"memoffset",
@ -240,7 +246,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e7e9d99fa91428effe99c5c6d4634cdeba32b8cf784fc428a2a687f61a952c49"
dependencies = [
"autocfg",
"cfg-if",
"cfg-if 1.0.0",
"lazy_static",
]
@ -254,10 +260,10 @@ dependencies = [
"crossterm_winapi",
"lazy_static",
"libc",
"mio",
"mio 0.7.11",
"parking_lot",
"signal-hook",
"winapi",
"winapi 0.3.9",
]
[[package]]
@ -266,7 +272,7 @@ version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2265c3f8e080075d9b6417aa72293fc71662f34b4af2612d8d1b074d29510db"
dependencies = [
"winapi",
"winapi 0.3.9",
]
[[package]]
@ -317,7 +323,7 @@ checksum = "8e93d7f5705de3e49895a2b5e0b8855a1c27f080192ae9c32a6432d50741a57a"
dependencies = [
"libc",
"redox_users",
"winapi",
"winapi 0.3.9",
]
[[package]]
@ -338,6 +344,53 @@ version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
[[package]]
name = "filetime"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d34cfa13a63ae058bfa601fe9e313bbdb3746427c1459185464ce0fcf62e1e8"
dependencies = [
"cfg-if 1.0.0",
"libc",
"redox_syscall 0.2.5",
"winapi 0.3.9",
]
[[package]]
name = "fsevent"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ab7d1bd1bd33cc98b0889831b72da23c0aa4df9cec7e0702f46ecea04b35db6"
dependencies = [
"bitflags",
"fsevent-sys",
]
[[package]]
name = "fsevent-sys"
version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f41b048a94555da0f42f1d632e2e19510084fb8e303b0daa2816e733fb3644a0"
dependencies = [
"libc",
]
[[package]]
name = "fuchsia-zircon"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82"
dependencies = [
"bitflags",
"fuchsia-zircon-sys",
]
[[package]]
name = "fuchsia-zircon-sys"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
[[package]]
name = "generic-array"
version = "0.12.4"
@ -353,7 +406,7 @@ version = "0.1.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce"
dependencies = [
"cfg-if",
"cfg-if 1.0.0",
"libc",
"wasi 0.9.0+wasi-snapshot-preview1",
]
@ -387,13 +440,42 @@ dependencies = [
"libc",
]
[[package]]
name = "inotify"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4816c66d2c8ae673df83366c18341538f234a26d65a9ecea5c348b453ac1d02f"
dependencies = [
"bitflags",
"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 = "instant"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "61124eeebbd69b8190558df225adf7e4caafce0d743919e5d6b19652314ec5ec"
dependencies = [
"cfg-if",
"cfg-if 1.0.0",
]
[[package]]
name = "iovec"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e"
dependencies = [
"libc",
]
[[package]]
@ -429,12 +511,28 @@ dependencies = [
"wasm-bindgen",
]
[[package]]
name = "kernel32-sys"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
dependencies = [
"winapi 0.2.8",
"winapi-build",
]
[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "lazycell"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
[[package]]
name = "libc"
version = "0.2.92"
@ -462,7 +560,7 @@ version = "0.4.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
dependencies = [
"cfg-if",
"cfg-if 1.0.0",
]
[[package]]
@ -502,6 +600,25 @@ dependencies = [
"unicase",
]
[[package]]
name = "mio"
version = "0.6.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4afd66f5b91bf2a3bc13fad0e21caedac168ca4c707504e75585648ae80e4cc4"
dependencies = [
"cfg-if 0.1.10",
"fuchsia-zircon",
"fuchsia-zircon-sys",
"iovec",
"kernel32-sys",
"libc",
"log",
"miow 0.2.2",
"net2",
"slab",
"winapi 0.2.8",
]
[[package]]
name = "mio"
version = "0.7.11"
@ -510,9 +627,33 @@ checksum = "cf80d3e903b34e0bd7282b218398aec54e082c840d9baf8339e0080a0c542956"
dependencies = [
"libc",
"log",
"miow",
"miow 0.3.7",
"ntapi",
"winapi",
"winapi 0.3.9",
]
[[package]]
name = "mio-extras"
version = "2.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "52403fe290012ce777c4626790c8951324a2b9e3316b3143779c72b029742f19"
dependencies = [
"lazycell",
"log",
"mio 0.6.23",
"slab",
]
[[package]]
name = "miow"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ebd808424166322d4a38da87083bfddd3ac4c131334ed55856112eb06d46944d"
dependencies = [
"kernel32-sys",
"net2",
"winapi 0.2.8",
"ws2_32-sys",
]
[[package]]
@ -521,7 +662,36 @@ version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21"
dependencies = [
"winapi",
"winapi 0.3.9",
]
[[package]]
name = "net2"
version = "0.2.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "391630d12b68002ae1e25e8f974306474966550ad82dac6886fb8910c19568ae"
dependencies = [
"cfg-if 0.1.10",
"libc",
"winapi 0.3.9",
]
[[package]]
name = "notify"
version = "4.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "80ae4a7688d1fab81c5bf19c64fc8db920be8d519ce6336ed4e7efe024724dbd"
dependencies = [
"bitflags",
"filetime",
"fsevent",
"fsevent-sys",
"inotify",
"libc",
"mio 0.6.23",
"mio-extras",
"walkdir",
"winapi 0.3.9",
]
[[package]]
@ -530,7 +700,7 @@ version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f6bb902e437b6d86e03cce10a7e2af662292c5dfef23b65899ea3ac9354ad44"
dependencies = [
"winapi",
"winapi 0.3.9",
]
[[package]]
@ -597,12 +767,12 @@ version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fa7a782938e745763fe6907fc6ba86946d72f49fe7e21de074e08128a99fb018"
dependencies = [
"cfg-if",
"cfg-if 1.0.0",
"instant",
"libc",
"redox_syscall 0.2.5",
"smallvec",
"winapi",
"winapi 0.3.9",
]
[[package]]
@ -913,7 +1083,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7e31d442c16f047a671b5a71e2161d6e68814012b7f5379d269ebd915fac2729"
dependencies = [
"libc",
"mio",
"mio 0.7.11",
"signal-hook-registry",
]
@ -926,6 +1096,12 @@ dependencies = [
"libc",
]
[[package]]
name = "slab"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
[[package]]
name = "smallvec"
version = "1.6.1"
@ -972,7 +1148,7 @@ checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255"
dependencies = [
"libc",
"wasi 0.10.0+wasi-snapshot-preview1",
"winapi",
"winapi 0.3.9",
]
[[package]]
@ -1051,7 +1227,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56"
dependencies = [
"same-file",
"winapi",
"winapi 0.3.9",
"winapi-util",
]
@ -1073,7 +1249,7 @@ version = "0.2.73"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "83240549659d187488f91f33c0f8547cbfef0b2088bc470c116d1d260ef623d9"
dependencies = [
"cfg-if",
"cfg-if 1.0.0",
"wasm-bindgen-macro",
]
@ -1131,6 +1307,12 @@ dependencies = [
"wasm-bindgen",
]
[[package]]
name = "winapi"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
[[package]]
name = "winapi"
version = "0.3.9"
@ -1141,6 +1323,12 @@ dependencies = [
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
name = "winapi-build"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
@ -1153,7 +1341,7 @@ version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
dependencies = [
"winapi",
"winapi 0.3.9",
]
[[package]]
@ -1162,6 +1350,16 @@ version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "ws2_32-sys"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e"
dependencies = [
"winapi 0.2.8",
"winapi-build",
]
[[package]]
name = "xplr"
version = "0.3.9"
@ -1173,6 +1371,7 @@ dependencies = [
"dirs",
"handlebars",
"mime_guess",
"notify",
"serde",
"serde_yaml",
"termion",

@ -22,6 +22,7 @@ handlebars = "3.5"
mime_guess = "2.0.3"
anyhow = "1.0"
chrono = { version = "0.4", features = ["serde"] }
notify = "4.0.12"
[dev-dependencies]
criterion = "0.3"

@ -10,23 +10,21 @@ fn criterion_benchmark(c: &mut Criterion) {
let app = app::App::create("/tmp/xplr_bench".into())
.expect("failed to create app")
.enqueue(app::Task::new(
.handle_task(app::Task::new(
1,
app::MsgIn::External(app::ExternalMsg::ChangeDirectory("/tmp/xplr_bench".into())),
None,
))
.mutate_or_sleep()
.unwrap();
c.bench_function("focus next item", |b| {
b.iter(|| {
app.clone()
.enqueue(app::Task::new(
.handle_task(app::Task::new(
1,
app::MsgIn::External(app::ExternalMsg::FocusNext),
None,
))
.mutate_or_sleep()
.unwrap()
})
});
@ -34,12 +32,11 @@ fn criterion_benchmark(c: &mut Criterion) {
c.bench_function("focus previous item", |b| {
b.iter(|| {
app.clone()
.enqueue(app::Task::new(
.handle_task(app::Task::new(
1,
app::MsgIn::External(app::ExternalMsg::FocusPrevious),
None,
))
.mutate_or_sleep()
.unwrap()
})
});
@ -47,12 +44,11 @@ fn criterion_benchmark(c: &mut Criterion) {
c.bench_function("focus first item", |b| {
b.iter(|| {
app.clone()
.enqueue(app::Task::new(
.handle_task(app::Task::new(
1,
app::MsgIn::External(app::ExternalMsg::FocusFirst),
None,
))
.mutate_or_sleep()
.unwrap()
})
});
@ -60,12 +56,11 @@ fn criterion_benchmark(c: &mut Criterion) {
c.bench_function("focus last item", |b| {
b.iter(|| {
app.clone()
.enqueue(app::Task::new(
.handle_task(app::Task::new(
1,
app::MsgIn::External(app::ExternalMsg::FocusLast),
None,
))
.mutate_or_sleep()
.unwrap()
})
});
@ -73,19 +68,17 @@ fn criterion_benchmark(c: &mut Criterion) {
c.bench_function("leave and enter directory", |b| {
b.iter(|| {
app.clone()
.enqueue(app::Task::new(
.handle_task(app::Task::new(
1,
app::MsgIn::External(app::ExternalMsg::Back),
None,
))
.mutate_or_sleep()
.unwrap()
.enqueue(app::Task::new(
.handle_task(app::Task::new(
1,
app::MsgIn::External(app::ExternalMsg::Enter),
None,
))
.mutate_or_sleep()
.unwrap()
})
});

@ -12,7 +12,6 @@ use std::collections::VecDeque;
use std::fs;
use std::io;
use std::path::PathBuf;
use std::time::Duration;
pub const VERSION: &str = "v0.3.9"; // Update Cargo.toml and default.nix
pub const TEMPLATE_TABLE_ROW: &str = "TEMPLATE_TABLE_ROW";
@ -826,15 +825,10 @@ impl App {
self
}
pub fn mutate_or_sleep(mut self) -> Result<Self> {
if let Some(task) = self.tasks.pop() {
match task.msg {
MsgIn::Internal(msg) => self.handle_internal(msg),
MsgIn::External(msg) => self.handle_external(msg, task.key),
}
} else {
std::thread::sleep(Duration::from_millis(5));
Ok(self)
pub fn handle_task(self, task: Task) -> Result<Self> {
match task.msg {
MsgIn::Internal(msg) => self.handle_internal(msg),
MsgIn::External(msg) => self.handle_external(msg, task.key),
}
}
@ -1430,4 +1424,9 @@ impl App {
pub fn version(&self) -> &String {
&self.version
}
/// Get a reference to the app's tasks.
pub fn pop_task_out(&mut self) -> Option<Task> {
self.tasks.pop()
}
}

@ -9,4 +9,5 @@ pub mod event_reader;
pub mod explorer;
pub mod input;
pub mod pipe_reader;
pub mod pwd_watcher;
pub mod ui;

@ -17,11 +17,13 @@ use xplr::auto_refresher;
use xplr::event_reader;
use xplr::explorer;
use xplr::pipe_reader;
use xplr::pwd_watcher;
use xplr::ui;
fn main() -> Result<()> {
let (tx_msg_in, rx_msg_in) = mpsc::channel();
let (tx_event_reader, rx_event_reader) = mpsc::channel();
let (tx_pwd_watcher, rx_pwd_watcher) = mpsc::channel();
let mut pwd = PathBuf::from(env::args().nth(1).unwrap_or_else(|| ".".into()))
.canonicalize()
@ -93,15 +95,25 @@ fn main() -> Result<()> {
auto_refresher::start_auto_refreshing(tx_msg_in.clone());
pipe_reader::keep_reading(app.pipe().msg_in.clone(), tx_msg_in.clone());
event_reader::keep_reading(tx_msg_in.clone(), rx_event_reader);
pwd_watcher::keep_watching(app.pwd(), tx_msg_in.clone(), rx_pwd_watcher)?;
'outer: for task in rx_msg_in {
let last_app = app.clone();
let (new_app, new_result) = match app.handle_task(task) {
Ok(a) => (a, Ok(())),
Err(err) => (last_app.clone(), Err(err)),
};
app = new_app;
result = new_result;
if result.is_err() {
break;
}
let mut last_app = app.clone();
'outer: while result.is_ok() {
while let Some(msg) = app.pop_msg_out() {
match msg {
app::MsgOut::Debug(path) => {
fs::write(&path, serde_yaml::to_string(&app)?)?;
}
app::MsgOut::PrintResultAndQuit => {
output = Some(app.result_str());
break 'outer;
@ -113,6 +125,10 @@ fn main() -> Result<()> {
break 'outer;
}
app::MsgOut::Debug(path) => {
fs::write(&path, serde_yaml::to_string(&app)?)?;
}
app::MsgOut::ClearScreen => {
terminal.clear()?;
}
@ -129,6 +145,7 @@ fn main() -> Result<()> {
app::MsgOut::Refresh => {
app = app.refresh_selection()?;
if app.pwd() != last_app.pwd() {
tx_pwd_watcher.send(app.pwd().clone())?;
explorer::explore(
app.explorer_config().clone(),
app.pwd().clone(),
@ -162,7 +179,7 @@ fn main() -> Result<()> {
if app.result() != last_app.result() {
fs::write(&app.pipe().result_out, app.result_str())?;
}
};
}
app::MsgOut::Call(cmd) => {
@ -230,20 +247,11 @@ fn main() -> Result<()> {
terminal.draw(|f| ui::draw(f, &app, &hb))?;
}
};
last_app = app.clone();
}
for task in rx_msg_in.try_iter() {
app = app.enqueue(task);
while let Some(task) = app.pop_task_out() {
tx_msg_in.send(task)?;
}
let (new_app, new_result) = match app.clone().mutate_or_sleep() {
Ok(a) => (a, Ok(())),
Err(e) => (app, Err(e)),
};
app = new_app;
result = new_result;
}
terminal.clear()?;

@ -0,0 +1,38 @@
use crate::app::Task;
use crate::app::{ExternalMsg, MsgIn};
use anyhow::Result;
use notify::{watcher, RecursiveMode, Watcher};
use std::sync::mpsc::{channel, Receiver, Sender};
use std::thread;
use std::time::Duration;
pub fn keep_watching(
pwd: &str,
tx_msg_in: Sender<Task>,
rx_pwd_watcher: Receiver<String>,
) -> Result<()> {
let (tx, rx) = channel();
let mut watcher = watcher(tx, Duration::from_secs(1))?;
watcher.watch(pwd, RecursiveMode::NonRecursive)?;
let mut last_pwd = pwd.to_string();
thread::spawn(move || loop {
if let Ok(new_pwd) = rx_pwd_watcher.try_recv() {
watcher.unwatch(&last_pwd).unwrap();
watcher
.watch(&new_pwd, RecursiveMode::NonRecursive)
.unwrap();
last_pwd = new_pwd;
} else {
thread::sleep(Duration::from_secs(1));
}
if rx.try_recv().is_ok() {
let msg = MsgIn::External(ExternalMsg::Explore);
tx_msg_in.send(Task::new(3, msg, None)).unwrap();
} else {
thread::sleep(Duration::from_secs(1));
}
});
Ok(())
}
Loading…
Cancel
Save