From 3ad478044b80de5196394e1e422b250174eb6644 Mon Sep 17 00:00:00 2001 From: Justin Su Date: Sat, 20 Jul 2024 23:04:24 -0400 Subject: [PATCH 1/3] Fix some words --- src/terminal/Selection.zig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/terminal/Selection.zig b/src/terminal/Selection.zig index d1bd4accb..e4edca0f6 100644 --- a/src/terminal/Selection.zig +++ b/src/terminal/Selection.zig @@ -353,9 +353,9 @@ pub fn adjust( s: *const Screen, adjustment: Adjustment, ) void { - // Note that we always adjusts "end" because end always represents + // Note that we always adjust "end" because end always represents // the last point of the selection by mouse, not necessarilly the - // top/bottom visually. So this results in the right behavior + // top/bottom visually. So this results in the correct behavior // whether the user drags up or down. const end_pin = self.endPtr(); switch (adjustment) { From 97bd46de7fddc6fc7c3972117b60e0199420fbf2 Mon Sep 17 00:00:00 2001 From: Justin Su Date: Sat, 20 Jul 2024 23:06:06 -0400 Subject: [PATCH 2/3] Add `adjust_selection` actions for `beginning_of_line` and `end_of_line` --- src/Surface.zig | 2 ++ src/input/Binding.zig | 2 ++ src/terminal/Selection.zig | 10 ++++++++-- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/Surface.zig b/src/Surface.zig index fe7fd2157..f5c5b65da 100644 --- a/src/Surface.zig +++ b/src/Surface.zig @@ -3471,6 +3471,8 @@ pub fn performBindingAction(self: *Surface, action: input.Binding.Action) !bool .page_down => .page_down, .home => .home, .end => .end, + .beginning_of_line => .beginning_of_line, + .end_of_line => .end_of_line, }); // If the selection endpoint is outside of the current viewpoint, diff --git a/src/input/Binding.zig b/src/input/Binding.zig index 213e711c9..a2eb360c4 100644 --- a/src/input/Binding.zig +++ b/src/input/Binding.zig @@ -304,6 +304,8 @@ pub const Action = union(enum) { page_down, home, end, + beginning_of_line, + end_of_line, }; pub const SplitDirection = enum { diff --git a/src/terminal/Selection.zig b/src/terminal/Selection.zig index e4edca0f6..365947bf9 100644 --- a/src/terminal/Selection.zig +++ b/src/terminal/Selection.zig @@ -344,6 +344,8 @@ pub const Adjustment = enum { end, page_up, page_down, + beginning_of_line, + end_of_line, }; /// Adjust the selection by some given adjustment. An adjustment allows @@ -362,7 +364,7 @@ pub fn adjust( .up => if (end_pin.up(1)) |new_end| { end_pin.* = new_end; } else { - end_pin.x = 0; + self.adjust(s, .beginning_of_line); }, .down => { @@ -377,7 +379,7 @@ pub fn adjust( } } else { // If we're at the bottom, just go to the end of the line - end_pin.x = end_pin.page.data.size.cols - 1; + self.adjust(s, .end_of_line); } }, @@ -440,6 +442,10 @@ pub fn adjust( } } }, + + .beginning_of_line => end_pin.x = 0, + + .end_of_line => end_pin.x = end_pin.page.data.size.cols - 1, } } From 64f9327a7d5173d3a35c41923e46be8e03f752ea Mon Sep 17 00:00:00 2001 From: Justin Su Date: Sun, 21 Jul 2024 17:58:00 -0400 Subject: [PATCH 3/3] Add unit tests --- src/terminal/Selection.zig | 138 +++++++++++++++++++++++++++++++++++++ 1 file changed, 138 insertions(+) diff --git a/src/terminal/Selection.zig b/src/terminal/Selection.zig index 365947bf9..aad69c6f2 100644 --- a/src/terminal/Selection.zig +++ b/src/terminal/Selection.zig @@ -792,6 +792,144 @@ test "Selection: adjust end with not full screen" { } } +test "Selection: adjust beginning of line" { + const testing = std.testing; + var s = try Screen.init(testing.allocator, 8, 10, 0); + defer s.deinit(); + try s.testWriteString("A12 B34\nC12 D34"); + + // Not at beginning of the line + { + var sel = Selection.init( + s.pages.pin(.{ .screen = .{ .x = 5, .y = 1 } }).?, + s.pages.pin(.{ .screen = .{ .x = 5, .y = 1 } }).?, + false, + ); + defer sel.deinit(&s); + sel.adjust(&s, .beginning_of_line); + + // Start line + try testing.expectEqual(point.Point{ .screen = .{ + .x = 5, + .y = 1, + } }, s.pages.pointFromPin(.screen, sel.start()).?); + try testing.expectEqual(point.Point{ .screen = .{ + .x = 0, + .y = 1, + } }, s.pages.pointFromPin(.screen, sel.end()).?); + } + + // Already at beginning of the line + { + var sel = Selection.init( + s.pages.pin(.{ .screen = .{ .x = 5, .y = 1 } }).?, + s.pages.pin(.{ .screen = .{ .x = 0, .y = 1 } }).?, + false, + ); + defer sel.deinit(&s); + sel.adjust(&s, .beginning_of_line); + + // Start line + try testing.expectEqual(point.Point{ .screen = .{ + .x = 5, + .y = 1, + } }, s.pages.pointFromPin(.screen, sel.start()).?); + try testing.expectEqual(point.Point{ .screen = .{ + .x = 0, + .y = 1, + } }, s.pages.pointFromPin(.screen, sel.end()).?); + } + + // End pin moves to start pin + { + var sel = Selection.init( + s.pages.pin(.{ .screen = .{ .x = 0, .y = 1 } }).?, + s.pages.pin(.{ .screen = .{ .x = 5, .y = 1 } }).?, + false, + ); + defer sel.deinit(&s); + sel.adjust(&s, .beginning_of_line); + + // Start line + try testing.expectEqual(point.Point{ .screen = .{ + .x = 0, + .y = 1, + } }, s.pages.pointFromPin(.screen, sel.start()).?); + try testing.expectEqual(point.Point{ .screen = .{ + .x = 0, + .y = 1, + } }, s.pages.pointFromPin(.screen, sel.end()).?); + } +} + +test "Selection: adjust end of line" { + const testing = std.testing; + var s = try Screen.init(testing.allocator, 8, 10, 0); + defer s.deinit(); + try s.testWriteString("A12 B34\nC12 D34"); + + // Not at end of the line + { + var sel = Selection.init( + s.pages.pin(.{ .screen = .{ .x = 1, .y = 0 } }).?, + s.pages.pin(.{ .screen = .{ .x = 1, .y = 0 } }).?, + false, + ); + defer sel.deinit(&s); + sel.adjust(&s, .end_of_line); + + try testing.expectEqual(point.Point{ .screen = .{ + .x = 1, + .y = 0, + } }, s.pages.pointFromPin(.screen, sel.start()).?); + try testing.expectEqual(point.Point{ .screen = .{ + .x = 7, + .y = 0, + } }, s.pages.pointFromPin(.screen, sel.end()).?); + } + + // Already at end of the line + { + var sel = Selection.init( + s.pages.pin(.{ .screen = .{ .x = 1, .y = 0 } }).?, + s.pages.pin(.{ .screen = .{ .x = 7, .y = 0 } }).?, + false, + ); + defer sel.deinit(&s); + sel.adjust(&s, .end_of_line); + + try testing.expectEqual(point.Point{ .screen = .{ + .x = 1, + .y = 0, + } }, s.pages.pointFromPin(.screen, sel.start()).?); + try testing.expectEqual(point.Point{ .screen = .{ + .x = 7, + .y = 0, + } }, s.pages.pointFromPin(.screen, sel.end()).?); + } + + // End pin moves to start pin + { + var sel = Selection.init( + s.pages.pin(.{ .screen = .{ .x = 7, .y = 0 } }).?, + s.pages.pin(.{ .screen = .{ .x = 1, .y = 0 } }).?, + false, + ); + defer sel.deinit(&s); + sel.adjust(&s, .end_of_line); + + // Start line + try testing.expectEqual(point.Point{ .screen = .{ + .x = 7, + .y = 0, + } }, s.pages.pointFromPin(.screen, sel.start()).?); + try testing.expectEqual(point.Point{ .screen = .{ + .x = 7, + .y = 0, + } }, s.pages.pointFromPin(.screen, sel.end()).?); + } +} + test "Selection: order, standard" { const testing = std.testing; const alloc = testing.allocator;