summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorNathan Reiner <nathan@nathanreiner.xyz>2024-07-25 14:50:03 +0200
committerNathan Reiner <nathan@nathanreiner.xyz>2024-07-25 14:50:03 +0200
commit21c8643173e87691b47ae9860c6cb095a6ea68b2 (patch)
tree54d4103810e609a0feb8cc9c165fa48a0805644b /src
parent0f13518aa4be5ea5a10127b959bb88e3a0df892e (diff)
luaeditor add autoindent
Diffstat (limited to 'src')
-rw-r--r--src/widgets/luaeditor/buffer.rs44
1 files changed, 39 insertions, 5 deletions
diff --git a/src/widgets/luaeditor/buffer.rs b/src/widgets/luaeditor/buffer.rs
index bdbee8d..6a954ed 100644
--- a/src/widgets/luaeditor/buffer.rs
+++ b/src/widgets/luaeditor/buffer.rs
@@ -12,7 +12,7 @@ impl Buffer {
pub fn new() -> Self {
Self {
lines: Vec::new(),
- cursor: Cursor::new().with_position(0, 0).with_max(0, 0)
+ cursor: Cursor::new().with_position(0, 0).with_max(0, 0),
}
}
@@ -30,6 +30,22 @@ impl Buffer {
self.refresh_buffer_max();
}
+ fn end_balance(&self, level: usize) -> isize {
+ let str = "\t".repeat(level);
+ let start_count = self.lines.iter().filter(|s| {
+ s.starts_with(&(str.clone() + "if "))
+ || s.starts_with(&(str.clone() + "for "))
+ || s.starts_with(&(str.clone() + "while "))
+ || (s.starts_with(&str) && s.contains("function(") && s.ends_with(")"))
+ }).count();
+
+ let end_count = self.lines.iter().filter(
+ |s| s.starts_with(&(str.clone() + "end ")) || **s == (str.clone() + "end")
+ ).count();
+
+ (end_count as isize) - (start_count as isize)
+ }
+
pub fn insert(&mut self, c: char) {
match c {
'\n' => {
@@ -39,13 +55,31 @@ impl Buffer {
(a.to_string(), b.to_string())
};
+ let indent_normalized = a.replace(" ", "\t");
+ let indent = indent_normalized.len() - indent_normalized.trim_start().len();
+ let l = a.trim();
+ let insert_end = (l.starts_with("if ") && l.ends_with(" then"))
+ || ((l.starts_with("for ") || l.starts_with("while ")) && l.ends_with(" do"))
+ || (l.contains("function(") && l.ends_with(")"));
+
+ let extra_indent = if insert_end { 1 } else { 0 };
+
{
*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()
+ self.lines
+ .insert(self.cursor().y(), "\t".repeat(indent + extra_indent) + &b);
+
+ if insert_end && self.end_balance(indent) < 0 {
+ self.lines
+ .insert(self.cursor().y() + 1, "\t".repeat(indent) + "end");
+ }
+
+ self.refresh_max();
+ self.cursor
+ .move_checked(CursorMove::Right(indent + extra_indent));
}
_ => {
let x = self.cursor().x();
@@ -65,7 +99,8 @@ impl Buffer {
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.cursor
+ .move_checked(CursorMove::Jump((new_x, self.cursor.y())));
self.refresh_buffer_max()
} else {
@@ -74,7 +109,6 @@ impl Buffer {
self.refresh_line_max();
self.cursor.move_checked(CursorMove::Left(1));
}
-
}
pub fn line(&self, index: usize) -> Option<&String> {