From 1af7d728d6400d0caa419e0081ba3f71e171f5ff Mon Sep 17 00:00:00 2001 From: sxyazi Date: Mon, 28 Aug 2023 13:15:34 +0800 Subject: [PATCH] .. --- app/src/executor.rs | 2 +- core/src/files/file.rs | 2 +- core/src/files/files.rs | 6 ++-- core/src/manager/folder.rs | 2 +- core/src/manager/manager.rs | 24 +++++++-------- core/src/manager/watcher.rs | 59 ++++++++++++++++++++++--------------- core/src/tasks/scheduler.rs | 5 ++-- shared/src/fs.rs | 4 +-- 8 files changed, 57 insertions(+), 47 deletions(-) diff --git a/app/src/executor.rs b/app/src/executor.rs index 68702479..025475c2 100644 --- a/app/src/executor.rs +++ b/app/src/executor.rs @@ -106,7 +106,7 @@ impl Executor { } } "remove" => { - let targets = cx.manager.selected().into_iter().map(|p| p.path()).collect(); + let targets = cx.manager.selected().into_iter().map(|f| f.path().clone()).collect(); cx.tasks.file_remove(targets, exec.named.contains_key("permanently")) } "create" => cx.manager.create(), diff --git a/core/src/files/file.rs b/core/src/files/file.rs index c66420fc..53331015 100644 --- a/core/src/files/file.rs +++ b/core/src/files/file.rs @@ -37,7 +37,7 @@ impl File { impl File { #[inline] - pub fn path(&self) -> PathBuf { self.path.clone() } + pub fn path(&self) -> &PathBuf { &self.path } #[inline] pub fn set_path(mut self, path: PathBuf) -> Self { diff --git a/core/src/files/files.rs b/core/src/files/files.rs index a7053f8f..a2681ced 100644 --- a/core/src/files/files.rs +++ b/core/src/files/files.rs @@ -86,7 +86,7 @@ impl Files { match state { Some(true) => { - self.selected = self.iter().map(|f| f.path()).collect(); + self.selected = self.iter().map(|f| f.path().clone()).collect(); } Some(false) => { self.selected.clear(); @@ -96,7 +96,7 @@ impl Files { if self.selected.contains(&item.path) { self.selected.remove(&item.path); } else { - self.selected.insert(item.path()); + self.selected.insert(item.path().clone()); } } } @@ -106,7 +106,7 @@ impl Files { pub fn select_index(&mut self, indices: &BTreeSet, state: Option) -> bool { let mut applied = false; - let paths: Vec<_> = self.pick(indices).iter().map(|f| f.path()).collect(); + let paths: Vec<_> = self.pick(indices).iter().map(|f| f.path().clone()).collect(); for path in paths { applied |= self.select(&path, state); diff --git a/core/src/manager/folder.rs b/core/src/manager/folder.rs index 9b976d64..5a0ca30a 100644 --- a/core/src/manager/folder.rs +++ b/core/src/manager/folder.rs @@ -40,7 +40,7 @@ impl Folder { self.cursor = self.cursor.min(len.saturating_sub(1)); self.set_page(true); - if let Some(h) = self.hovered.as_ref().map(|h| h.path()) { + if let Some(h) = self.hovered.as_ref().map(|h| h.path().clone()) { self.hover(&h); } self.hovered = self.files.duplicate(self.cursor); diff --git a/core/src/manager/manager.rs b/core/src/manager/manager.rs index 678fe5ca..98e334a9 100644 --- a/core/src/manager/manager.rs +++ b/core/src/manager/manager.rs @@ -39,15 +39,15 @@ impl Manager { let mut to_watch = BTreeSet::new(); for tab in self.tabs.iter() { - to_watch.insert(tab.current.cwd.clone()); - if let Some(ref p) = tab.parent { - to_watch.insert(p.cwd.clone()); - } + to_watch.insert(&tab.current.cwd); if let Some(ref h) = tab.current.hovered { if h.meta.is_dir() { to_watch.insert(h.path()); } } + if let Some(ref p) = tab.parent { + to_watch.insert(&p.cwd); + } } self.watcher.watch(to_watch); } @@ -83,10 +83,8 @@ impl Manager { } pub fn yank(&mut self, cut: bool) -> bool { - let selected = self.selected().into_iter().map(|f| f.path()).collect::>(); self.yanked.0 = cut; - self.yanked.1.clear(); - self.yanked.1.extend(selected); + self.yanked.1 = self.selected().into_iter().map(|f| f.path().clone()).collect(); false } @@ -124,7 +122,7 @@ impl Manager { .into_iter() .map(|f| { ( - f.path().into_os_string(), + f.path().as_os_str().to_owned(), if f.meta.is_dir() { Some(MIME_DIR.to_owned()) } else { @@ -203,7 +201,7 @@ impl Manager { return self.bulk_rename(); } - let Some(hovered) = self.hovered().map(|h| h.path()) else { + let Some(hovered) = self.hovered().map(|h| h.path().clone()) else { return false; }; @@ -221,10 +219,10 @@ impl Manager { } pub fn bulk_rename(&self) -> bool { - let mut old: Vec<_> = self.selected().iter().map(|&f| f.path()).collect(); + let old: Vec<_> = self.selected().into_iter().map(|f| f.path()).collect(); let root = max_common_root(&old); - old.iter_mut().for_each(|p| *p = p.strip_prefix(&root).unwrap().to_owned()); + let old: Vec<_> = old.into_iter().map(|p| p.strip_prefix(&root).unwrap().to_owned()).collect(); let tmp = BOOT.tmpfile("bulk"); tokio::spawn(async move { @@ -327,7 +325,7 @@ impl Manager { pub fn update_read(&mut self, op: FilesOp) -> bool { let path = op.path(); let cwd = self.cwd().to_owned(); - let hovered = self.hovered().map(|h| h.path()); + let hovered = self.hovered().map(|h| h.path().clone()); let mut b = if cwd == path && !self.current().in_search { self.current_mut().update(op) @@ -347,7 +345,7 @@ impl Manager { b |= self.active_mut().parent.as_mut().map_or(false, |p| p.hover(&cwd)); b |= hovered.as_ref().map_or(false, |h| self.current_mut().hover(h)); - if hovered != self.hovered().map(|h| h.path()) { + if hovered.as_ref() != self.hovered().map(|h| h.path()) { emit!(Hover); } b diff --git a/core/src/manager/watcher.rs b/core/src/manager/watcher.rs index cc2c8b75..3848cbc0 100644 --- a/core/src/manager/watcher.rs +++ b/core/src/manager/watcher.rs @@ -69,44 +69,55 @@ impl Watcher { instance } - pub(super) fn watch(&mut self, mut to_watch: BTreeSet) { - let keys = self.watched.read().keys().cloned().collect::>(); - for p in keys.difference(&to_watch) { - self.watcher.unwatch(p).ok(); + pub(super) fn watch(&mut self, mut watched: BTreeSet<&PathBuf>) { + let (to_unwatch, to_watch): (BTreeSet<_>, BTreeSet<_>) = { + let guard = self.watched.read(); + let keys = guard.keys().collect::>(); + ( + keys.difference(&watched).map(|&x| x.clone()).collect(), + watched.difference(&keys).map(|&x| x.clone()).collect(), + ) + }; + + for p in to_unwatch { + self.watcher.unwatch(&p).ok(); } - for p in to_watch.clone().difference(&keys) { - if self.watcher.watch(p, RecursiveMode::NonRecursive).is_err() { - to_watch.remove(p); + for p in to_watch { + if self.watcher.watch(&p, RecursiveMode::NonRecursive).is_err() { + watched.remove(&p); } } - let mut todo = Vec::new(); - let mut watched = self.watched.write(); - *watched = IndexMap::from_iter(to_watch.into_iter().map(|k| { - if let Some(v) = watched.remove(&k) { - (k, v) - } else { - todo.push(k.clone()); - (k, None) - } - })); - watched.sort_unstable_by(|_, a, _, b| b.cmp(a)); + let mut to_resolve = Vec::new(); + let mut guard = self.watched.write(); + *guard = watched + .into_iter() + .map(|k| { + if let Some((k, v)) = guard.remove_entry(k) { + (k, v) + } else { + to_resolve.push(k.clone()); + (k.clone(), None) + } + }) + .collect(); + guard.sort_unstable_by(|_, a, _, b| b.cmp(a)); - let watched = self.watched.clone(); + let lock = self.watched.clone(); tokio::spawn(async move { let mut ext = IndexMap::new(); - for k in todo { + for k in to_resolve { match fs::canonicalize(&k).await { - Ok(v) if v != k => { + Ok(v) if v != *k => { ext.insert(k, Some(v)); } _ => {} } } - let mut watched = watched.write(); - watched.extend(ext); - watched.sort_unstable_by(|_, a, _, b| b.cmp(a)); + let mut guard = lock.write(); + guard.extend(ext); + guard.sort_unstable_by(|_, a, _, b| b.cmp(a)); }); } diff --git a/core/src/tasks/scheduler.rs b/core/src/tasks/scheduler.rs index ac2ca0d2..912c23ef 100644 --- a/core/src/tasks/scheduler.rs +++ b/core/src/tasks/scheduler.rs @@ -318,13 +318,13 @@ impl Scheduler { }); } - pub(super) fn precache_size(&self, targets: Vec) { + pub(super) fn precache_size(&self, targets: Vec<&PathBuf>) { let throttle = Arc::new(Throttle::new(targets.len(), Duration::from_millis(300))); let mut handing = self.precache.size_handing.lock(); let mut running = self.running.write(); for target in targets { - if !handing.contains(&target) { + if !handing.contains(target) { handing.insert(target.clone()); } else { continue; @@ -333,6 +333,7 @@ impl Scheduler { let id = running.add(format!("Calculate the size of {:?}", target)); let _ = self.todo.send_blocking({ let precache = self.precache.clone(); + let target = target.clone(); let throttle = throttle.clone(); async move { precache.size(PrecacheOpSize { id, target, throttle }).await.ok(); diff --git a/shared/src/fs.rs b/shared/src/fs.rs index 351e990a..8a5cb5fb 100644 --- a/shared/src/fs.rs +++ b/shared/src/fs.rs @@ -148,12 +148,12 @@ pub fn file_mode(mode: u32) -> String { // Find the max common root of a list of files // e.g. /a/b/c, /a/b/d -> /a/b // /aa/bb/cc, /aa/dd/ee -> /aa -pub fn max_common_root(files: &[PathBuf]) -> PathBuf { +pub fn max_common_root(files: &[impl AsRef]) -> PathBuf { if files.is_empty() { return PathBuf::new(); } - let mut it = files.iter().map(|p| p.parent().unwrap_or(Path::new("")).components()); + let mut it = files.iter().map(|p| p.as_ref().parent().unwrap_or(Path::new("")).components()); let mut root = it.next().unwrap().collect::(); for components in it { let mut new_root = PathBuf::new();