Skip to main content

spyne_text/buffer/
cursor.rs

1use 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    // Implement yanking (kill) functions later
142}