From 56b0611f7c8ac96ad2d0ecd1797069b12a554d8a Mon Sep 17 00:00:00 2001 From: sxyazi Date: Fri, 24 Nov 2023 06:21:13 +0800 Subject: [PATCH] fix: peek down directories --- README.md | 24 ++++---- yazi-core/src/manager/commands/hover.rs | 4 +- yazi-core/src/manager/commands/peek.rs | 28 ++++----- yazi-core/src/preview/preview.rs | 80 +++++++++++-------------- yazi-fm/src/app.rs | 2 +- yazi-plugin/src/bindings/active.rs | 4 +- 6 files changed, 67 insertions(+), 75 deletions(-) diff --git a/README.md b/README.md index 7176342b..6d0ce515 100644 --- a/README.md +++ b/README.md @@ -31,18 +31,18 @@ https://github.com/sxyazi/yazi/assets/17523360/92ff23fa-0cd5-4f04-b387-894c12265 ## Image Preview -| Platform | Protocol | Support | -| ----------------- | -------------------------------------------------------------------------------- | --------------------- | -| kitty | [Terminal graphics protocol](https://sw.kovidgoyal.net/kitty/graphics-protocol/) | ✅ Built-in | -| WezTerm | [Terminal graphics protocol](https://sw.kovidgoyal.net/kitty/graphics-protocol/) | ✅ Built-in | -| Konsole | [Terminal graphics protocol](https://sw.kovidgoyal.net/kitty/graphics-protocol/) | ✅ Built-in | -| iTerm2 | [Inline images protocol](https://iterm2.com/documentation-images.html) | ✅ Built-in | -| Mintty (Git Bash) | [Inline images protocol](https://iterm2.com/documentation-images.html) | ✅ Built-in | -| Hyper | [Sixel graphics format](https://www.vt100.net/docs/vt3xx-gp/chapter14.html) | ✅ Built-in | -| foot | [Sixel graphics format](https://www.vt100.net/docs/vt3xx-gp/chapter14.html) | ✅ Built-in | -| Black Box | [Sixel graphics format](https://www.vt100.net/docs/vt3xx-gp/chapter14.html) | ✅ Built-in | -| X11 / Wayland | Window system protocol | ☑️ Überzug++ required | -| Fallback | [Chafa](https://hpjansson.org/chafa/) | ☑️ Überzug++ required | +| Platform | Protocol | Support | +| ----------------- | ----------------------------------------------------------------------------------------------------- | --------------------- | +| kitty | [Kitty unicode placeholders](https://sw.kovidgoyal.net/kitty/graphics-protocol/#unicode-placeholders) | ✅ Built-in | +| Konsole | [Kitty old protocol](https://github.com/sxyazi/yazi/blob/main/yazi-adaptor/src/kitty_old.rs) | ✅ Built-in | +| iTerm2 | [Inline images protocol](https://iterm2.com/documentation-images.html) | ✅ Built-in | +| WezTerm | [Inline images protocol](https://iterm2.com/documentation-images.html) | ✅ Built-in | +| Mintty (Git Bash) | [Inline images protocol](https://iterm2.com/documentation-images.html) | ✅ Built-in | +| foot | [Sixel graphics format](https://www.vt100.net/docs/vt3xx-gp/chapter14.html) | ✅ Built-in | +| Black Box | [Sixel graphics format](https://www.vt100.net/docs/vt3xx-gp/chapter14.html) | ✅ Built-in | +| Hyper | [Sixel graphics format](https://www.vt100.net/docs/vt3xx-gp/chapter14.html) | ✅ Built-in | +| X11 / Wayland | Window system protocol | ☑️ Überzug++ required | +| Fallback | [Chafa](https://hpjansson.org/chafa/) | ☑️ Überzug++ required | Yazi automatically selects the appropriate preview method for you, based on the priority from top to bottom. That's relying on the `$TERM`, `$TERM_PROGRAM`, and `$XDG_SESSION_TYPE` variables, make sure you don't overwrite them by mistake! diff --git a/yazi-core/src/manager/commands/hover.rs b/yazi-core/src/manager/commands/hover.rs index d6d24b33..a68c7e90 100644 --- a/yazi-core/src/manager/commands/hover.rs +++ b/yazi-core/src/manager/commands/hover.rs @@ -25,10 +25,10 @@ impl Manager { pub fn hover(&mut self, opt: impl Into) -> bool { // Hover on the file let opt = opt.into() as Opt; - let b = self.current_mut().repos(opt.url); + let mut b = self.current_mut().repos(opt.url); // Re-peek - self.peek(0); + b |= self.peek(0); // 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 0dce34b0..bfafb5d5 100644 --- a/yazi-core/src/manager/commands/peek.rs +++ b/yazi-core/src/manager/commands/peek.rs @@ -54,12 +54,13 @@ impl Manager { }; let (url, cha) = (hovered.url.clone(), hovered.cha); - if self.active().preview.same_url(&url) { - self.active_mut().preview.arrow(opt.step, &mime); - } else if opt.upper_bound { - self.active_mut().preview.apply_bound(opt.step as usize); + if opt.upper_bound { + self.active_mut().preview.arrow(0, &mime, Some(opt.step as usize)); + } else if self.active().preview.same_url(&url) { + self.active_mut().preview.arrow(opt.step, &mime, None); } else { - self.active_mut().preview.set_skip(0); + self.active_mut().preview.arrow(0, &mime, Some(0)); + self.active_mut().preview.reset(); } self.active_mut().preview.go(&url, cha, &mime); @@ -72,15 +73,14 @@ impl Manager { .map(|f| (f.offset, f.files.len().saturating_sub(MANAGER.layout.folder_height()))) .unwrap_or_default(); - if self.active().preview.same_url(&url) { - self.active_mut().preview.arrow(opt.step, MIME_DIR); - self.active_mut().preview.apply_bound(bound); - return false; - } - let in_chunks = folder.is_none(); - self.active_mut().preview.set_skip(skip); - self.active_mut().preview.go_folder(url, in_chunks); - false + if self.active().preview.same_url(&url) { + self.active_mut().preview.arrow(opt.step, MIME_DIR, Some(bound)); + self.active_mut().preview.sync_skip() + } else { + self.active_mut().preview.arrow(skip as isize, MIME_DIR, Some(skip)); + self.active_mut().preview.go_folder(url, in_chunks); + false + } } } diff --git a/yazi-core/src/preview/preview.rs b/yazi-core/src/preview/preview.rs index 4bb996d5..2ea76927 100644 --- a/yazi-core/src/preview/preview.rs +++ b/yazi-core/src/preview/preview.rs @@ -37,7 +37,7 @@ impl Preview { return; } - self.reset(); + self.abort(); let (url, kind, skip) = (url.clone(), MimeKind::new(mime), self.skip); self.handle = Some(tokio::spawn(async move { @@ -54,7 +54,7 @@ impl Preview { } pub fn go_folder(&mut self, url: Url, in_chunks: bool) { - self.reset(); + self.abort(); self.lock = Some(PreviewLock { url: url.clone(), cha: None, @@ -84,34 +84,49 @@ impl Preview { })); } - pub fn reset(&mut self) -> bool { - self.handle.take().map(|h| h.abort()); - Highlighter::abort(); - ADAPTOR.image_hide(MANAGER.layout.image_rect()).ok(); + pub fn arrow(&mut self, step: isize, mime: &str, upper: Option) { + let size = Provider::step_size(MimeKind::new(mime), step.unsigned_abs()); + self.skip = if step < 0 { self.skip.saturating_sub(size) } else { self.skip + size }; - let Some(ref lock) = self.lock else { - return false; - }; - - let b = !lock.is_image(); - self.lock = None; - b - } - - pub fn reset_image(&mut self) -> bool { - if !matches!(self.lock, Some(ref lock) if lock.is_image()) { - return false; + if let Some(upper) = upper { + self.skip = self.skip.min(upper); } - - self.reset(); - true } #[inline] + pub fn abort(&mut self) { + self.handle.take().map(|h| h.abort()); + Highlighter::abort(); + ADAPTOR.image_hide(MANAGER.layout.image_rect()).ok(); + } + + #[inline] + pub fn reset(&mut self) -> bool { + self.abort(); + self.lock.take().map(|l| l.is_image()) == Some(false) + } + + pub fn reset_image(&mut self) -> bool { + if matches!(self.lock, Some(ref l) if l.is_image()) { + self.reset(); + true + } else { + false + } + } + pub fn same_url(&self, url: &Url) -> bool { matches!(self.lock, Some(ref lock) if lock.url == *url) } + pub fn sync_skip(&mut self) -> bool { + if let Some(lock) = &mut self.lock { + mem::replace(&mut lock.skip, self.skip) != self.skip + } else { + false + } + } + fn content_unchanged(&self, url: &Url, cha: &Cha) -> bool { let Some(lock) = &self.lock else { return false; @@ -138,29 +153,6 @@ impl Preview { } } -impl Preview { - // --- skip - #[inline] - pub fn arrow(&mut self, step: isize, mime: &str) -> bool { - let size = Provider::step_size(MimeKind::new(mime), step.unsigned_abs()); - let skip = if step < 0 { self.skip.saturating_sub(size) } else { self.skip + size }; - mem::replace(&mut self.skip, skip) != skip - } - - #[inline] - pub fn set_skip(&mut self, skip: usize) -> bool { mem::replace(&mut self.skip, skip) != skip } - - #[inline] - pub fn apply_bound(&mut self, upper: usize) -> bool { - if self.skip <= upper { - return false; - } - - self.skip = upper; - true - } -} - impl PreviewLock { #[inline] pub fn is_image(&self) -> bool { matches!(self.data, PreviewData::Image) } diff --git a/yazi-fm/src/app.rs b/yazi-fm/src/app.rs index f6523f9e..f1d25f9a 100644 --- a/yazi-fm/src/app.rs +++ b/yazi-fm/src/app.rs @@ -94,7 +94,7 @@ impl App { if !COLLISION.load(Ordering::Relaxed) { if collision { // Reload preview if collision is resolved - self.cx.manager.active_mut().preview.reset(); + self.cx.manager.active_mut().preview.reset_image(); self.cx.manager.peek(0); } return Ok(()); diff --git a/yazi-plugin/src/bindings/active.rs b/yazi-plugin/src/bindings/active.rs index 0a81bdfb..1823009a 100644 --- a/yazi-plugin/src/bindings/active.rs +++ b/yazi-plugin/src/bindings/active.rs @@ -125,8 +125,8 @@ impl<'a, 'b> Active<'a, 'b> { .lock .as_ref() .filter(|l| l.is_folder()) - .and_then(|l| tab.history(&l.url)) - .and_then(|f| self.folder(f, Some((f.offset, MANAGER.layout.preview_height()))).ok()), + .and_then(|l| tab.history(&l.url).map(|f| (l, f))) + .and_then(|(l, f)| self.folder(f, Some((l.skip, MANAGER.layout.preview_height()))).ok()), )?; Ok(ud)