Refactor the move command

This commit is contained in:
sxyazi 2025-01-04 10:33:49 +08:00
parent def6a3f4f5
commit 74adbaca73
No known key found for this signature in database

View file

@ -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<Self, Self::Error> {
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<CmdCow> 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<isize> 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<Self, Self::Err> {
Ok(match s {
"bol" => Self::Bol,
"eol" => Self::Eol,
"first-char" => Self::FirstChar,
s => Self::Offset(s.parse().map_err(|_| ())?),
})
}
}
impl From<isize> for OptStep {
fn from(value: isize) -> Self { Self::Offset(value) }
}
impl TryFrom<&Data> for OptStep {
type Error = ();
fn try_from(value: &Data) -> Result<Self, Self::Error> {
match value {
Data::String(s) => s.parse().map_err(|_| ()),
Data::Integer(i) => Ok(Self::from(*i as isize)),
_ => Err(()),
}
}
}