~rockorager/libvaxis

TextInput: Add ctrl+w keybind v1 PROPOSED

Tristan Partin: 1
 TextInput: Add ctrl+w keybind

 1 files changed, 31 insertions(+), 4 deletions(-)
Export patchset (mbox)
How do I use this?

Copy & paste the following snippet into your terminal to import this patchset into git:

curl -s https://lists.sr.ht/~rockorager/libvaxis/patches/54438/mbox | git am -3
Learn more about email & git

[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