yazi_core/tab/
backstack.rs1use yazi_shared::url::{Url, UrlBuf};
2
3#[derive(Default)]
4pub struct Backstack {
5 cursor: usize,
6 stack: Vec<UrlBuf>,
7}
8
9impl Backstack {
10 pub fn push(&mut self, url: Url) {
11 if self.stack.is_empty() {
12 self.stack.push(url.to_owned());
13 return;
14 }
15
16 if self.stack[self.cursor] == url {
17 return;
18 }
19
20 self.cursor += 1;
21 if self.cursor == self.stack.len() {
22 self.stack.push(url.to_owned());
23 } else {
24 self.stack[self.cursor] = url.to_owned();
25 self.stack.truncate(self.cursor + 1);
26 }
27
28 if self.stack.len() > 60 {
30 let start = self.cursor.saturating_sub(30);
31 self.stack.drain(..start);
32 self.cursor -= start;
33 }
34 }
35
36 pub fn current(&self) -> Option<&UrlBuf> { self.stack.get(self.cursor) }
37
38 pub fn shift_backward(&mut self) -> Option<&UrlBuf> {
39 if self.cursor > 0 {
40 self.cursor -= 1;
41 Some(&self.stack[self.cursor])
42 } else {
43 None
44 }
45 }
46
47 pub fn shift_forward(&mut self) -> Option<&UrlBuf> {
48 if self.cursor + 1 >= self.stack.len() {
49 None
50 } else {
51 self.cursor += 1;
52 Some(&self.stack[self.cursor])
53 }
54 }
55}
56
57#[cfg(test)]
58mod tests {
59 use super::*;
60
61 #[test]
62 fn test_backstack() {
63 let mut bs: Backstack = Backstack::default();
64 assert_eq!(bs.shift_forward(), None);
65
66 bs.push(Url::regular("1"));
67 assert_eq!(bs.stack[bs.cursor], Url::regular("1"));
68
69 bs.push(Url::regular("2"));
70 bs.push(Url::regular("3"));
71 assert_eq!(bs.stack[bs.cursor], Url::regular("3"));
72
73 assert_eq!(bs.shift_backward().unwrap(), Url::regular("2"));
74 assert_eq!(bs.shift_backward().unwrap(), Url::regular("1"));
75 assert_eq!(bs.shift_backward(), None);
76 assert_eq!(bs.shift_backward(), None);
77 assert_eq!(bs.stack[bs.cursor], Url::regular("1"));
78 assert_eq!(bs.shift_forward().unwrap(), Url::regular("2"));
79 assert_eq!(bs.shift_forward().unwrap(), Url::regular("3"));
80 assert_eq!(bs.shift_forward(), None);
81
82 bs.shift_backward();
83 bs.push(Url::regular("4"));
84
85 assert_eq!(bs.stack[bs.cursor], Url::regular("4"));
86 assert_eq!(bs.shift_forward(), None);
87 assert_eq!(bs.shift_backward().unwrap(), Url::regular("2"));
88 }
89}