yazi_widgets/input/
snaps.rs

1use std::mem;
2
3use super::InputSnap;
4
5#[derive(PartialEq, Eq)]
6pub struct InputSnaps {
7	idx:      usize,
8	versions: Vec<InputSnap>,
9	current:  InputSnap,
10}
11
12impl Default for InputSnaps {
13	fn default() -> Self {
14		Self {
15			idx:      0,
16			versions: vec![InputSnap::new(String::new(), false, 0)],
17			current:  InputSnap::new(String::new(), false, 0),
18		}
19	}
20}
21
22impl InputSnaps {
23	pub fn new(value: String, obscure: bool, limit: usize) -> Self {
24		let current = InputSnap::new(value, obscure, limit);
25		Self { idx: 0, versions: vec![current.clone()], current }
26	}
27
28	pub(super) fn tag(&mut self, limit: usize) -> bool {
29		if self.versions.len() <= self.idx {
30			return false;
31		}
32
33		// Sync *current* cursor position to the *last* version:
34		// 		Save offset/cursor/ect. of the *current* as the last version,
35		// 		while keeping the *last* value unchanged.
36		let value = mem::take(&mut self.versions[self.idx].value);
37		self.versions[self.idx] = self.current.clone();
38		self.versions[self.idx].value = value;
39		self.versions[self.idx].resize(limit);
40
41		// If the *current* value is the same as the *last* version
42		if self.versions[self.idx].value == self.current.value {
43			return false;
44		}
45
46		self.versions.truncate(self.idx + 1);
47		self.versions.push(self.current().clone());
48		self.idx += 1;
49		true
50	}
51
52	pub(super) fn undo(&mut self) -> bool {
53		if self.idx == 0 {
54			return false;
55		}
56
57		self.idx -= 1;
58		self.current = self.versions[self.idx].clone();
59		true
60	}
61
62	pub(super) fn redo(&mut self) -> bool {
63		if self.idx + 1 >= self.versions.len() {
64			return false;
65		}
66
67		self.idx += 1;
68		self.current = self.versions[self.idx].clone();
69		true
70	}
71}
72
73impl InputSnaps {
74	#[inline]
75	pub fn current(&self) -> &InputSnap { &self.current }
76
77	#[inline]
78	pub(super) fn current_mut(&mut self) -> &mut InputSnap { &mut self.current }
79}