yazi_widgets/input/actor/
move.rs1use anyhow::Result;
2use yazi_macro::{render, succ};
3use yazi_shared::data::Data;
4
5use crate::input::{Input, op::InputOp, parser::MoveOpt, snap::InputSnap};
6
7impl Input {
8 pub fn r#move(&mut self, opt: MoveOpt) -> Result<Data> {
9 let snap = self.snap();
10 if opt.in_operating && snap.op == InputOp::None {
11 succ!();
12 }
13
14 let o_cur = snap.cursor;
15 render!(self.handle_op(opt.step.add(&snap.value, snap.cursor), false));
16 let n_cur = self.snap().cursor;
17
18 let (limit, snap) = (self.limit, self.snap_mut());
19 if snap.value.is_empty() {
20 succ!(snap.offset = 0);
21 }
22
23 let (o_off, scrolloff) = (snap.offset, 5.min(limit / 2));
24 snap.offset = if n_cur <= o_cur {
25 let it = snap.slice(0..n_cur).chars().rev().map(|c| if snap.obscure { '•' } else { c });
26 let pad = InputSnap::find_window(it, 0, scrolloff).end;
27
28 if n_cur >= o_off { snap.offset.min(n_cur - pad) } else { n_cur - pad }
29 } else {
30 let count = snap.count();
31
32 let it = snap.slice(n_cur..count).chars().map(|c| if snap.obscure { '•' } else { c });
33 let pad = InputSnap::find_window(it, 0, scrolloff + snap.mode.delta()).end;
34
35 let it = snap.slice(0..n_cur + pad).chars().rev().map(|c| if snap.obscure { '•' } else { c });
36 let max = InputSnap::find_window(it, 0, limit).end;
37
38 if snap.width(o_off..n_cur) < limit as u16 {
39 snap.offset.max(n_cur + pad - max)
40 } else {
41 n_cur + pad - max
42 }
43 };
44
45 if n_cur != o_cur {
46 self.flush_trigger(false);
47 }
48 succ!();
49 }
50}