hac_core/text_object/
cursor.rs1use std::ops::Add;
2
3#[derive(Debug, Default, Clone, PartialEq)]
4pub struct Cursor {
5 row: usize,
6 col: usize,
7 snapback_col: usize,
8 col_offset: usize,
11 row_offset: usize,
12}
13
14impl Cursor {
15 pub fn move_left(&mut self, amount: usize) {
16 self.col = self.col.saturating_sub(amount);
17 self.snapback_col = self.col;
18 }
19
20 pub fn move_down(&mut self, amount: usize) {
21 self.row = self.row.add(amount);
22 }
23
24 pub fn move_up(&mut self, amount: usize) {
25 self.row = self.row.saturating_sub(amount);
26 }
27
28 pub fn move_right(&mut self, amount: usize) {
29 self.col = self.col.add(amount);
30 self.snapback_col = self.col;
31 }
32
33 pub fn move_to_newline_start(&mut self) {
34 self.col = 0;
35 self.snapback_col = 0;
36 self.row = self.row.add(1);
37 }
38
39 pub fn move_to_line_start(&mut self) {
40 self.col = 0;
41 self.snapback_col = 0;
42 }
43
44 pub fn move_to_line_end(&mut self, line_len: usize) {
45 self.col = line_len.saturating_sub(1);
46 self.snapback_col = self.col;
47 }
48
49 pub fn move_to_col(&mut self, col: usize) {
50 self.col = col;
51 self.snapback_col = col;
52 }
53
54 pub fn move_to_row(&mut self, row: usize) {
55 self.row = row;
56 }
57
58 pub fn row(&self) -> usize {
59 self.row
60 }
61
62 pub fn col(&self) -> usize {
63 self.col
64 }
65
66 pub fn row_with_offset(&self) -> usize {
67 self.row + self.row_offset
68 }
69
70 pub fn col_with_offset(&self) -> usize {
71 self.col + self.col_offset
72 }
73
74 pub fn set_col_offset(&mut self, offset: usize) {
75 self.col_offset = offset;
76 }
77
78 pub fn set_row_offset(&mut self, offset: usize) {
79 self.row_offset = offset;
80 }
81
82 pub fn readable_position(&self) -> (usize, usize) {
83 (self.col.add(1), self.row.add(1))
84 }
85
86 pub fn maybe_snap_to_col(&mut self, line_len: usize) {
94 match line_len.saturating_sub(1).cmp(&self.col) {
95 std::cmp::Ordering::Less => {
96 if self.snapback_col.eq(&self.col) {
97 self.snapback_col = self.col;
98 }
99 self.col = line_len.saturating_sub(1);
100 }
101 std::cmp::Ordering::Greater => {
102 self.col = self.snapback_col.min(line_len.saturating_sub(1))
103 }
104 std::cmp::Ordering::Equal => {}
106 }
107 }
108}