Skip to content

Commit 292d37c

Browse files
authored
refactor: simplify cursor repositioning (#3040)
1 parent 41b00c8 commit 292d37c

25 files changed

Lines changed: 206 additions & 161 deletions

File tree

yazi-actor/src/context.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,11 @@ impl<'a> Ctx<'a> {
8888
#[inline]
8989
pub fn hovered_folder(&self) -> Option<&Folder> { self.tab().hovered_folder() }
9090

91+
#[inline]
92+
pub fn hovered_folder_mut(&mut self) -> Option<&mut Folder> {
93+
self.tab_mut().hovered_folder_mut()
94+
}
95+
9196
#[inline]
9297
pub fn tasks(&self) -> &Tasks { &self.tasks }
9398

yazi-actor/src/mgr/arrow.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ impl Actor for Arrow {
2424
*items = (start.min(end)..=end.max(start)).collect();
2525
}
2626

27-
act!(mgr:hover, cx, None)?;
27+
act!(mgr:hover, cx)?;
2828
act!(mgr:peek, cx)?;
2929
act!(mgr:watch, cx)?;
3030

yazi-actor/src/mgr/cd.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ impl Actor for Cd {
5959
}
6060

6161
err!(Pubsub::pub_after_cd(tab.id, tab.cwd()));
62+
act!(mgr:hidden, cx)?;
63+
act!(mgr:sort, cx)?;
6264
act!(mgr:hover, cx)?;
6365
act!(mgr:refresh, cx)?;
6466
succ!(render!());

yazi-actor/src/mgr/filter_do.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,10 @@ impl Actor for FilterDo {
1717
let filter = if opt.query.is_empty() { None } else { Some(Filter::new(&opt.query, opt.case)?) };
1818

1919
let hovered = cx.hovered().map(|f| f.urn_owned());
20-
if cx.current_mut().files.set_filter(filter) {
21-
cx.current_mut().repos(hovered.as_ref());
22-
}
20+
cx.current_mut().files.set_filter(filter);
2321

24-
if cx.hovered().map(|f| f.urn()) != hovered.as_ref().map(|u| u.as_urn()) {
25-
act!(mgr:hover, cx)?;
22+
if cx.hovered().map(|f| f.urn()) != hovered.as_deref() {
23+
act!(mgr:hover, cx, hovered)?;
2624
act!(mgr:peek, cx)?;
2725
act!(mgr:watch, cx)?;
2826
}

yazi-actor/src/mgr/hidden.rs

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
use anyhow::Result;
2-
use yazi_macro::{act, succ};
2+
use yazi_core::tab::Folder;
3+
use yazi_fs::FolderStage;
4+
use yazi_macro::{act, render, render_and, succ};
35
use yazi_parser::mgr::HiddenOpt;
46
use yazi_shared::event::Data;
57

@@ -13,21 +15,39 @@ impl Actor for Hidden {
1315
const NAME: &str = "hidden";
1416

1517
fn act(cx: &mut Ctx, opt: Self::Options) -> Result<Data> {
16-
let tab = cx.tab_mut();
17-
tab.pref.show_hidden = opt.state.unwrap_or(!tab.pref.show_hidden);
18-
19-
let hovered = tab.hovered().map(|f| f.url_owned());
20-
tab.apply_files_attrs();
18+
let state = opt.state.bool(cx.tab().pref.show_hidden);
19+
cx.tab_mut().pref.show_hidden = state;
20+
21+
let hovered = cx.hovered().map(|f| f.urn_owned());
22+
let apply = |f: &mut Folder| {
23+
if f.stage == FolderStage::Loading {
24+
render!();
25+
false
26+
} else {
27+
f.files.set_show_hidden(state);
28+
render_and!(f.files.catchup_revision())
29+
}
30+
};
31+
32+
// Apply to CWD and parent
33+
if let (a, Some(b)) = (apply(cx.current_mut()), cx.parent_mut().map(apply))
34+
&& (a | b)
35+
{
36+
act!(mgr:hover, cx)?;
37+
act!(mgr:update_paged, cx)?;
38+
}
2139

22-
if hovered.as_ref() != tab.hovered().map(|f| &f.url) {
23-
act!(mgr:hover, cx, hovered)?;
40+
// Apply to hovered
41+
if let Some(h) = cx.hovered_folder_mut()
42+
&& apply(h)
43+
{
44+
render!(h.repos(None));
45+
act!(mgr:peek, cx, true)?;
46+
} else if hovered.as_deref() != cx.hovered().map(|f| f.urn()) {
2447
act!(mgr:peek, cx)?;
2548
act!(mgr:watch, cx)?;
26-
} else if tab.hovered().is_some_and(|f| f.is_dir()) {
27-
act!(mgr:peek, cx, true)?;
2849
}
2950

30-
act!(mgr:update_paged, cx)?;
31-
succ!();
51+
succ!()
3252
}
3353
}

yazi-actor/src/mgr/hover.rs

Lines changed: 16 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use anyhow::Result;
22
use yazi_dds::Pubsub;
3-
use yazi_macro::{act, err, render, succ};
4-
use yazi_parser::mgr::{HoverDoOpt, HoverOpt};
3+
use yazi_macro::{err, render, succ, tab};
4+
use yazi_parser::mgr::HoverOpt;
55
use yazi_shared::event::Data;
66

77
use crate::{Actor, Ctx};
@@ -14,39 +14,27 @@ impl Actor for Hover {
1414
const NAME: &str = "hover";
1515

1616
fn act(cx: &mut Ctx, opt: Self::Options) -> Result<Data> {
17-
if let Some(u) = opt.url {
18-
act!(mgr:hover_do, cx, u)?;
19-
} else {
20-
cx.current_mut().arrow(0);
21-
}
22-
23-
// Publish through DDS
24-
let tab = cx.tab();
25-
err!(Pubsub::pub_after_hover(tab.id, tab.hovered().map(|h| &h.url)));
26-
succ!();
27-
}
28-
}
29-
30-
// --- Do
31-
pub struct HoverDo;
17+
let tab = tab!(cx);
3218

33-
impl Actor for HoverDo {
34-
type Options = HoverDoOpt;
35-
36-
const NAME: &str = "hover_do";
37-
38-
fn act(cx: &mut Ctx, opt: Self::Options) -> Result<Data> {
39-
// Hover on the file
40-
if let Some(u) = opt.url.strip_prefix(cx.cwd()) {
41-
render!(cx.current_mut().hover(u));
19+
// Parent should always track CWD
20+
if let Some(p) = &mut tab.parent {
21+
render!(p.repos(tab.current.url.strip_prefix(&p.url)));
4222
}
4323

24+
// Repos CWD
25+
tab.current.repos(opt.urn.as_deref());
26+
4427
// Turn on tracing
45-
if cx.hovered().is_some_and(|h| h.url == opt.url) {
28+
if let (Some(h), Some(u)) = (tab.hovered(), opt.urn)
29+
&& *h.urn() == u
30+
{
4631
// `hover(Some)` occurs after user actions, such as create, rename, reveal, etc.
4732
// At this point, it's intuitive to track the location of the file regardless.
48-
cx.current_mut().trace = Some(opt.url.urn_owned());
33+
tab.current.trace = Some(u.to_owned());
4934
}
35+
36+
// Publish through DDS
37+
err!(Pubsub::pub_after_hover(tab.id, tab.hovered().map(|h| &h.url)));
5038
succ!();
5139
}
5240
}

yazi-actor/src/mgr/refresh.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,13 @@ impl Actor for Refresh {
2121
execute!(TTY.writer(), SetTitle(s)).ok();
2222
}
2323

24-
cx.tab_mut().apply_files_attrs();
25-
2624
if let Some(p) = cx.parent() {
2725
cx.mgr.watcher.trigger_dirs(&[cx.current(), p]);
2826
} else {
2927
cx.mgr.watcher.trigger_dirs(&[cx.current()]);
3028
}
3129

32-
act!(mgr:peek, cx, false)?;
30+
act!(mgr:peek, cx)?;
3331
act!(mgr:watch, cx)?;
3432
act!(mgr:update_paged, cx)?;
3533

yazi-actor/src/mgr/reveal.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,12 @@ impl Actor for Reveal {
2626
// If the child is not hovered, which means it doesn't exist,
2727
// create a dummy file
2828
if !opt.no_dummy && tab.hovered().is_none_or(|f| &child != f.urn()) {
29-
let op = FilesOp::Creating(parent, vec![File::from_dummy(opt.target.clone(), None)]);
29+
let op = FilesOp::Creating(parent, vec![File::from_dummy(opt.target, None)]);
3030
tab.current.update_pub(tab.id, op);
3131
}
3232

3333
// Now, we can safely hover on the target
34-
act!(mgr:hover, cx, Some(opt.target))?;
34+
act!(mgr:hover, cx, Some(child))?;
3535

3636
act!(mgr:peek, cx)?;
3737
act!(mgr:watch, cx)?;

yazi-actor/src/mgr/search.rs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -107,11 +107,15 @@ impl Actor for SearchStop {
107107
handle.abort();
108108
}
109109

110-
if tab.cwd().is_search() {
111-
let rep = tab.history.remove_or(&tab.cwd().to_regular());
112-
drop(mem::replace(&mut tab.current, rep));
113-
act!(mgr:refresh, cx)?;
110+
if !tab.cwd().is_search() {
111+
succ!();
114112
}
115-
succ!();
113+
114+
let rep = tab.history.remove_or(&tab.cwd().to_regular());
115+
drop(mem::replace(&mut tab.current, rep));
116+
117+
act!(mgr:hidden, cx)?;
118+
act!(mgr:sort, cx)?;
119+
act!(mgr:refresh, cx)
116120
}
117121
}

yazi-actor/src/mgr/sort.rs

Lines changed: 39 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
use anyhow::Result;
2-
use yazi_macro::{act, succ};
2+
use yazi_core::tab::Folder;
3+
use yazi_fs::{FilesSorter, FolderStage};
4+
use yazi_macro::{act, render, render_and, succ};
35
use yazi_parser::mgr::SortOpt;
46
use yazi_shared::event::Data;
57

@@ -13,25 +15,44 @@ impl Actor for Sort {
1315
const NAME: &str = "sort";
1416

1517
fn act(cx: &mut Ctx, opt: Self::Options) -> Result<Data> {
16-
let mut new = cx.tab().pref.clone();
17-
new.sort_by = opt.by.unwrap_or(new.sort_by);
18-
new.sort_reverse = opt.reverse.unwrap_or(new.sort_reverse);
19-
new.sort_dir_first = opt.dir_first.unwrap_or(new.sort_dir_first);
20-
new.sort_sensitive = opt.sensitive.unwrap_or(new.sort_sensitive);
21-
new.sort_translit = opt.translit.unwrap_or(new.sort_translit);
22-
23-
if new == cx.tab().pref {
24-
succ!();
18+
let pref = &mut cx.tab_mut().pref;
19+
pref.sort_by = opt.by.unwrap_or(pref.sort_by);
20+
pref.sort_reverse = opt.reverse.unwrap_or(pref.sort_reverse);
21+
pref.sort_dir_first = opt.dir_first.unwrap_or(pref.sort_dir_first);
22+
pref.sort_sensitive = opt.sensitive.unwrap_or(pref.sort_sensitive);
23+
pref.sort_translit = opt.translit.unwrap_or(pref.sort_translit);
24+
25+
let sorter = FilesSorter::from(&*pref);
26+
let hovered = cx.hovered().map(|f| f.urn_owned());
27+
let apply = |f: &mut Folder| {
28+
if f.stage == FolderStage::Loading {
29+
render!();
30+
false
31+
} else {
32+
f.files.set_sorter(sorter);
33+
render_and!(f.files.catchup_revision())
34+
}
35+
};
36+
37+
// Apply to CWD and parent
38+
if let (a, Some(b)) = (apply(cx.current_mut()), cx.parent_mut().map(apply))
39+
&& (a | b)
40+
{
41+
act!(mgr:hover, cx)?;
42+
act!(mgr:update_paged, cx)?;
43+
cx.tasks.prework_sorted(&cx.mgr.tabs[cx.tab].current.files);
2544
}
2645

27-
cx.tab_mut().pref = new;
28-
cx.tab_mut().apply_files_attrs();
29-
act!(mgr:hover, cx)?;
30-
31-
cx.tasks.prework_sorted(&cx.mgr.tabs[cx.tab].current.files);
32-
act!(mgr:peek, cx)?;
33-
act!(mgr:watch, cx)?;
34-
act!(mgr:update_paged, cx)?;
46+
// Apply to hovered
47+
if let Some(h) = cx.hovered_folder_mut()
48+
&& apply(h)
49+
{
50+
render!(h.repos(None));
51+
act!(mgr:peek, cx, true)?;
52+
} else if hovered.as_deref() != cx.hovered().map(|f| f.urn()) {
53+
act!(mgr:peek, cx)?;
54+
act!(mgr:watch, cx)?;
55+
}
3556

3657
succ!();
3758
}

0 commit comments

Comments
 (0)