spyne_text/buffer/
cursor.rs1use std::marker::PhantomData;
2
3use crate::buffer::TextBuffer;
4
5pub struct Cursor<T: TextBuffer> {
6 buffer: PhantomData<T>,
7 position: usize
8}
9
10impl<T: TextBuffer> Cursor<T> {
11 pub fn new() -> Self {
12 Self {
13 buffer: PhantomData,
14 position: 0
15 }
16 }
17
18 pub fn position(&self) -> usize {
19 self.position
20 }
21
22 pub fn move_left(&mut self, offset: usize) -> usize {
23 if self.position.checked_sub(offset) != None {
24 self.position -= offset;
25 }
26
27 self.position
28 }
29
30 pub fn move_right(&mut self, offset: usize, len: usize) -> usize {
31 if self.position + offset <= len {
32 self.position += offset;
33 }
34
35 self.position
36 }
37
38 pub fn home(&mut self) {
39 self.position = 0;
40 }
41
42 pub fn end(&mut self, len: usize) {
43 self.position = len;
44 }
45
46 pub fn backspace(&mut self, buffer: &mut impl TextBuffer) {
47 if self.position != 0 {
48 self.position -= 1;
49 buffer.delete(self.position, 1);
50 }
51 }
52
53 pub fn delete(&self, buffer: &mut impl TextBuffer) {
54 if self.position != buffer.len() {
55 buffer.delete(self.position, 1);
56 }
57 }
58
59 pub fn move_to_next_word_end(&mut self, buffer: &impl TextBuffer) {
60 let line_to_end = buffer.read(self.position, buffer.len());
61 let mut in_word = false;
62 let mut offset = buffer.len() - self.position;
63 for (i, char) in line_to_end.enumerate() {
64 if char.is_alphanumeric() {
65 in_word = true;
66 continue;
67 }
68 if in_word {
69 offset = i;
70 break;
71 }
72 }
73
74 self.move_right(offset, buffer.len());
75 }
76
77 pub fn move_to_prev_word_start(&mut self, buffer: &impl TextBuffer) {
78 let line_from_start = buffer.read(0, self.position);
79 let mut in_word = false;
80 let mut offset = self.position;
81 for (i, char) in line_from_start.rev().enumerate() {
82 if char.is_alphanumeric() {
83 in_word = true;
84 continue;
85 }
86 if in_word {
87 offset = i;
88 break;
89 }
90 }
91
92 self.move_left(offset);
93 }
94
95 pub fn delete_prev_word(&mut self, buffer: &mut impl TextBuffer) {
96 let line_from_start = buffer.read(0, self.position);
97 let mut in_word = false;
98 let mut offset = self.position;
99 for (i, char) in line_from_start.rev().enumerate() {
100 if *char != ' ' {
101 in_word = true;
102 continue;
103 }
104 if in_word {
105 offset = i;
106 break;
107 }
108 }
109
110 self.move_left(offset);
111 buffer.delete(self.position, offset);
112 }
113
114 pub fn delete_next_word(&mut self, buffer: &mut impl TextBuffer) {
115 let line_to_end = buffer.read(self.position, buffer.len());
116 let mut in_word = false;
117 let mut offset = buffer.len() - self.position;
118 for (i, char) in line_to_end.enumerate() {
119 if *char != ' ' {
120 in_word = true;
121 continue;
122 }
123 if in_word {
124 offset = i;
125 break;
126 }
127 }
128
129 buffer.delete(self.position, offset);
130 }
131
132 pub fn delete_to_line_start(&mut self, buffer: &mut impl TextBuffer) {
133 buffer.delete(0, self.position);
134 self.position = 0;
135 }
136
137 pub fn delete_to_line_end(&self, buffer: &mut impl TextBuffer) {
138 buffer.delete(self.position, buffer.len() - self.position);
139 }
140
141 }