From 169543b79978cb7507d2ee628f244a29157ff975 Mon Sep 17 00:00:00 2001 From: sxyazi Date: Sun, 24 Dec 2023 23:01:02 +0800 Subject: [PATCH] .. --- yazi-adaptor/src/adaptor.rs | 2 - yazi-core/src/folder/files.rs | 51 +++++++++++-------- yazi-core/src/folder/folder.rs | 3 +- yazi-core/src/manager/commands/hover.rs | 5 +- yazi-core/src/manager/commands/peek.rs | 19 +++++-- yazi-core/src/manager/commands/refresh.rs | 3 +- .../src/manager/commands/update_files.rs | 2 +- .../src/manager/commands/update_mimetype.rs | 2 +- yazi-core/src/manager/tabs.rs | 1 + yazi-core/src/tab/commands/search.rs | 3 -- yazi-core/src/tab/finder.rs | 12 ++--- yazi-core/src/tab/preview.rs | 12 ++++- yazi-core/src/tab/tab.rs | 6 +-- yazi-fm/src/app/app.rs | 6 +-- yazi-fm/src/app/commands/stop.rs | 7 +-- 15 files changed, 80 insertions(+), 54 deletions(-) diff --git a/yazi-adaptor/src/adaptor.rs b/yazi-adaptor/src/adaptor.rs index a521ff0a..e6d2674d 100644 --- a/yazi-adaptor/src/adaptor.rs +++ b/yazi-adaptor/src/adaptor.rs @@ -160,8 +160,6 @@ impl Adaptor { pub(super) fn start(self) { Ueberzug::start(self); } pub async fn image_show(self, path: &Path, rect: Rect) -> Result<(u32, u32)> { - self.image_hide().ok(); - let size = match self { Self::Kitty => Kitty::image_show(path, rect).await, Self::KittyOld => KittyOld::image_show(path, rect).await, diff --git a/yazi-core/src/folder/files.rs b/yazi-core/src/folder/files.rs index 29a03ac9..90ad88c2 100644 --- a/yazi-core/src/folder/files.rs +++ b/yazi-core/src/folder/files.rs @@ -11,6 +11,7 @@ pub struct Files { hidden: Vec, items: Vec, ticket: u64, + version: u64, pub(crate) revision: u64, pub sizes: BTreeMap, @@ -26,6 +27,7 @@ impl Default for Files { items: Default::default(), hidden: Default::default(), ticket: Default::default(), + version: Default::default(), revision: Default::default(), sizes: Default::default(), @@ -160,9 +162,9 @@ impl Files { } self.ticket = ticket; - if !self.items.is_empty() || !self.hidden.is_empty() { + self.hidden.clear(); + if !self.items.is_empty() { self.revision += 1; - self.hidden.clear(); self.items.clear(); } } @@ -287,14 +289,24 @@ impl Files { return; } - self.revision += 1; if !hidden.is_empty() { self.hidden.extend(hidden.into_values()); } if !items.is_empty() { + self.revision += 1; self.items.extend(items.into_values()); } } + + pub fn catchup_revision(&mut self) -> bool { + if self.version == self.revision { + return false; + } + + self.version = self.revision; + self.sorter.sort(&mut self.items, &self.sizes); + true + } } impl Files { @@ -355,33 +367,32 @@ impl Files { #[inline] pub fn sorter(&self) -> &FilesSorter { &self.sorter } - pub fn set_sorter(&mut self, sorter: FilesSorter) -> bool { - if self.sorter == sorter { - return false; + pub fn set_sorter(&mut self, sorter: FilesSorter) { + if self.sorter != sorter { + self.sorter = sorter; + self.revision += 1; } - self.sorter = sorter; - self.revision += 1; - self.sorter.sort(&mut self.items, &self.sizes) } // --- Show hidden - pub fn set_show_hidden(&mut self, state: bool) -> bool { - if state == self.show_hidden { - return false; - } else if state && self.hidden.is_empty() { - return false; + pub fn set_show_hidden(&mut self, state: bool) { + if self.show_hidden == state { + return; } - if state { + self.show_hidden = state; + if self.show_hidden && self.hidden.is_empty() { + return; + } else if !self.show_hidden && self.items.is_empty() { + return; + } + + self.revision += 1; + if self.show_hidden { self.items.append(&mut self.hidden); - self.sorter.sort(&mut self.items, &self.sizes); } else { let items = mem::take(&mut self.items); (self.hidden, self.items) = items.into_iter().partition(|f| f.is_hidden()); } - - self.show_hidden = state; - self.revision += 1; - true } } diff --git a/yazi-core/src/folder/folder.rs b/yazi-core/src/folder/folder.rs index 5ef367f0..45292d4f 100644 --- a/yazi-core/src/folder/folder.rs +++ b/yazi-core/src/folder/folder.rs @@ -25,7 +25,6 @@ impl From<&Url> for Folder { impl Folder { pub fn update(&mut self, op: FilesOp) -> bool { - let revision = self.files.revision; match op { FilesOp::Full(_, files) => self.files.update_full(files), FilesOp::Part(_, files, ticket) => self.files.update_part(files, ticket), @@ -37,7 +36,7 @@ impl Folder { FilesOp::Upserting(_, files) => self.files.update_upserting(files), _ => unreachable!(), } - if revision == self.files.revision { + if !self.files.catchup_revision() { return false; } diff --git a/yazi-core/src/manager/commands/hover.rs b/yazi-core/src/manager/commands/hover.rs index 6a93ee4e..75144d76 100644 --- a/yazi-core/src/manager/commands/hover.rs +++ b/yazi-core/src/manager/commands/hover.rs @@ -11,6 +11,9 @@ pub struct Opt { impl From<&Exec> for Opt { fn from(e: &Exec) -> Self { Self { url: e.args.first().map(Url::from) } } } +impl From> for Opt { + fn from(url: Option) -> Self { Self { url } } +} impl Manager { #[inline] @@ -27,7 +30,7 @@ impl Manager { let mut b = self.current_mut().repos(opt.url); // Re-peek - b |= self.peek(()); + b |= self.peek(false); // Refresh watcher let mut to_watch = BTreeSet::new(); diff --git a/yazi-core/src/manager/commands/peek.rs b/yazi-core/src/manager/commands/peek.rs index 3fefb558..91559a92 100644 --- a/yazi-core/src/manager/commands/peek.rs +++ b/yazi-core/src/manager/commands/peek.rs @@ -1,10 +1,11 @@ -use yazi_shared::{event::Exec, fs::Url, MIME_DIR}; +use yazi_shared::{emit, event::Exec, fs::Url, Layer, MIME_DIR}; use crate::manager::Manager; #[derive(Debug, Default)] pub struct Opt { skip: Option, + force: bool, only_if: Option, upper_bound: bool, } @@ -13,16 +14,22 @@ impl From<&Exec> for Opt { fn from(e: &Exec) -> Self { Self { skip: e.args.first().and_then(|s| s.parse().ok()), + force: e.named.contains_key("force"), only_if: e.named.get("only-if").map(Url::from), upper_bound: e.named.contains_key("upper-bound"), } } } -impl From<()> for Opt { - fn from(_: ()) -> Self { Default::default() } +impl From for Opt { + fn from(force: bool) -> Self { Self { force, ..Default::default() } } } impl Manager { + #[inline] + pub fn _peek(force: bool) { + emit!(Call(Exec::call("peek", vec![]).with_bool("force", force).vec(), Layer::Manager)); + } + pub fn peek(&mut self, opt: impl Into) -> bool { let Some(hovered) = self.hovered() else { return self.active_mut().preview.reset(); @@ -56,7 +63,11 @@ impl Manager { } } - self.active_mut().preview.go(hovered, mime); + if opt.force { + self.active_mut().preview.force(hovered, mime); + } else { + self.active_mut().preview.go(hovered, mime); + } false } } diff --git a/yazi-core/src/manager/commands/refresh.rs b/yazi-core/src/manager/commands/refresh.rs index 2cf64129..e362e683 100644 --- a/yazi-core/src/manager/commands/refresh.rs +++ b/yazi-core/src/manager/commands/refresh.rs @@ -28,7 +28,6 @@ impl Manager { self.watcher.trigger_dirs(&[self.cwd()]); } - Self::_hover(None); - false + self.hover(None) } } diff --git a/yazi-core/src/manager/commands/update_files.rs b/yazi-core/src/manager/commands/update_files.rs index d2c2144a..158ae30b 100644 --- a/yazi-core/src/manager/commands/update_files.rs +++ b/yazi-core/src/manager/commands/update_files.rs @@ -35,7 +35,7 @@ impl Manager { b |= hovered.as_ref().is_some_and(|h| self.current_mut().hover(h)); if hovered.as_ref() != self.hovered().map(|h| &h.url) { - Self::_hover(None); + b |= self.hover(None); } b } diff --git a/yazi-core/src/manager/commands/update_mimetype.rs b/yazi-core/src/manager/commands/update_mimetype.rs index 1ebf0f61..2911007c 100644 --- a/yazi-core/src/manager/commands/update_mimetype.rs +++ b/yazi-core/src/manager/commands/update_mimetype.rs @@ -37,7 +37,7 @@ impl Manager { tasks.preload_affected(paged, &updates); self.mimetype.extend(updates); - self.peek(()); + self.peek(false); true } } diff --git a/yazi-core/src/manager/tabs.rs b/yazi-core/src/manager/tabs.rs index 4b49480d..b029aa11 100644 --- a/yazi-core/src/manager/tabs.rs +++ b/yazi-core/src/manager/tabs.rs @@ -1,3 +1,4 @@ +use yazi_adaptor::ADAPTOR; use yazi_config::BOOT; use yazi_shared::fs::Url; diff --git a/yazi-core/src/tab/commands/search.rs b/yazi-core/src/tab/commands/search.rs index 15d40439..59635de5 100644 --- a/yazi-core/src/tab/commands/search.rs +++ b/yazi-core/src/tab/commands/search.rs @@ -78,9 +78,6 @@ impl Tab { handle.abort(); } if self.current.cwd.is_search() { - // TODO: plugin system - // self.preview.reset_image(); - let rep = self.history_new(&self.current.cwd.to_regular()); drop(mem::replace(&mut self.current, rep)); Manager::_refresh(); diff --git a/yazi-core/src/tab/finder.rs b/yazi-core/src/tab/finder.rs index 96ea9c19..c537a0c8 100644 --- a/yazi-core/src/tab/finder.rs +++ b/yazi-core/src/tab/finder.rs @@ -14,9 +14,9 @@ pub enum FinderCase { } pub struct Finder { - query: Regex, - matched: BTreeMap, - version: u64, + query: Regex, + matched: BTreeMap, + revision: u64, } impl Finder { @@ -29,7 +29,7 @@ impl Finder { FinderCase::Sensitive => Regex::new(s)?, FinderCase::Insensitive => RegexBuilder::new(s).case_insensitive(true).build()?, }; - Ok(Self { query, matched: Default::default(), version: 0 }) + Ok(Self { query, matched: Default::default(), revision: 0 }) } pub(super) fn prev(&self, files: &Files, cursor: usize, include: bool) -> Option { @@ -53,7 +53,7 @@ impl Finder { } pub(super) fn catchup(&mut self, files: &Files) -> bool { - if self.version == files.revision { + if self.revision == files.revision { return false; } self.matched.clear(); @@ -72,7 +72,7 @@ impl Finder { i += 1; } - self.version = files.revision; + self.revision = files.revision; true } diff --git a/yazi-core/src/tab/preview.rs b/yazi-core/src/tab/preview.rs index 534d5ac2..90247f91 100644 --- a/yazi-core/src/tab/preview.rs +++ b/yazi-core/src/tab/preview.rs @@ -14,10 +14,12 @@ pub struct Preview { impl Preview { pub fn go(&mut self, file: File, mime: String) { - if self.content_unchanged(&file.url, &file.cha) { - return; + if !self.content_unchanged(&file.url, &file.cha) { + self.force(file, mime); } + } + pub fn force(&mut self, file: File, mime: String) { let Some(previewer) = PLUGIN.previewer(&file.url, &mime) else { self.reset(); return; @@ -44,6 +46,12 @@ impl Preview { self.lock.take().is_some() } + #[inline] + pub fn reset_image(&mut self) { + self.abort(); + ADAPTOR.image_hide().ok(); + } + #[inline] pub fn same_url(&self, url: &Url) -> bool { matches!(self.lock, Some(ref lock) if lock.url == *url) diff --git a/yazi-core/src/tab/tab.rs b/yazi-core/src/tab/tab.rs index 238829c6..c493ca38 100644 --- a/yazi-core/src/tab/tab.rs +++ b/yazi-core/src/tab/tab.rs @@ -76,9 +76,9 @@ impl Tab { let apply = |f: &mut Folder| { let hovered = f.hovered().map(|h| h.url()); - let mut b = f.files.set_show_hidden(self.conf.show_hidden); - b |= f.files.set_sorter(self.conf.sorter()); - b | f.repos(hovered) + f.files.set_show_hidden(self.conf.show_hidden); + f.files.set_sorter(self.conf.sorter()); + f.files.catchup_revision() | f.repos(hovered) }; let mut b = false; diff --git a/yazi-fm/src/app/app.rs b/yazi-fm/src/app/app.rs index e2ab7910..113076bf 100644 --- a/yazi-fm/src/app/app.rs +++ b/yazi-fm/src/app/app.rs @@ -86,9 +86,7 @@ impl App { if !COLLISION.load(Ordering::Relaxed) { if collision { // Reload preview if collision is resolved - // TODO: plugin system - // self.cx.manager.active_mut().preview.reset_image(); - self.cx.manager.peek(()); + self.cx.manager.peek(true); } return Ok(()); } @@ -117,7 +115,7 @@ impl App { self.dispatch_render()?; self.cx.manager.current_mut().set_page(true); - self.cx.manager.peek(()); + self.cx.manager.peek(false); Ok(()) } diff --git a/yazi-fm/src/app/commands/stop.rs b/yazi-fm/src/app/commands/stop.rs index 3b19f3cf..f0ded8eb 100644 --- a/yazi-fm/src/app/commands/stop.rs +++ b/yazi-fm/src/app/commands/stop.rs @@ -1,5 +1,6 @@ use anyhow::Result; use tokio::sync::oneshot; +use yazi_adaptor::ADAPTOR; use yazi_core::manager::Manager; use yazi_shared::{emit, event::Exec, term::Term}; @@ -24,16 +25,16 @@ impl App { return false; }; - // TODO: plugin system - // self.cx.manager.active_mut().preview.reset_image(); + self.cx.manager.active_mut().preview.reset_image(); if opt.state { self.signals.stop_term(true); self.term = None; } else { self.term = Some(Term::start().unwrap()); self.signals.stop_term(false); + self.cx.manager.hover(None); + self.cx.manager.peek(true); emit!(Render); - Manager::_hover(None); } if let Some(tx) = opt.tx { tx.send(()).ok();