feat: fine-grained peek and watch (#2655)

This commit is contained in:
三咲雅 · Misaki Masa 2025-04-21 21:04:31 +08:00 committed by GitHub
parent 8327826217
commit 7169e19ff0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
16 changed files with 60 additions and 30 deletions

View file

@ -1,5 +1,3 @@
use std::collections::HashSet;
use yazi_dds::Pubsub;
use yazi_macro::render;
use yazi_shared::{Id, event::{CmdCow, Data}, url::{Url, Urn}};
@ -29,21 +27,8 @@ impl Mgr {
self.current_or_mut(opt.tab).arrow(0);
}
// Repeek
self.peek(false);
// Refresh watcher
let mut to_watch = HashSet::with_capacity(3 * self.tabs.len());
for tab in self.tabs.iter() {
to_watch.insert(tab.cwd());
if let Some(ref p) = tab.parent {
to_watch.insert(&p.url);
}
if let Some(h) = tab.hovered().filter(|&h| h.is_dir()) {
to_watch.insert(&h.url);
}
}
self.watcher.watch(to_watch);
self.watch(());
// Publish through DDS
Pubsub::pub_from_hover(self.active().id, self.hovered().map(|h| &h.url));

View file

@ -25,5 +25,6 @@ yazi_macro::mod_flat!(
update_paged
update_tasks
update_yanked
watch
yank
);

View file

@ -21,7 +21,8 @@ impl Mgr {
self.watcher.trigger_dirs(&[self.current()]);
}
self.hover(None);
self.watch(());
self.peek(false);
self.update_paged((), tasks);
tasks.prework_sorted(&self.current().files);

View file

@ -22,6 +22,7 @@ impl Mgr {
return;
};
let revision = self.current().files.revision;
let linked: Vec<_> = LINKED.read().from_dir(opt.op.cwd()).map(|u| opt.op.rebase(u)).collect();
for op in [opt.op].into_iter().chain(linked) {
self.yanked.apply_op(&op);
@ -29,7 +30,12 @@ impl Mgr {
}
render!(self.yanked.catchup_revision(false));
self.active_mut().apply_files_attrs();
if revision != self.current().files.revision {
self.active_mut().apply_files_attrs();
self.hover(None);
self.peek(false);
self.update_paged((), tasks);
}
}
fn update_tab(&mut self, op: FilesOp, tasks: &Tasks) {
@ -71,8 +77,6 @@ impl Mgr {
return;
}
self.hover(None); // Re-hover
self.update_paged((), tasks); // Update for paged files
if calc {
tasks.prework_sorted(&self.current().files);
}

View file

@ -20,7 +20,7 @@ impl From<()> for Opt {
impl Mgr {
pub fn update_paged(&mut self, opt: impl TryInto<Opt>, tasks: &Tasks) {
let Ok(opt) = opt.try_into() else {
let Ok(opt): Result<Opt, _> = opt.try_into() else {
return;
};
@ -29,7 +29,9 @@ impl Mgr {
}
let targets = self.current().paginate(opt.page.unwrap_or(self.current().page));
tasks.fetch_paged(targets, &self.mimetype);
tasks.preload_paged(targets, &self.mimetype);
if !targets.is_empty() {
tasks.fetch_paged(targets, &self.mimetype);
tasks.preload_paged(targets, &self.mimetype);
}
}
}

View file

@ -0,0 +1,31 @@
use std::collections::HashSet;
use yazi_shared::event::CmdCow;
use crate::mgr::Mgr;
struct Opt;
impl From<CmdCow> for Opt {
fn from(_: CmdCow) -> Self { Self }
}
impl From<()> for Opt {
fn from((): ()) -> Self { Self }
}
impl Mgr {
#[yazi_codegen::command]
pub fn watch(&mut self, _: Opt) {
let mut to_watch = HashSet::with_capacity(3 * self.tabs.len());
for tab in self.tabs.iter() {
to_watch.insert(tab.cwd());
if let Some(ref p) = tab.parent {
to_watch.insert(&p.url);
}
if let Some(h) = tab.hovered().filter(|&h| h.is_dir()) {
to_watch.insert(&h.url);
}
}
self.watcher.watch(to_watch);
}
}

View file

@ -37,6 +37,7 @@ impl Tab {
}
MgrProxy::hover(None, self.id);
MgrProxy::peek(false);
render!();
}
}

View file

@ -28,6 +28,7 @@ impl Tab {
self.current.repos(hovered.as_ref());
if self.hovered().map(|f| f.urn()) != hovered.as_ref().map(|u| u.as_urn()) {
MgrProxy::hover(None, self.id);
MgrProxy::peek(false);
}
render!();

View file

@ -16,6 +16,7 @@ impl Tab {
if hovered.as_ref() != self.hovered().map(|f| &f.url) {
MgrProxy::hover(hovered, self.id);
MgrProxy::peek(false);
} else if self.hovered().is_some_and(|f| f.is_dir()) {
MgrProxy::peek(true);
}

View file

@ -30,7 +30,9 @@ impl Tab {
};
self.cd(parent.clone());
// TODO
FilesOp::Creating(parent, vec![File::from_dummy(opt.target.clone(), None)]).emit();
MgrProxy::hover(Some(opt.target), self.id);
MgrProxy::peek(false);
}
}

View file

@ -21,6 +21,7 @@ impl Tab {
self.apply_files_attrs();
MgrProxy::hover(None, self.id);
MgrProxy::peek(false);
MgrProxy::update_paged();
tasks.prework_sorted(&self.current.files);

View file

@ -20,6 +20,7 @@ impl App {
self.cx.current_mut().sync_page(true);
self.cx.mgr.hover(None);
self.cx.mgr.peek(false);
self.cx.mgr.parent_mut().map(|f| f.arrow(0));
}
}

View file

@ -78,6 +78,7 @@ impl<'a> Executor<'a> {
on!(MGR, update_paged, &self.app.cx.tasks);
on!(MGR, update_yanked);
on!(MGR, hover);
on!(MGR, watch);
on!(MGR, peek);
on!(MGR, seek);
on!(MGR, spot);

View file

@ -16,8 +16,6 @@ pub fn compose(lua: &Lua) -> mlua::Result<Value> {
b"Line" => super::Line::compose(lua)?,
b"List" => super::List::compose(lua)?,
b"Pad" => super::Pad::compose(lua, true)?,
// TODO: deprecate this
b"Padding" => super::Pad::compose(lua, false)?,
b"Pos" => super::Pos::compose(lua)?,
b"Rect" => super::Rect::compose(lua)?,
b"Row" => super::Row::compose(lua)?,

View file

@ -71,11 +71,6 @@ impl UserData for Rect {
fn add_methods<M: mlua::UserDataMethods<Self>>(methods: &mut M) {
methods.add_method("pad", |_, me, pad: Pad| Ok(me.pad(pad)));
// TODO: deprecate this
methods.add_method("padding", |lua, me, pad: Pad| {
crate::deprecate!(lua, "The `padding()` method of `ui.Rect` has been deprecated, please use `pad()` instead, in your {}");
Ok(me.pad(pad))
});
methods.add_method("contains", |_, me, Rect(rect)| Ok(me.contains(rect.into())));
}
}

View file

@ -21,6 +21,11 @@ impl MgrProxy {
emit!(Call(Cmd::args("mgr:hover", &url.map_or_else(Vec::new, |u| vec![u])).with("tab", tab)));
}
#[inline]
pub fn watch() {
emit!(Call(Cmd::new("mgr:watch")));
}
#[inline]
pub fn refresh() {
emit!(Call(Cmd::new("mgr:refresh")));