diff --git a/yazi-core/src/help/commands/arrow.rs b/yazi-core/src/help/commands/arrow.rs index 3fc71b8a..e966998b 100644 --- a/yazi-core/src/help/commands/arrow.rs +++ b/yazi-core/src/help/commands/arrow.rs @@ -1,30 +1,31 @@ +use yazi_fs::Step; use yazi_macro::render; -use yazi_shared::event::{CmdCow, Data}; +use yazi_shared::event::CmdCow; use crate::help::Help; struct Opt { - step: isize, + step: Step, } impl From for Opt { - fn from(c: CmdCow) -> Self { Self { step: c.first().and_then(Data::as_isize).unwrap_or(0) } } + fn from(c: CmdCow) -> Self { + Self { step: c.first().and_then(|d| d.try_into().ok()).unwrap_or_default() } + } } + impl From for Opt { - fn from(step: isize) -> Self { Self { step } } + fn from(n: isize) -> Self { Self { step: n.into() } } } impl Help { #[yazi_codegen::command] pub fn arrow(&mut self, opt: Opt) { - let max = self.bindings.len().saturating_sub(1); - self.offset = self.offset.min(max); - self.cursor = self.cursor.min(max); - - if opt.step > 0 { - self.next(opt.step as usize); + let new = opt.step.add(self.cursor, self.bindings.len(), Self::limit()); + if new > self.cursor { + self.next(new); } else { - self.prev(opt.step.unsigned_abs()); + self.prev(new); } } diff --git a/yazi-core/src/spot/commands/arrow.rs b/yazi-core/src/spot/commands/arrow.rs index 0223d4b8..7a9e5203 100644 --- a/yazi-core/src/spot/commands/arrow.rs +++ b/yazi-core/src/spot/commands/arrow.rs @@ -1,15 +1,18 @@ +use yazi_fs::Step; use yazi_macro::render; use yazi_proxy::MgrProxy; -use yazi_shared::event::{CmdCow, Data}; +use yazi_shared::event::CmdCow; use crate::spot::Spot; struct Opt { - step: isize, + step: Step, } impl From for Opt { - fn from(c: CmdCow) -> Self { Self { step: c.first().and_then(Data::as_isize).unwrap_or(0) } } + fn from(c: CmdCow) -> Self { + Self { step: c.first().and_then(|d| d.try_into().ok()).unwrap_or_default() } + } } impl Spot { @@ -17,12 +20,12 @@ impl Spot { pub fn arrow(&mut self, opt: Opt) { let Some(lock) = &mut self.lock else { return }; + let new = opt.step.add(self.skip, lock.len().unwrap_or(u16::MAX as _), 0); let Some(old) = lock.selected() else { - let new = self.skip.saturating_add_signed(opt.step); return MgrProxy::spot(Some(new)); }; - lock.select(Some(old.saturating_add_signed(opt.step))); + lock.select(Some(new)); let new = lock.selected().unwrap(); self.skip = new; diff --git a/yazi-core/src/spot/commands/swipe.rs b/yazi-core/src/spot/commands/swipe.rs index 2e9069f5..fe624bec 100644 --- a/yazi-core/src/spot/commands/swipe.rs +++ b/yazi-core/src/spot/commands/swipe.rs @@ -1,14 +1,16 @@ +use std::borrow::Cow; + use yazi_proxy::{MgrProxy, TabProxy}; -use yazi_shared::event::{CmdCow, Data}; +use yazi_shared::event::CmdCow; use crate::spot::Spot; struct Opt { - step: isize, + step: Cow<'static, str>, } impl From for Opt { - fn from(c: CmdCow) -> Self { Self { step: c.first().and_then(Data::as_isize).unwrap_or(0) } } + fn from(mut c: CmdCow) -> Self { Self { step: c.take_first_str().unwrap_or_default() } } } impl Spot { diff --git a/yazi-plugin/src/elements/table.rs b/yazi-plugin/src/elements/table.rs index d31d9d04..24f72851 100644 --- a/yazi-plugin/src/elements/table.rs +++ b/yazi-plugin/src/elements/table.rs @@ -82,6 +82,9 @@ impl Table { table.render(self.area.transform(trans), buf, &mut self.state); } + #[inline] + pub(crate) fn len(&self) -> usize { self.rows.len() } + pub(crate) fn select(&mut self, idx: Option) { self .state diff --git a/yazi-plugin/src/utils/spot.rs b/yazi-plugin/src/utils/spot.rs index 26a43e90..a9323a19 100644 --- a/yazi-plugin/src/utils/spot.rs +++ b/yazi-plugin/src/utils/spot.rs @@ -32,6 +32,9 @@ impl TryFrom for SpotLock { } impl SpotLock { + #[inline] + pub fn len(&self) -> Option { Some(self.table()?.len()) } + pub fn select(&mut self, idx: Option) { if let Some(t) = self.table_mut() { t.select(idx); diff --git a/yazi-proxy/src/tab.rs b/yazi-proxy/src/tab.rs index ef846588..7c3c2dc4 100644 --- a/yazi-proxy/src/tab.rs +++ b/yazi-proxy/src/tab.rs @@ -17,8 +17,8 @@ impl TabProxy { } #[inline] - pub fn arrow(step: isize) { - emit!(Call(Cmd::args("mgr:arrow", &[step]))); + pub fn arrow(step: impl AsRef) { + emit!(Call(Cmd::args("mgr:arrow", &[step.as_ref()]))); } #[inline]