[RFC PATCH v1] TextInput: Add ctrl+w keybind
Export this patch
This deletes the previous word.
Signed-off-by: Tristan Partin <tristan@partin.io>
---
src/widgets/TextInput.zig | 35 +++++++++++++++++++++++++++++++----
1 file changed, 31 insertions(+), 4 deletions(-)
diff --git a/src/widgets/TextInput.zig b/src/widgets/TextInput.zig
index fc1bbf3..69ebbdf 100644
--- a/src/widgets/TextInput.zig
+++ b/src/widgets/TextInput.zig
@@ -6,6 +6,8 @@ const Window = @import("../Window.zig");
const GapBuffer = @import("gap_buffer").GapBuffer;
const Unicode = @import("../Unicode.zig");
+const log = std.log.scoped(.vaxis);
+
const TextInput = @This();
/// The events that this widget handles
@@ -30,9 +32,11 @@ prev_cursor_idx: usize = 0,
scroll_offset: usize = 4,
unicode: *const Unicode,
+alloc: std.mem.Allocator,
pub fn init(alloc: std.mem.Allocator, unicode: *const Unicode) TextInput {
return TextInput{
+ .alloc = alloc,
.buf = GapBuffer(u8).init(alloc),
.unicode = unicode,
};
@@ -63,6 +67,25 @@ pub fn update(self: *TextInput, event: Event) !void {
try self.deleteToEnd();
} else if (key.matches('u', .{ .ctrl = true })) {
try self.deleteToStart();
+ } else if (key.matches('w', .{ .ctrl = true })) {
+ // We need to find the first non-whitespace character
+ var idx = self.cursor_idx;
+ while (idx >= 0) {
+ const b = self.buf.getAt(idx);
+ if (b == ' ' or b == '\t') {
+ idx -= 1;
+ continue;
+ }
+
+ break;
+ }
+
+ const slice = try self.buf.dupeLogicalSlice(self.alloc, 0, idx);
+ defer self.alloc.free(slice);
+
+ // Now we find the first whitespace character
+ const delete_till = std.mem.indexOfAny(u8, slice, &.{' '}) orelse 0;
+ try self.deleteToPrevIdx(delete_till);
} else if (key.text) |text| {
try self.buf.insertSliceBefore(self.byteOffsetToCursor(), text);
self.cursor_idx += 1;
@@ -249,11 +272,15 @@ fn deleteToEnd(self: *TextInput) !void {
self.grapheme_count = self.cursor_idx;
}
-fn deleteToStart(self: *TextInput) !void {
+fn deleteToPrevIdx(self: *TextInput, idx: usize) !void {
const offset = self.byteOffsetToCursor();
- try self.buf.replaceRangeBefore(0, offset, &.{});
- self.grapheme_count -= self.cursor_idx;
- self.cursor_idx = 0;
+ try self.buf.replaceRangeBefore(idx, offset, &.{});
+ self.grapheme_count -= (self.cursor_idx - idx);
+ self.cursor_idx = idx;
+}
+
+fn deleteToStart(self: *TextInput) !void {
+ self.deleteToPrevIdx(0);
}
fn deleteBeforeCursor(self: *TextInput) !void {
--
Tristan Partin
https://tristan.partin.io