From 676f89b28f86c9b64638790965844c1f77830254 Mon Sep 17 00:00:00 2001 From: Uko Kokņevičs Date: Sun, 2 Jan 2022 09:15:10 +0200 Subject: Make actually do something --- src/Buffer.zig | 44 ++++++++++++++++++++++++++++++++++---------- src/Row.zig | 8 ++------ src/key_state.zig | 4 +++- 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 { } } +pub fn indent(self: *Buffer) !void { + if (self.config.hard_tabs) { + return self.insertChar('\t'); + } else { + return self.insertNChars(' ', self.config.tab_stop - self.cx % self.config.tab_stop); + } +} + pub fn insertChar(self: *Buffer, char: u8) !void { if (self.cy == self.rows.items.len) { try self.insertRow(self.rows.items.len, ""); @@ -320,8 +328,8 @@ pub fn insertNewline(self: *Buffer) !void { var row = &self.rows.items[self.cy]; - const indentation = try row.indentation(self.allocator); - defer self.allocator.free(indentation); + const indentation_size = row.indentationSize(); + const indentation = row.data.items[0..indentation_size]; try self.insertRow(self.cy + 1, indentation); row = &self.rows.items[self.cy]; @@ -349,14 +357,6 @@ pub fn insertRow(self: *Buffer, at: usize, data: []const u8) !void { self.dirty = true; } -pub fn insertTab(self: *Buffer) !void { - if (self.config.hard_tabs) { - return self.insertChar('\t'); - } else { - return self.insertNChars(' ', self.config.tab_stop - self.cx % self.config.tab_stop); - } -} - pub fn killLine(self: *Buffer) !void { return self.deleteRow(self.cy); } @@ -537,6 +537,30 @@ pub fn selectSyntaxHighlighting(self: *Buffer) !void { } } +pub fn unindent(self: *Buffer) !void { + if (self.cy == self.rows.items.len) { + return; + } + + // Find the end of starting whitespace + const row = &self.rows.items[self.cy]; + var indentation_size = row.indentationSize(); + if (indentation_size == 0) { + return; + } + + const indentation_rsize = row.cxToRx(self.config, indentation_size); + const desired_rsize = indentation_rsize - 1 - (indentation_rsize - 1) % self.config.tab_stop; + const desired_size = row.rxToCx(self.config, desired_rsize); + + self.cx -= indentation_size - desired_size; + + // TODO: ArrayList needs orderedRemoveNItems + while (indentation_size > desired_size) : (indentation_size -= 1) { + try row.deleteChar(self, desired_size); + } +} + fn printWithLeftPadding( allocator: Allocator, 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 { try self.update(buf); } -pub fn indentation(self: Row, allocator: Allocator) ![]u8 { - var str = ArrayList(u8).init(allocator); - defer str.deinit(); - +pub fn indentationSize(self: Row) usize { var idx: usize = 0; while (idx < self.data.items.len) : (idx += 1) { if (!std.ascii.isBlank(self.data.items[idx])) { @@ -94,8 +91,7 @@ pub fn indentation(self: Row, allocator: Allocator) ![]u8 { } } - try str.appendSlice(self.data.items[0..idx]); - return str.toOwnedSlice(); + return idx; } pub 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 { // TODO: C-h help // tab - Key.ctrl('i') => try buf.insertTab(), + Key.ctrl('i') => try buf.indent(), // line feed Key.ctrl('j') => try buf.insertNewline(), Key.ctrl('k') => try buf.killLine(), @@ -122,6 +122,8 @@ pub fn defaultState(editor: *Editor, buf: *Buffer, key: Key) Error!void { }, // ========== <*> ========== + Key.untab => try buf.unindent(), + else => { if (@enumToInt(key) <= @enumToInt(Key.max_char)) { const char = @intCast(u8, @enumToInt(key)); -- cgit v1.2.3