feat: increase the granularity of back/forward history navigation to make its behavior more sensible

This commit is contained in:
sxyazi 2025-05-05 01:45:08 +08:00
parent c53865788a
commit fc85074d4f
No known key found for this signature in database
6 changed files with 35 additions and 8 deletions

View file

@ -4,6 +4,6 @@ use crate::tab::Tab;
impl Tab {
pub fn back(&mut self, _: CmdCow) {
self.backstack.shift_backward().cloned().map(|u| self.cd(u));
self.backstack.shift_backward().cloned().map(|u| self.cd((u, super::cd::OptSource::Back)));
}
}

View file

@ -1,5 +1,6 @@
use std::{mem, time::Duration};
use serde::Deserialize;
use tokio::{fs, pin};
use tokio_stream::{StreamExt, wrappers::UnboundedReceiverStream};
use yazi_config::popup::InputCfg;
@ -13,12 +14,14 @@ use crate::tab::Tab;
struct Opt {
target: Url,
source: OptSource,
interactive: bool,
}
impl From<CmdCow> 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 +29,15 @@ impl From<CmdCow> for Opt {
}
impl From<Url> 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 +74,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 +115,19 @@ impl Tab {
});
}
}
// --- OptSource
#[derive(Clone, Copy, PartialEq, Eq)]
pub(super) enum OptSource {
Cd,
Enter,
Leave,
Forward,
Back,
Reveal,
}
impl OptSource {
#[inline]
fn big_jump(self) -> bool { self != Self::Enter && self != Self::Leave }
}

View file

@ -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)));
}
}

View file

@ -4,6 +4,6 @@ use crate::tab::Tab;
impl Tab {
pub fn forward(&mut self, _: CmdCow) {
self.backstack.shift_forward().cloned().map(|u| self.cd(u));
self.backstack.shift_forward().cloned().map(|u| self.cd((u, super::cd::OptSource::Forward)));
}
}

View file

@ -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)));
}
}

View file

@ -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()) {