From 1786b9fea2a94924fe46c61c67811fdc919e0a0a Mon Sep 17 00:00:00 2001 From: Uko Kokņevičs Date: Wed, 21 Feb 2024 23:00:48 +0200 Subject: Add functionality for skipping paragraphs up and down --- src/Buffer.zig | 32 ++++++++++++++++++++++++++++++++ src/KeyMap.zig | 6 ++++++ src/KeyReader.zig | 8 +++++--- 3 files changed, 43 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/Buffer.zig b/src/Buffer.zig index f9a1576..bb6d3ce 100644 --- a/src/Buffer.zig +++ b/src/Buffer.zig @@ -94,6 +94,22 @@ pub fn backwardDeleteChar(self: *Buffer) !void { return self.deleteChar(); } +pub fn backwardParagraph(self: *Buffer) void { + if (self.cy == 0) { + return; + } + + self.cy -= 1; + while (self.cy > 0) : (self.cy -= 1) { + // TODO: I'm lazy but also consider lines of only whitespace + if (self.rows.items[self.cy].data.items.len == 0) { + break; + } + } + + self.cx = 0; +} + pub fn cleanWhiteSpace(self: *Buffer) !void { for (self.rows.items) |*row| { try row.cleanWhiteSpace(self); @@ -272,6 +288,22 @@ pub fn forwardChar(self: *Buffer) void { } } +pub fn forwardParagraph(self: *Buffer) void { + if (self.cy == self.rows.items.len) { + return; + } + + self.cy += 1; + while (self.cy < self.rows.items.len) : (self.cy += 1) { + // TODO: I'm lazy but also consider whitespace-only lines + if (self.rows.items[self.cy].data.items.len == 0) { + break; + } + } + + self.cx = 0; +} + // TODO: Make use of the callback feature to go to the final line while typing in. pub fn goToLine(self: *Buffer, editor: *Editor) !void { if (try editor.prompt(self.allocator, "Goto line")) |line_str| { diff --git a/src/KeyMap.zig b/src/KeyMap.zig index 8df4c06..90dcd01 100644 --- a/src/KeyMap.zig +++ b/src/KeyMap.zig @@ -112,11 +112,17 @@ pub fn defaultMap(allocator: Allocator) !KeyMap { try map.bind(&.{Key.meta(Key.ctrl('d'))}, Buffer.backwardDeleteChar); // M-<*> + try map.bind(&.{Key.meta(Key.down)}, Buffer.forwardParagraph); + try map.bind(&.{Key.meta(Key.up)}, Buffer.backwardParagraph); // M-g is taken + try map.bind(&.{Key.meta('n')}, Buffer.forwardParagraph); // M-O is taken + try map.bind(&.{Key.meta('p')}, Buffer.backwardParagraph); try map.bind(&.{Key.meta('v')}, Buffer.pageUp); // C-<*> + try map.bind(&.{Key.ctrl(Key.down)}, Buffer.forwardParagraph); + try map.bind(&.{Key.ctrl(Key.up)}, Buffer.backwardParagraph); try map.bind(&.{Key.ctrl('a')}, Buffer.moveBeginningOfLine); try map.bind(&.{Key.ctrl('b')}, Buffer.backwardChar); try map.bind(&.{Key.ctrl('d')}, Buffer.deleteChar); diff --git a/src/KeyReader.zig b/src/KeyReader.zig index 28e6dcb..5ddef82 100644 --- a/src/KeyReader.zig +++ b/src/KeyReader.zig @@ -31,7 +31,7 @@ pub fn readKey(self: *KeyReader) Error!Key { const reader = std.io.getStdIn().reader(); const char = try readByteBlocking(reader); if (char == '\x1b') { - return self.readMetaKey(reader); + return self.readMetaKey(reader, true); } else if (char == '\x9b') { return self.readControlSequence(reader); } else { @@ -186,9 +186,11 @@ fn readControlSequence(self: *KeyReader, reader: File.Reader) !Key { return Key.meta('['); } -fn readMetaKey(self: *KeyReader, reader: File.Reader) Error!Key { +fn readMetaKey(self: *KeyReader, reader: File.Reader, canRecurse: bool) Error!Key { if (try readByte(reader)) |char| { - if (char == '[') { + if (char == '\x1b' and canRecurse) { + return Key.meta(try self.readMetaKey(reader, false)); + } else if (char == '[') { return self.readControlSequence(reader); } else { return Key.meta(char); -- cgit v1.2.3