feat: more complete hovered file cursor tracking

This commit is contained in:
sxyazi 2025-01-18 22:00:15 +08:00
parent e37d8d6bc1
commit b8663c0ac3
No known key found for this signature in database
4 changed files with 25 additions and 36 deletions

View file

@ -56,10 +56,10 @@ impl Manager {
} }
// Turn on tracing // Turn on tracing
if self.current_or(tab).hovered().is_some_and(|f| url == f.url) { if self.current_or(tab).hovered().is_some_and(|h| h.url == url) {
// `hover(Some)` occurs after user actions, such as create, rename, reveal, etc. // `hover(Some)` occurs after user actions, such as create, rename, reveal, etc.
// At this point, it's intuitive to track the location of this file regardless. // At this point, it's intuitive to track the location of this file regardless.
self.current_or_mut(tab).tracing = true; self.current_or_mut(tab).trace = Some(url.urn_owned());
} }
} }
} }

View file

@ -70,16 +70,12 @@ impl Manager {
} }
fn update_current(tab: &mut Tab, op: Cow<FilesOp>, tasks: &Tasks) { fn update_current(tab: &mut Tab, op: Cow<FilesOp>, tasks: &Tasks) {
let hovered = tab.hovered().filter(|_| tab.current.tracing).map(|h| h.urn_owned());
let calc = !matches!(*op, FilesOp::Size(..) | FilesOp::Deleting(..)); let calc = !matches!(*op, FilesOp::Size(..) | FilesOp::Deleting(..));
let foreign = matches!(op, Cow::Borrowed(_)); let foreign = matches!(op, Cow::Borrowed(_));
if !tab.current.update_pub(tab.id, op.into_owned()) { if !tab.current.update_pub(tab.id, op.into_owned()) {
return; return;
} } else if foreign {
tab.current.repos(hovered.as_ref().map(|u| u.as_urn()));
if foreign {
return; return;
} }
@ -109,11 +105,11 @@ impl Manager {
|(p, n)| matches!(*op, FilesOp::Deleting(ref parent, ref urns) if *parent == p && urns.contains(n)), |(p, n)| matches!(*op, FilesOp::Deleting(ref parent, ref urns) if *parent == p && urns.contains(n)),
); );
let folder = tab.history.entry(op.cwd().clone()).or_insert_with(|| Folder::from(op.cwd())); tab
let hovered = folder.hovered().filter(|_| folder.tracing).map(|h| h.urn_owned()); .history
if folder.update_pub(tab.id, op.into_owned()) { .entry(op.cwd().clone())
folder.repos(hovered.as_ref().map(|u| u.as_urn())); .or_insert_with(|| Folder::from(op.cwd()))
} .update_pub(tab.id, op.into_owned());
if leave { if leave {
tab.leave(()); tab.leave(());

View file

@ -4,7 +4,7 @@ use yazi_config::{LAYOUT, MANAGER};
use yazi_dds::Pubsub; use yazi_dds::Pubsub;
use yazi_fs::{Cha, File, Files, FilesOp, FolderStage, Step}; use yazi_fs::{Cha, File, Files, FilesOp, FolderStage, Step};
use yazi_proxy::ManagerProxy; use yazi_proxy::ManagerProxy;
use yazi_shared::{Id, url::{Url, Urn}}; use yazi_shared::{Id, url::{Url, Urn, UrnBuf}};
pub struct Folder { pub struct Folder {
pub url: Url, pub url: Url,
@ -16,7 +16,7 @@ pub struct Folder {
pub cursor: usize, pub cursor: usize,
pub page: usize, pub page: usize,
pub tracing: bool, pub trace: Option<UrnBuf>,
} }
impl Default for Folder { impl Default for Folder {
@ -29,7 +29,7 @@ impl Default for Folder {
offset: Default::default(), offset: Default::default(),
cursor: Default::default(), cursor: Default::default(),
page: Default::default(), page: Default::default(),
tracing: Default::default(), trace: Default::default(),
} }
} }
} }
@ -73,7 +73,7 @@ impl Folder {
FilesOp::Upserting(_, files) => self.files.update_upserting(files), FilesOp::Upserting(_, files) => self.files.update_upserting(files),
} }
self.arrow(0); self.repos(self.trace.clone().as_ref().map(|u| u.as_urn()));
(stage, revision) != (self.stage, self.files.revision) (stage, revision) != (self.stage, self.files.revision)
} }
@ -90,15 +90,14 @@ impl Folder {
pub fn arrow(&mut self, step: impl Into<Step>) -> bool { pub fn arrow(&mut self, step: impl Into<Step>) -> bool {
let step = step.into() as Step; let step = step.into() as Step;
let mut b = if self.files.is_empty() { let mut b = if self.files.is_empty() {
(self.cursor, self.offset, self.tracing) = (0, 0, false); (mem::take(&mut self.cursor), mem::take(&mut self.offset)) != (0, 0)
false
} else if step.is_positive() { } else if step.is_positive() {
self.next(step) self.next(step)
} else { } else {
self.prev(step) self.prev(step)
}; };
self.tracing |= b; self.trace = self.hovered().filter(|_| b).map(|h| h.urn_owned()).or(mem::take(&mut self.trace));
b |= self.squeeze_offset(); b |= self.squeeze_offset();
self.sync_page(false); self.sync_page(false);
@ -107,7 +106,7 @@ impl Folder {
pub fn hover(&mut self, urn: &Urn) -> bool { pub fn hover(&mut self, urn: &Urn) -> bool {
if self.hovered().map(|h| h.urn()) == Some(urn) { if self.hovered().map(|h| h.urn()) == Some(urn) {
return false; return self.arrow(0);
} }
let new = self.files.position(urn).unwrap_or(self.cursor) as isize; let new = self.files.position(urn).unwrap_or(self.cursor) as isize;

View file

@ -123,22 +123,16 @@ impl Tab {
return render!(); return render!();
} }
let hovered = f.hovered().filter(|_| f.tracing).map(|h| h.urn_owned());
f.files.set_show_hidden(self.pref.show_hidden); f.files.set_show_hidden(self.pref.show_hidden);
f.files.set_sorter(<_>::from(&self.pref)); f.files.set_sorter(<_>::from(&self.pref));
render!(f.files.catchup_revision()); render!(f.files.catchup_revision());
render!(f.repos(hovered.as_ref().map(|u| u.as_urn()))); render!(f.repos(f.trace.clone().as_ref().map(|u| u.as_urn())));
}; };
apply(&mut self.current); apply(&mut self.current);
if let Some(parent) = &mut self.parent { if let Some(parent) = &mut self.parent {
apply(parent); apply(parent);
// The parent should always track the CWD
parent.hover(self.current.url.urn());
parent.tracing = parent.hovered().map(|h| &h.url) == Some(&self.current.url);
} }
self self