-
Notifications
You must be signed in to change notification settings - Fork 527
/
Copy pathmove_.rs
58 lines (51 loc) · 1.47 KB
/
move_.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
use unicode_width::UnicodeWidthStr;
use yazi_shared::{event::{Cmd, Data}, render};
use crate::input::{op::InputOp, snap::InputSnap, Input};
pub struct Opt {
step: isize,
in_operating: bool,
}
impl From<Cmd> for Opt {
fn from(c: Cmd) -> Self {
Self {
step: c.first().and_then(Data::as_isize).unwrap_or(0),
in_operating: c.bool("in-operating"),
}
}
}
impl From<isize> for Opt {
fn from(step: isize) -> Self { Self { step, in_operating: false } }
}
impl Input {
pub fn move_(&mut self, opt: impl Into<Opt>) {
let opt = opt.into() as Opt;
let snap = self.snap();
if opt.in_operating && snap.op == InputOp::None {
return;
}
render!(self.handle_op(
if opt.step <= 0 {
snap.cursor.saturating_sub(opt.step.unsigned_abs())
} else {
snap.count().min(snap.cursor + opt.step as usize)
},
false,
));
let (limit, snap) = (self.limit(), self.snap_mut());
let offset = InputSnap::find_window_backward(&snap.value, snap.cursor, limit / 2)
.start
.min(InputSnap::find_window_backward(&snap.value, snap.value.chars().count(), limit).start);
if snap.offset != offset {
snap.offset = offset;
} else if snap.value.is_empty() {
snap.offset = 0;
} else {
let delta = snap.mode.delta();
let s = snap.slice(snap.offset..snap.cursor + delta);
if s.width() >= limit {
let s = s.chars().rev().collect::<String>();
snap.offset = snap.cursor - InputSnap::find_window(&s, 0, limit).end.saturating_sub(delta);
}
}
}
}