yazi_widgets/input/commands/
move.rs

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