Skip to main content

yazi_widgets/input/actor/
move.rs

1use 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}