summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Uko Kokņevičs2022-01-02 09:15:10 +0200
committerGravatar Uko Kokņevičs2022-01-02 09:15:10 +0200
commit676f89b28f86c9b64638790965844c1f77830254 (patch)
tree5f0a1ed3165848021de8a9cd8cc5e6e875c2404a
parentAdd <untab> (diff)
downloades-676f89b28f86c9b64638790965844c1f77830254.tar.gz
es-676f89b28f86c9b64638790965844c1f77830254.tar.xz
es-676f89b28f86c9b64638790965844c1f77830254.zip
Make <untab> actually do something
-rw-r--r--src/Buffer.zig44
-rw-r--r--src/Row.zig8
-rw-r--r--src/key_state.zig4
3 files changed, 39 insertions, 17 deletions
diff --git a/src/Buffer.zig b/src/Buffer.zig
index ce2212c..7f3043b 100644
--- a/src/Buffer.zig
+++ b/src/Buffer.zig
@@ -291,6 +291,14 @@ pub fn goToLine(self: *Buffer, editor: *Editor) !void {
291 } 291 }
292} 292}
293 293
294pub fn indent(self: *Buffer) !void {
295 if (self.config.hard_tabs) {
296 return self.insertChar('\t');
297 } else {
298 return self.insertNChars(' ', self.config.tab_stop - self.cx % self.config.tab_stop);
299 }
300}
301
294pub fn insertChar(self: *Buffer, char: u8) !void { 302pub fn insertChar(self: *Buffer, char: u8) !void {
295 if (self.cy == self.rows.items.len) { 303 if (self.cy == self.rows.items.len) {
296 try self.insertRow(self.rows.items.len, ""); 304 try self.insertRow(self.rows.items.len, "");
@@ -320,8 +328,8 @@ pub fn insertNewline(self: *Buffer) !void {
320 328
321 var row = &self.rows.items[self.cy]; 329 var row = &self.rows.items[self.cy];
322 330
323 const indentation = try row.indentation(self.allocator); 331 const indentation_size = row.indentationSize();
324 defer self.allocator.free(indentation); 332 const indentation = row.data.items[0..indentation_size];
325 333
326 try self.insertRow(self.cy + 1, indentation); 334 try self.insertRow(self.cy + 1, indentation);
327 row = &self.rows.items[self.cy]; 335 row = &self.rows.items[self.cy];
@@ -349,14 +357,6 @@ pub fn insertRow(self: *Buffer, at: usize, data: []const u8) !void {
349 self.dirty = true; 357 self.dirty = true;
350} 358}
351 359
352pub fn insertTab(self: *Buffer) !void {
353 if (self.config.hard_tabs) {
354 return self.insertChar('\t');
355 } else {
356 return self.insertNChars(' ', self.config.tab_stop - self.cx % self.config.tab_stop);
357 }
358}
359
360pub fn killLine(self: *Buffer) !void { 360pub fn killLine(self: *Buffer) !void {
361 return self.deleteRow(self.cy); 361 return self.deleteRow(self.cy);
362} 362}
@@ -537,6 +537,30 @@ pub fn selectSyntaxHighlighting(self: *Buffer) !void {
537 } 537 }
538} 538}
539 539
540pub fn unindent(self: *Buffer) !void {
541 if (self.cy == self.rows.items.len) {
542 return;
543 }
544
545 // Find the end of starting whitespace
546 const row = &self.rows.items[self.cy];
547 var indentation_size = row.indentationSize();
548 if (indentation_size == 0) {
549 return;
550 }
551
552 const indentation_rsize = row.cxToRx(self.config, indentation_size);
553 const desired_rsize = indentation_rsize - 1 - (indentation_rsize - 1) % self.config.tab_stop;
554 const desired_size = row.rxToCx(self.config, desired_rsize);
555
556 self.cx -= indentation_size - desired_size;
557
558 // TODO: ArrayList needs orderedRemoveNItems
559 while (indentation_size > desired_size) : (indentation_size -= 1) {
560 try row.deleteChar(self, desired_size);
561 }
562}
563
540fn printWithLeftPadding( 564fn printWithLeftPadding(
541 allocator: Allocator, 565 allocator: Allocator,
542 writer: anytype, 566 writer: anytype,
diff --git a/src/Row.zig b/src/Row.zig
index a47be6a..d1de2aa 100644
--- a/src/Row.zig
+++ b/src/Row.zig
@@ -83,10 +83,7 @@ pub fn deleteChar(self: *Row, buf: *Buffer, at: usize) !void {
83 try self.update(buf); 83 try self.update(buf);
84} 84}
85 85
86pub fn indentation(self: Row, allocator: Allocator) ![]u8 { 86pub fn indentationSize(self: Row) usize {
87 var str = ArrayList(u8).init(allocator);
88 defer str.deinit();
89
90 var idx: usize = 0; 87 var idx: usize = 0;
91 while (idx < self.data.items.len) : (idx += 1) { 88 while (idx < self.data.items.len) : (idx += 1) {
92 if (!std.ascii.isBlank(self.data.items[idx])) { 89 if (!std.ascii.isBlank(self.data.items[idx])) {
@@ -94,8 +91,7 @@ pub fn indentation(self: Row, allocator: Allocator) ![]u8 {
94 } 91 }
95 } 92 }
96 93
97 try str.appendSlice(self.data.items[0..idx]); 94 return idx;
98 return str.toOwnedSlice();
99} 95}
100 96
101pub fn insertChar(self: *Row, buf: *Buffer, at: usize, char: u8) !void { 97pub fn insertChar(self: *Row, buf: *Buffer, at: usize, char: u8) !void {
diff --git a/src/key_state.zig b/src/key_state.zig
index 2cb9988..818dded 100644
--- a/src/key_state.zig
+++ b/src/key_state.zig
@@ -96,7 +96,7 @@ pub fn defaultState(editor: *Editor, buf: *Buffer, key: Key) Error!void {
96 // TODO: C-h help 96 // TODO: C-h help
97 97
98 // tab 98 // tab
99 Key.ctrl('i') => try buf.insertTab(), 99 Key.ctrl('i') => try buf.indent(),
100 // line feed 100 // line feed
101 Key.ctrl('j') => try buf.insertNewline(), 101 Key.ctrl('j') => try buf.insertNewline(),
102 Key.ctrl('k') => try buf.killLine(), 102 Key.ctrl('k') => try buf.killLine(),
@@ -122,6 +122,8 @@ pub fn defaultState(editor: *Editor, buf: *Buffer, key: Key) Error!void {
122 }, 122 },
123 123
124 // ========== <*> ========== 124 // ========== <*> ==========
125 Key.untab => try buf.unindent(),
126
125 else => { 127 else => {
126 if (@enumToInt(key) <= @enumToInt(Key.max_char)) { 128 if (@enumToInt(key) <= @enumToInt(Key.max_char)) {
127 const char = @intCast(u8, @enumToInt(key)); 129 const char = @intCast(u8, @enumToInt(key));