From 93050dc047204cd12857199c3dea8fc4f38a2e5e Mon Sep 17 00:00:00 2001 From: Uko Kokņevičs Date: Thu, 22 Feb 2024 00:00:22 +0200 Subject: Add functionality for deleting words --- src/Buffer.zig | 128 +++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 83 insertions(+), 45 deletions(-) (limited to 'src/Buffer.zig') diff --git a/src/Buffer.zig b/src/Buffer.zig index 26f9a93..8cf7dc0 100644 --- a/src/Buffer.zig +++ b/src/Buffer.zig @@ -90,10 +90,25 @@ pub fn backwardChar(self: *Buffer) void { } pub fn backwardDeleteChar(self: *Buffer) !void { + if (self.cx == 0 and self.cy == 0) { + return; + } self.backwardChar(); return self.deleteChar(); } +pub fn backwardDeleteWord(self: *Buffer) !void { + const start = self.findBackwardWordStart(); + if (start == self.cx) { + return self.backwardDeleteChar(); + } else { + var row = &self.rows.items[self.cy]; + row.data.replaceRangeAssumeCapacity(start, self.cx - start, &.{}); + self.cx = start; + return row.update(self); + } +} + pub fn backwardParagraph(self: *Buffer) void { if (self.cy == 0) { return; @@ -111,22 +126,11 @@ pub fn backwardParagraph(self: *Buffer) void { } pub fn backwardWord(self: *Buffer) void { - if (self.cx == 0) { - return self.backwardChar(); - } - - const chars = self.rows.items[self.cy].data.items; - // First we skip non-word - while (self.cx > 0) : (self.cx -= 1) { - if (std.ascii.isAlphanumeric(chars[self.cx - 1])) { - break; - } - } - // Then we skip word - while (self.cx > 0) : (self.cx -= 1) { - if (!std.ascii.isAlphanumeric(chars[self.cx - 1])) { - break; - } + const target = self.findBackwardWordStart(); + if (target == self.cx) { + self.backwardChar(); + } else { + self.cx = target; } } @@ -176,6 +180,17 @@ pub fn deleteAllRows(self: *Buffer) void { } } +pub fn deleteWord(self: *Buffer) !void { + const end = self.findForwardWordEnd(); + if (end == self.cx) { + return self.deleteChar(); + } else { + var row = &self.rows.items[self.cy]; + row.data.replaceRangeAssumeCapacity(self.cx, end - self.cx, &.{}); + return row.update(self); + } +} + pub fn deleteRow(self: *Buffer, at: usize) void { if (at == self.rows.items.len) { return; @@ -295,6 +310,50 @@ pub fn drawStatusBar(self: Buffer, writer: anytype, screencols: usize) !void { try writer.writeAll("\x1b[m\r\n"); } +pub fn findBackwardWordStart(self: Buffer) usize { + if (self.cy == self.rows.items.len) { + return 0; + } + + const chars = self.rows.items[self.cy].data.items; + var start = self.cx; + // First we skip non-word + while (start > 0) : (start -= 1) { + if (std.ascii.isAlphanumeric(chars[start - 1])) { + break; + } + } + // Then we skip word + while (start > 0) : (start -= 1) { + if (!std.ascii.isAlphanumeric(chars[start - 1])) { + break; + } + } + return start; +} + +pub fn findForwardWordEnd(self: Buffer) usize { + if (self.cy == self.rows.items.len) { + return 0; + } + + const chars = self.rows.items[self.cy].data.items; + var end = self.cx; + // First we skip non-word + while (end < chars.len) : (end += 1) { + if (std.ascii.isAlphanumeric(chars[end])) { + break; + } + } + // Then we skip word + while (end < chars.len) : (end += 1) { + if (!std.ascii.isAlphanumeric(chars[end])) { + break; + } + } + return end; +} + pub fn forwardChar(self: *Buffer) void { if (self.rows.items.len == self.cy) { return; @@ -325,26 +384,11 @@ pub fn forwardParagraph(self: *Buffer) void { } pub fn forwardWord(self: *Buffer) void { - if (self.cy == self.rows.items.len) { - return; - } - - const chars = self.rows.items[self.cy].data.items; - if (self.cx == chars.len) { - return self.forwardChar(); - } - - // First we skip non-word - while (self.cx < chars.len) : (self.cx += 1) { - if (std.ascii.isAlphanumeric(chars[self.cx])) { - break; - } - } - // Then we skip word - while (self.cx < chars.len) : (self.cx += 1) { - if (!std.ascii.isAlphanumeric(chars[self.cx])) { - break; - } + const end = self.findForwardWordEnd(); + if (end == self.cx) { + self.forwardChar(); + } else { + self.cx = end; } } @@ -440,18 +484,12 @@ pub fn killLine(self: *Buffer) !void { var row = &self.rows.items[self.cy]; if (self.cx == row.data.items.len) { - if (self.cy == self.rows.items.len - 1) { - return; - } - - try row.appendString(self, self.rows.items[self.cy+1].data.items); - self.deleteRow(self.cy + 1); + return self.deleteChar(); } else { + self.dirty = true; try row.data.resize(self.cx); + return row.update(self); } - - self.dirty = true; - return row.update(self); } pub fn lineNumberDigits(self: Buffer) usize { -- cgit v1.2.3