mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-25 08:41:05 +00:00
..
This commit is contained in:
parent
e5ba8e7d27
commit
169543b799
15 changed files with 80 additions and 54 deletions
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ pub struct Files {
|
|||
hidden: Vec<File>,
|
||||
items: Vec<File>,
|
||||
ticket: u64,
|
||||
version: u64,
|
||||
pub(crate) revision: u64,
|
||||
|
||||
pub sizes: BTreeMap<Url, u64>,
|
||||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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<Option<Url>> for Opt {
|
||||
fn from(url: Option<Url>) -> 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();
|
||||
|
|
|
|||
|
|
@ -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<usize>,
|
||||
force: bool,
|
||||
only_if: Option<Url>,
|
||||
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<bool> 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<Opt>) -> 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
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,7 +28,6 @@ impl Manager {
|
|||
self.watcher.trigger_dirs(&[self.cwd()]);
|
||||
}
|
||||
|
||||
Self::_hover(None);
|
||||
false
|
||||
self.hover(None)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ impl Manager {
|
|||
tasks.preload_affected(paged, &updates);
|
||||
|
||||
self.mimetype.extend(updates);
|
||||
self.peek(());
|
||||
self.peek(false);
|
||||
true
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
use yazi_adaptor::ADAPTOR;
|
||||
use yazi_config::BOOT;
|
||||
use yazi_shared::fs::Url;
|
||||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -14,9 +14,9 @@ pub enum FinderCase {
|
|||
}
|
||||
|
||||
pub struct Finder {
|
||||
query: Regex,
|
||||
matched: BTreeMap<Url, u8>,
|
||||
version: u64,
|
||||
query: Regex,
|
||||
matched: BTreeMap<Url, u8>,
|
||||
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<isize> {
|
||||
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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(())
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue