fix: peek down directories

This commit is contained in:
sxyazi 2023-11-24 06:21:13 +08:00
parent 63b7491ad7
commit 56b0611f7c
No known key found for this signature in database
6 changed files with 67 additions and 75 deletions

View file

@ -31,18 +31,18 @@ https://github.com/sxyazi/yazi/assets/17523360/92ff23fa-0cd5-4f04-b387-894c12265
## Image Preview ## Image Preview
| Platform | Protocol | Support | | Platform | Protocol | Support |
| ----------------- | -------------------------------------------------------------------------------- | --------------------- | | ----------------- | ----------------------------------------------------------------------------------------------------- | --------------------- |
| kitty | [Terminal graphics protocol](https://sw.kovidgoyal.net/kitty/graphics-protocol/) | ✅ Built-in | | kitty | [Kitty unicode placeholders](https://sw.kovidgoyal.net/kitty/graphics-protocol/#unicode-placeholders) | ✅ Built-in |
| WezTerm | [Terminal graphics protocol](https://sw.kovidgoyal.net/kitty/graphics-protocol/) | ✅ Built-in | | Konsole | [Kitty old protocol](https://github.com/sxyazi/yazi/blob/main/yazi-adaptor/src/kitty_old.rs) | ✅ 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 |
| 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 | | 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 |
| 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 |
| 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 | | X11 / Wayland | Window system protocol | ☑️ Überzug++ required |
| Fallback | [Chafa](https://hpjansson.org/chafa/) | ☑️ Ü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. 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! That's relying on the `$TERM`, `$TERM_PROGRAM`, and `$XDG_SESSION_TYPE` variables, make sure you don't overwrite them by mistake!

View file

@ -25,10 +25,10 @@ impl Manager {
pub fn hover(&mut self, opt: impl Into<Opt>) -> bool { pub fn hover(&mut self, opt: impl Into<Opt>) -> bool {
// Hover on the file // Hover on the file
let opt = opt.into() as Opt; 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 // Re-peek
self.peek(0); b |= self.peek(0);
// Refresh watcher // Refresh watcher
let mut to_watch = BTreeSet::new(); let mut to_watch = BTreeSet::new();

View file

@ -54,12 +54,13 @@ impl Manager {
}; };
let (url, cha) = (hovered.url.clone(), hovered.cha); let (url, cha) = (hovered.url.clone(), hovered.cha);
if self.active().preview.same_url(&url) { if opt.upper_bound {
self.active_mut().preview.arrow(opt.step, &mime); self.active_mut().preview.arrow(0, &mime, Some(opt.step as usize));
} else if opt.upper_bound { } else if self.active().preview.same_url(&url) {
self.active_mut().preview.apply_bound(opt.step as usize); self.active_mut().preview.arrow(opt.step, &mime, None);
} else { } 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); 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()))) .map(|f| (f.offset, f.files.len().saturating_sub(MANAGER.layout.folder_height())))
.unwrap_or_default(); .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(); let in_chunks = folder.is_none();
self.active_mut().preview.set_skip(skip); if self.active().preview.same_url(&url) {
self.active_mut().preview.go_folder(url, in_chunks); self.active_mut().preview.arrow(opt.step, MIME_DIR, Some(bound));
false 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
}
} }
} }

View file

@ -37,7 +37,7 @@ impl Preview {
return; return;
} }
self.reset(); self.abort();
let (url, kind, skip) = (url.clone(), MimeKind::new(mime), self.skip); let (url, kind, skip) = (url.clone(), MimeKind::new(mime), self.skip);
self.handle = Some(tokio::spawn(async move { self.handle = Some(tokio::spawn(async move {
@ -54,7 +54,7 @@ impl Preview {
} }
pub fn go_folder(&mut self, url: Url, in_chunks: bool) { pub fn go_folder(&mut self, url: Url, in_chunks: bool) {
self.reset(); self.abort();
self.lock = Some(PreviewLock { self.lock = Some(PreviewLock {
url: url.clone(), url: url.clone(),
cha: None, cha: None,
@ -84,34 +84,49 @@ impl Preview {
})); }));
} }
pub fn reset(&mut self) -> bool { pub fn arrow(&mut self, step: isize, mime: &str, upper: Option<usize>) {
self.handle.take().map(|h| h.abort()); let size = Provider::step_size(MimeKind::new(mime), step.unsigned_abs());
Highlighter::abort(); self.skip = if step < 0 { self.skip.saturating_sub(size) } else { self.skip + size };
ADAPTOR.image_hide(MANAGER.layout.image_rect()).ok();
let Some(ref lock) = self.lock else { if let Some(upper) = upper {
return false; self.skip = self.skip.min(upper);
};
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;
} }
self.reset();
true
} }
#[inline] #[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 { pub fn same_url(&self, url: &Url) -> bool {
matches!(self.lock, Some(ref lock) if lock.url == *url) 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 { fn content_unchanged(&self, url: &Url, cha: &Cha) -> bool {
let Some(lock) = &self.lock else { let Some(lock) = &self.lock else {
return false; 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 { impl PreviewLock {
#[inline] #[inline]
pub fn is_image(&self) -> bool { matches!(self.data, PreviewData::Image) } pub fn is_image(&self) -> bool { matches!(self.data, PreviewData::Image) }

View file

@ -94,7 +94,7 @@ impl App {
if !COLLISION.load(Ordering::Relaxed) { if !COLLISION.load(Ordering::Relaxed) {
if collision { if collision {
// Reload preview if collision is resolved // 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); self.cx.manager.peek(0);
} }
return Ok(()); return Ok(());

View file

@ -125,8 +125,8 @@ impl<'a, 'b> Active<'a, 'b> {
.lock .lock
.as_ref() .as_ref()
.filter(|l| l.is_folder()) .filter(|l| l.is_folder())
.and_then(|l| tab.history(&l.url)) .and_then(|l| tab.history(&l.url).map(|f| (l, f)))
.and_then(|f| self.folder(f, Some((f.offset, MANAGER.layout.preview_height()))).ok()), .and_then(|(l, f)| self.folder(f, Some((l.skip, MANAGER.layout.preview_height()))).ok()),
)?; )?;
Ok(ud) Ok(ud)