mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-21 23:01:05 +00:00
fix: peek down directories
This commit is contained in:
parent
63b7491ad7
commit
56b0611f7c
6 changed files with 67 additions and 75 deletions
24
README.md
24
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!
|
||||
|
|
|
|||
|
|
@ -25,10 +25,10 @@ impl Manager {
|
|||
pub fn hover(&mut self, opt: impl Into<Opt>) -> 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();
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<usize>) {
|
||||
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) }
|
||||
|
|
|
|||
|
|
@ -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(());
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue