summaryrefslogtreecommitdiff
path: root/src/widgets/luaeditor/buffer.rs
diff options
context:
space:
mode:
authorNathan Reiner <nathan@nathanreiner.xyz>2024-07-25 00:40:37 +0200
committerNathan Reiner <nathan@nathanreiner.xyz>2024-07-25 00:40:37 +0200
commit58b305b9f6d13007d2ea62775054c95177f81092 (patch)
tree2123cb5379aa69476b1e549e0bcacc08d67fba71 /src/widgets/luaeditor/buffer.rs
first sketch
Diffstat (limited to 'src/widgets/luaeditor/buffer.rs')
-rw-r--r--src/widgets/luaeditor/buffer.rs134
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)
+ }
+}