From ca96c5bd987c6c6a32df6e38c99dcf40f493035f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=89=E5=92=B2=E9=9B=85=20=C2=B7=20Misaki=20Masa?= Date: Mon, 5 May 2025 01:46:39 +0800 Subject: [PATCH] feat: increase the granularity of `back`/`forward` history navigation to make its behavior more sensible (#2720) --- yazi-core/src/tab/commands/back.rs | 7 ++++++- yazi-core/src/tab/commands/cd.rs | 28 ++++++++++++++++++++++++--- yazi-core/src/tab/commands/enter.rs | 6 +++++- yazi-core/src/tab/commands/forward.rs | 7 ++++++- yazi-core/src/tab/commands/leave.rs | 2 +- yazi-core/src/tab/commands/reveal.rs | 2 +- 6 files changed, 44 insertions(+), 8 deletions(-) diff --git a/yazi-core/src/tab/commands/back.rs b/yazi-core/src/tab/commands/back.rs index 15f3e146..f7f7ddc3 100644 --- a/yazi-core/src/tab/commands/back.rs +++ b/yazi-core/src/tab/commands/back.rs @@ -4,6 +4,11 @@ use crate::tab::Tab; impl Tab { pub fn back(&mut self, _: CmdCow) { - self.backstack.shift_backward().cloned().map(|u| self.cd(u)); + if self.current.url.is_regular() { + self.backstack.push(&self.current.url); + } + if let Some(u) = self.backstack.shift_backward().cloned() { + self.cd((u, super::cd::OptSource::Back)); + } } } diff --git a/yazi-core/src/tab/commands/cd.rs b/yazi-core/src/tab/commands/cd.rs index 3f881200..4350b51c 100644 --- a/yazi-core/src/tab/commands/cd.rs +++ b/yazi-core/src/tab/commands/cd.rs @@ -13,12 +13,14 @@ use crate::tab::Tab; struct Opt { target: Url, + source: OptSource, interactive: bool, } impl From for Opt { fn from(mut c: CmdCow) -> Self { Self { + source: OptSource::Cd, interactive: c.bool("interactive"), ..Self::from(c.take_first_url().unwrap_or_default()) } @@ -26,11 +28,15 @@ impl From for Opt { } impl From for Opt { - fn from(mut target: Url) -> Self { + fn from(target: Url) -> Self { Self::from((target, OptSource::Cd)) } +} + +impl From<(Url, OptSource)> for Opt { + fn from((mut target, source): (Url, OptSource)) -> Self { if target.is_regular() { target = Url::from(expand_path(&target)); } - Self { target, interactive: false } + Self { target, source, interactive: false } } } @@ -67,7 +73,7 @@ impl Tab { } // Backstack - if opt.target.is_regular() { + if opt.source.big_jump() && opt.target.is_regular() { self.backstack.push(&opt.target); } @@ -108,3 +114,19 @@ impl Tab { }); } } + +// --- OptSource +#[derive(Clone, Copy, PartialEq, Eq)] +pub(super) enum OptSource { + Cd, + Reveal, + Enter, + Leave, + Forward, + Back, +} + +impl OptSource { + #[inline] + fn big_jump(self) -> bool { self == Self::Cd || self == Self::Reveal } +} diff --git a/yazi-core/src/tab/commands/enter.rs b/yazi-core/src/tab/commands/enter.rs index 751e3a9c..aeefe4b9 100644 --- a/yazi-core/src/tab/commands/enter.rs +++ b/yazi-core/src/tab/commands/enter.rs @@ -4,6 +4,10 @@ use crate::tab::Tab; impl Tab { pub fn enter(&mut self, _: CmdCow) { - self.hovered().filter(|h| h.is_dir()).map(|h| h.url.to_regular()).map(|u| self.cd(u)); + self + .hovered() + .filter(|h| h.is_dir()) + .map(|h| h.url.to_regular()) + .map(|u| self.cd((u, super::cd::OptSource::Enter))); } } diff --git a/yazi-core/src/tab/commands/forward.rs b/yazi-core/src/tab/commands/forward.rs index e6678965..aaefd99f 100644 --- a/yazi-core/src/tab/commands/forward.rs +++ b/yazi-core/src/tab/commands/forward.rs @@ -4,6 +4,11 @@ use crate::tab::Tab; impl Tab { pub fn forward(&mut self, _: CmdCow) { - self.backstack.shift_forward().cloned().map(|u| self.cd(u)); + if self.current.url.is_regular() { + self.backstack.push(&self.current.url); + } + if let Some(u) = self.backstack.shift_forward().cloned() { + self.cd((u, super::cd::OptSource::Forward)); + } } } diff --git a/yazi-core/src/tab/commands/leave.rs b/yazi-core/src/tab/commands/leave.rs index 993578d5..db4a3c40 100644 --- a/yazi-core/src/tab/commands/leave.rs +++ b/yazi-core/src/tab/commands/leave.rs @@ -19,6 +19,6 @@ impl Tab { .and_then(|h| h.url.parent_url()) .filter(|u| u != self.cwd()) .or_else(|| self.cwd().parent_url()) - .map(|u| self.cd(u.into_regular())); + .map(|u| self.cd((u.into_regular(), super::cd::OptSource::Leave))); } } diff --git a/yazi-core/src/tab/commands/reveal.rs b/yazi-core/src/tab/commands/reveal.rs index c7025fb4..0e55faaa 100644 --- a/yazi-core/src/tab/commands/reveal.rs +++ b/yazi-core/src/tab/commands/reveal.rs @@ -30,7 +30,7 @@ impl Tab { return; }; - self.cd(parent.clone()); + self.cd((parent.clone(), super::cd::OptSource::Reveal)); self.current.hover(child.as_urn()); if !opt.no_dummy && self.hovered().is_none_or(|f| &child != f.urn()) {