diff options
| author | Nathan Reiner <nathan@nathanreiner.xyz> | 2024-07-25 00:40:37 +0200 |
|---|---|---|
| committer | Nathan Reiner <nathan@nathanreiner.xyz> | 2024-07-25 00:40:37 +0200 |
| commit | 58b305b9f6d13007d2ea62775054c95177f81092 (patch) | |
| tree | 2123cb5379aa69476b1e549e0bcacc08d67fba71 /src/widgets/luaeditor/buffer.rs | |
first sketch
Diffstat (limited to 'src/widgets/luaeditor/buffer.rs')
| -rw-r--r-- | src/widgets/luaeditor/buffer.rs | 134 |
1 files changed, 134 insertions, 0 deletions
diff --git a/src/widgets/luaeditor/buffer.rs b/src/widgets/luaeditor/buffer.rs new file mode 100644 index 0000000..bdbee8d --- /dev/null +++ b/src/widgets/luaeditor/buffer.rs @@ -0,0 +1,134 @@ +use std::str::FromStr; + +use super::cursor::{Cursor, CursorMove}; + +#[derive(Default, Debug)] +pub struct Buffer { + lines: Vec<String>, + cursor: Cursor, +} + +impl Buffer { + pub fn new() -> Self { + Self { + lines: Vec::new(), + cursor: Cursor::new().with_position(0, 0).with_max(0, 0) + } + } + + fn refresh_line_max(&mut self) { + self.cursor + .set_x_max(self.lines[self.cursor.y() as usize].len()) + } + + fn refresh_buffer_max(&mut self) { + self.cursor.set_y_max(self.lines.len() - 1); + } + + fn refresh_max(&mut self) { + self.refresh_line_max(); + self.refresh_buffer_max(); + } + + pub fn insert(&mut self, c: char) { + match c { + '\n' => { + let (a, b) = { + let line = self.current_line(); + let (a, b) = line.split_at(self.cursor.x()); + (a.to_string(), b.to_string()) + }; + + { + *self.current_line_mut() = a; + } + self.cursor.move_unchecked(CursorMove::Down(1)); + self.cursor.move_unchecked(CursorMove::Begin); + self.lines.insert(self.cursor().y(), b); + self.refresh_max() + } + _ => { + let x = self.cursor().x(); + self.current_line_mut().insert(x, c); + self.refresh_line_max(); + self.cursor.move_checked(CursorMove::Right(1)); + } + } + } + + pub fn delete(&mut self) { + if self.cursor.is_at_start() && !self.cursor.is_at_top() { + let old_line = self.current_line_mut().clone(); + self.lines.remove(self.cursor.y()); + self.cursor.move_checked(CursorMove::Up(1)); + self.refresh_line_max(); + + let new_x = self.current_line().len(); + self.current_line_mut().push_str(&old_line); + self.cursor.move_checked(CursorMove::Jump((new_x, self.cursor.y()))); + + self.refresh_buffer_max() + } else { + let x = self.cursor.x() - 1; + self.current_line_mut().remove(x); + self.refresh_line_max(); + self.cursor.move_checked(CursorMove::Left(1)); + } + + } + + pub fn line(&self, index: usize) -> Option<&String> { + self.lines.get(index) + } + + fn line_mut(&mut self, index: usize) -> Option<&mut String> { + self.lines.get_mut(index) + } + + pub fn current_line(&self) -> &String { + self.line(self.cursor.y() as usize).unwrap() + } + + fn current_line_mut(&mut self) -> &mut String { + self.line_mut(self.cursor.y() as usize).unwrap() + } + + pub fn cursor(&self) -> &Cursor { + &self.cursor + } + + pub fn move_cursor(&mut self, m: CursorMove) { + match m { + CursorMove::Up(_) + | CursorMove::Down(_) + | CursorMove::Top + | CursorMove::Bottom + | CursorMove::Jump(_) => { + self.cursor.move_checked(m); + self.cursor.set_x_max(self.current_line().len()); + self.cursor.correct_cursor_position(); + } + CursorMove::Left(_) | CursorMove::Right(_) | CursorMove::Begin | CursorMove::End => { + self.cursor.move_checked(m) + } + } + } + + pub fn lines(&self) -> &Vec<String> { + &self.lines + } +} + +impl FromStr for Buffer { + type Err = (); + + fn from_str(s: &str) -> Result<Self, Self::Err> { + let lines: Vec<_> = s.lines().map(|s| s.to_string()).collect(); + let mut buffer = Self::new(); + buffer.lines = lines; + + buffer.refresh_max(); + + Ok(buffer) + } +} |