Add WIP change detection

change-detection
trivernis 2 years ago
parent 817c2a7e6d
commit eda2ae2f18
Signed by: Trivernis
GPG Key ID: DFFFCC2C7A02DB45

90
Cargo.lock generated

@ -140,6 +140,16 @@ version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc"
[[package]]
name = "crossbeam-channel"
version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521"
dependencies = [
"cfg-if",
"crossbeam-utils",
]
[[package]]
name = "crossbeam-utils"
version = "0.8.11"
@ -260,6 +270,18 @@ dependencies = [
"log",
]
[[package]]
name = "filetime"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e94a7bbaa59354bc20dd75b67f23e2797b4490e9d6928203fb105c79e448c86c"
dependencies = [
"cfg-if",
"libc",
"redox_syscall",
"windows-sys",
]
[[package]]
name = "fnv"
version = "1.0.7"
@ -275,6 +297,15 @@ dependencies = [
"percent-encoding",
]
[[package]]
name = "fsevent-sys"
version = "4.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "76ee7a02da4d231650c7cea31349b889be2f45ddb3ef3032d2ec8185f6313fd2"
dependencies = [
"libc",
]
[[package]]
name = "futures-core"
version = "0.3.24"
@ -483,6 +514,7 @@ dependencies = [
"ignore",
"indoc",
"log",
"notify",
"once_cell",
"pulldown-cmark",
"serde",
@ -594,6 +626,26 @@ version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "adab1eaa3408fb7f0c777a73e7465fd5656136fc93b670eb6df3c88c2c1344e3"
[[package]]
name = "inotify"
version = "0.9.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8069d3ec154eb856955c1c0fbffefbf5f3c40a104ec912d4797314c1801abff"
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.12"
@ -618,6 +670,26 @@ dependencies = [
"wasm-bindgen",
]
[[package]]
name = "kqueue"
version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4d6112e8f37b59803ac47a42d14f1f3a59bbf72fc6857ffc5be455e28a691f8e"
dependencies = [
"kqueue-sys",
"libc",
]
[[package]]
name = "kqueue-sys"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8367585489f01bc55dd27404dcf56b95e6da061a256a666ab23be9ba96a2e587"
dependencies = [
"bitflags",
"libc",
]
[[package]]
name = "lazy_static"
version = "1.4.0"
@ -699,6 +771,24 @@ dependencies = [
"windows-sys",
]
[[package]]
name = "notify"
version = "5.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed2c66da08abae1c024c01d635253e402341b4060a12e99b31c7594063bf490a"
dependencies = [
"bitflags",
"crossbeam-channel",
"filetime",
"fsevent-sys",
"inotify",
"kqueue",
"libc",
"mio",
"walkdir",
"winapi",
]
[[package]]
name = "num-integer"
version = "0.1.45"

@ -66,6 +66,7 @@ serde = { version = "1.0", features = ["derive"] }
# ripgrep for global search
grep-regex = "0.1.10"
grep-searcher = "0.1.10"
notify = "5.0.0"
[target.'cfg(not(windows))'.dependencies] # https://github.com/vorner/signal-hook/issues/100
signal-hook-tokio = { version = "0.3", features = ["futures-v0_3"] }

@ -1370,6 +1370,7 @@ impl Component for EditorView {
if let Some(explore) = self.explorer.as_mut() {
if !explore.content.is_focus() && config.explorer.is_embed() {
explore.content.handle_changes(cx).unwrap();
let current_doc = view!(cx.editor).doc;
let current_doc = cx.editor.document(current_doc).unwrap();
if let Some(path) = current_doc.path() {

@ -11,9 +11,10 @@ use helix_view::{
input::{Event, KeyEvent},
Editor,
};
use std::borrow::Cow;
use std::cmp::Ordering;
use notify::{Config, RecommendedWatcher, RecursiveMode, Watcher};
use std::path::{Path, PathBuf};
use std::{borrow::Cow, sync::mpsc::channel};
use std::{cmp::Ordering, sync::mpsc::Receiver};
use tui::{
buffer::Buffer as Surface,
text::{Span, Spans},
@ -238,39 +239,6 @@ impl TreeItem for FileInfo {
}
}
// #[derive(Default, Debug, Clone)]
// struct PathState {
// root: PathBuf,
// sub_items: Vec<FileInfo>,
// selected: usize,
// save_view: (usize, usize), // (selected, row)
// row: usize,
// col: usize,
// max_len: usize,
// }
// impl PathState {
// fn mkdir(&mut self, dir: &str) -> Result<()> {
// self.new_path(dir, FileType::Dir)
// }
// fn create_file(&mut self, f: &str) -> Result<()> {
// self.new_path(f, FileType::File)
// }
// fn remove_current_file(&mut self) -> Result<()> {
// let item = &self.sub_items[self.selected];
// std::fs::remove_file(item.path_with_root(&self.root))?;
// self.sub_items.remove(self.selected);
// if self.selected >= self.sub_items.len() {
// self.selected = self.sub_items.len() - 1;
// }
// Ok(())
// }
// }
#[derive(Clone, Copy, Debug)]
enum PromptAction {
Search(bool), // search next/search pre
@ -304,12 +272,17 @@ pub struct Explorer {
on_next_key: Option<Box<dyn FnMut(&mut Context, &mut Self, &KeyEvent) -> EventResult>>,
#[allow(clippy::type_complexity)]
repeat_motion: Option<Box<dyn FnMut(&mut Self, PromptAction, &mut Context) + 'static>>,
watcher: RecommendedWatcher,
io_events: Receiver<Result<notify::Event, notify::Error>>,
}
impl Explorer {
pub fn new(cx: &mut Context) -> Result<Self> {
let current_root = std::env::current_dir().unwrap_or_else(|_| "./".into());
let items = Self::get_items(current_root.clone(), cx)?;
let (mut watcher, receiver) = Self::create_watcher()?;
watcher.watch(&current_root, RecursiveMode::Recursive)?;
Ok(Self {
tree: Tree::build_tree(items)
.with_enter_fn(Self::toggle_current)
@ -318,6 +291,8 @@ impl Explorer {
repeat_motion: None,
prompt: None,
on_next_key: None,
watcher,
io_events: receiver,
})
}
@ -339,25 +314,20 @@ impl Explorer {
.with_enter_fn(Self::toggle_current)
.with_folded_fn(Self::fold_current);
tree.insert_current_level(parent);
let (mut watcher, receiver) = Self::create_watcher()?;
watcher.watch(&current_root, RecursiveMode::Recursive)?;
Ok(Self {
tree,
state: State::new(true, current_root),
repeat_motion: None,
prompt: None,
on_next_key: None,
watcher,
io_events: receiver,
})
// let mut root = vec![, FileInfo::root(p)];
}
// pub fn new_with_uri(uri: String) -> Result<Self> {
// // support remote file?
// let p = Path::new(&uri);
// ensure!(p.exists(), "path: {uri} is not exist");
// ensure!(p.is_dir(), "path: {uri} is not dir");
// Ok(Self::default().with_list(get_sub(p, None)?))
// }
pub fn focus(&mut self) {
self.state.focus = true
}
@ -381,6 +351,24 @@ impl Explorer {
Ok(items)
}
pub fn handle_changes(&mut self, cx: &mut Context) -> Result<()> {
if let Ok(o) = self.io_events.try_recv() {
match o {
Ok(_) => self.refresh(cx),
Err(e) => Err(e.into()),
}
} else {
Ok(())
}
}
fn refresh(&mut self, cx: &mut Context) -> Result<()> {
let items = Self::get_items(self.state.current_root.clone(), cx)?;
self.tree.replace_with_new_items(items);
Ok(())
}
fn render_preview(&mut self, area: Rect, surface: &mut Surface, editor: &Editor) {
if area.height <= 2 || area.width < 60 {
return;
@ -422,6 +410,28 @@ impl Explorer {
}
}
fn watch(&mut self, path: &Path) -> Result<()> {
self.watcher.watch(path, RecursiveMode::Recursive)?;
Ok(())
}
fn unwatch(&mut self, path: &Path) -> Result<()> {
self.watcher.unwatch(path)?;
Ok(())
}
fn create_watcher() -> Result<(
RecommendedWatcher,
Receiver<Result<notify::Event, notify::Error>>,
)> {
let (tx, rx) = channel();
let watcher = RecommendedWatcher::new(tx, Config::default())?;
Ok((watcher, rx))
}
fn new_search_prompt(&mut self, search_next: bool) {
self.tree.save_view();
self.prompt = Some((

Loading…
Cancel
Save