From 74adbaca73689a77f8490fe1c0bb171b76191a4e Mon Sep 17 00:00:00 2001 From: sxyazi Date: Sat, 4 Jan 2025 10:33:49 +0800 Subject: [PATCH] Refactor the `move` command --- yazi-core/src/input/commands/move_.rs | 132 +++++++++++++------------- 1 file changed, 65 insertions(+), 67 deletions(-) diff --git a/yazi-core/src/input/commands/move_.rs b/yazi-core/src/input/commands/move_.rs index 03e5fa71..80d83360 100644 --- a/yazi-core/src/input/commands/move_.rs +++ b/yazi-core/src/input/commands/move_.rs @@ -1,3 +1,5 @@ +use std::str::FromStr; + use unicode_width::UnicodeWidthStr; use yazi_macro::render; use yazi_shared::event::{CmdCow, Data}; @@ -9,52 +11,16 @@ struct Opt { in_operating: bool, } -enum OptStep { - Offset(isize), - Bol, - Eol, - FirstChar, - LastChar, -} - -impl TryFrom<&Data> for OptStep { - type Error = (); - - fn try_from(data: &Data) -> Result { - if let Some(offset) = data.as_isize() { - return Ok(OptStep::Offset(offset)); - }; - if let Some(string) = data.as_str() { - if let Ok(offset) = string.parse() { - return Ok(OptStep::Offset(offset)); - }; - match string.as_ref() { - "bol" => return Ok(OptStep::Bol), - "eol" => return Ok(OptStep::Eol), - "first-char" => return Ok(OptStep::FirstChar), - "last-char" => return Ok(OptStep::LastChar), - _ => (), - } - } - Err(()) - } -} - impl From for Opt { fn from(c: CmdCow) -> Self { Self { - step: c.get(0).unwrap().try_into().unwrap_or(OptStep::Offset(0)), + step: c.get(0).and_then(|d| d.try_into().ok()).unwrap_or_default(), in_operating: c.bool("in-operating"), } } } impl From for Opt { - fn from(step: isize) -> Self { - Self { - step: OptStep::Offset(step), - in_operating: false, - } - } + fn from(step: isize) -> Self { Self { step: step.into(), in_operating: false } } } impl Input { @@ -65,35 +31,7 @@ impl Input { return; } - let position = match opt.step { - OptStep::Offset(offset) => - if offset <= 0 { - snap.cursor.saturating_sub(offset.unsigned_abs()) - } else { - snap.count().min(snap.cursor + offset as usize) - }, - OptStep::Bol => 0, - OptStep::Eol => snap.count(), - OptStep::FirstChar => snap - .value - .chars() - .enumerate() - .filter(|(_, ch)| !ch.is_whitespace()) - .map(|(i, _)| i) - .next() - .unwrap_or(0), - OptStep::LastChar => snap - .value - .chars() - .rev() - .enumerate() - .filter(|(_, ch)| !ch.is_whitespace()) - .map(|(i, _)| i) - .next() - .unwrap_or(0), - }; - - render!(self.handle_op(position, false)); + render!(self.handle_op(opt.step.cursor(snap), false)); let (limit, snap) = (self.limit(), self.snap_mut()); if snap.offset > snap.cursor { @@ -110,3 +48,63 @@ impl Input { } } } + +// --- Step +enum OptStep { + Offset(isize), + Bol, + Eol, + FirstChar, +} + +impl OptStep { + fn cursor(self, snap: &InputSnap) -> usize { + match self { + Self::Offset(n) => { + if n <= 0 { + snap.cursor.saturating_add_signed(n) + } else { + snap.count().min(snap.cursor + n as usize) + } + } + Self::Bol => 0, + Self::Eol => snap.count(), + Self::FirstChar => { + snap.value.chars().enumerate().find(|(_, c)| !c.is_whitespace()).map_or(0, |(i, _)| i) + } + } + } +} + +impl Default for OptStep { + fn default() -> Self { 0.into() } +} + +impl FromStr for OptStep { + type Err = (); + + fn from_str(s: &str) -> Result { + Ok(match s { + "bol" => Self::Bol, + "eol" => Self::Eol, + "first-char" => Self::FirstChar, + s => Self::Offset(s.parse().map_err(|_| ())?), + }) + } +} + +impl From for OptStep { + fn from(value: isize) -> Self { Self::Offset(value) } +} + +impl TryFrom<&Data> for OptStep { + type Error = (); + + fn try_from(value: &Data) -> Result { + match value { + Data::String(s) => s.parse().map_err(|_| ()), + Data::Integer(i) => Ok(Self::from(*i as isize)), + _ => Err(()), + } + } +}