From 59485713b4ff87bbe251255b5c054f1b5d4a54ed Mon Sep 17 00:00:00 2001 From: Adam Stephens Date: Tue, 27 Feb 2024 10:24:30 -0500 Subject: [PATCH 1/2] screen/selectword: add more boundary characters --- src/terminal/Screen.zig | 94 +++++++++++++++++++++++++---------------- 1 file changed, 58 insertions(+), 36 deletions(-) diff --git a/src/terminal/Screen.zig b/src/terminal/Screen.zig index 9b5cff2b9..0841376af 100644 --- a/src/terminal/Screen.zig +++ b/src/terminal/Screen.zig @@ -1739,7 +1739,7 @@ pub fn selectWordBetween( /// this happens is if the point pt is outside of the written screen space. pub fn selectWord(self: *Screen, pt: point.ScreenPoint) ?Selection { // Boundary characters for selection purposes - const boundary = &[_]u32{ 0, ' ', '\t', '\'', '"' }; + const boundary = &[_]u32{ 0, ' ', '\t', '\'', '"', '│', '`', '|', ':', ',', '(', ')', '[', ']', '{', '}', '<', '>' }; // Impossible to select anything outside of the area we've written. const y_max = self.rowsWritten() - 1; @@ -4766,50 +4766,72 @@ test "Screen: selectWord whitespace across soft-wrap" { } } -test "Screen: selectWord with single quote boundary" { +test "Screen: selectWord with character boundary" { const testing = std.testing; const alloc = testing.allocator; var s = try init(alloc, 10, 20, 0); defer s.deinit(); - try s.testWriteString(" 'abc' \n123"); - // Inside quotes forward - { - const sel = s.selectWord(.{ .x = 2, .y = 0 }).?; - try testing.expectEqual(@as(usize, 2), sel.start.x); - try testing.expectEqual(@as(usize, 0), sel.start.y); - try testing.expectEqual(@as(usize, 4), sel.end.x); - try testing.expectEqual(@as(usize, 0), sel.end.y); - } + const cases = [_][]const u8{ + " 'abc' \n123", + " \"abc\" \n123", + " │abc│ \n123", + " `abc` \n123", + " |abc| \n123", + " :abc: \n123", + " ,abc, \n123", + " (abc( \n123", + " )abc) \n123", + // " [abc[ \n123", + // " ]abc] \n123", + // " {abc{ \n123", + // " }abc} \n123", + // " abc> \n123", + }; - // Inside quotes backward - { - const sel = s.selectWord(.{ .x = 4, .y = 0 }).?; - try testing.expectEqual(@as(usize, 2), sel.start.x); - try testing.expectEqual(@as(usize, 0), sel.start.y); - try testing.expectEqual(@as(usize, 4), sel.end.x); - try testing.expectEqual(@as(usize, 0), sel.end.y); - } + for (cases) |case| { + try s.clear(.history); + try s.testWriteString(case); - // Inside quotes bidirectional - { - const sel = s.selectWord(.{ .x = 3, .y = 0 }).?; - try testing.expectEqual(@as(usize, 2), sel.start.x); - try testing.expectEqual(@as(usize, 0), sel.start.y); - try testing.expectEqual(@as(usize, 4), sel.end.x); - try testing.expectEqual(@as(usize, 0), sel.end.y); - } + // Inside character forward + { + const sel = s.selectWord(.{ .x = 2, .y = 0 }).?; + try testing.expectEqual(@as(usize, 2), sel.start.x); + try testing.expectEqual(@as(usize, 0), sel.start.y); + try testing.expectEqual(@as(usize, 4), sel.end.x); + try testing.expectEqual(@as(usize, 0), sel.end.y); + } - // On quote - // NOTE: this behavior is not ideal, so we can change this one day, - // but I think its also not that important compared to the above. - { - const sel = s.selectWord(.{ .x = 1, .y = 0 }).?; - try testing.expectEqual(@as(usize, 0), sel.start.x); - try testing.expectEqual(@as(usize, 0), sel.start.y); - try testing.expectEqual(@as(usize, 1), sel.end.x); - try testing.expectEqual(@as(usize, 0), sel.end.y); + // Inside character backward + { + const sel = s.selectWord(.{ .x = 4, .y = 0 }).?; + try testing.expectEqual(@as(usize, 2), sel.start.x); + try testing.expectEqual(@as(usize, 0), sel.start.y); + try testing.expectEqual(@as(usize, 4), sel.end.x); + try testing.expectEqual(@as(usize, 0), sel.end.y); + } + + // Inside character bidirectional + { + const sel = s.selectWord(.{ .x = 3, .y = 0 }).?; + try testing.expectEqual(@as(usize, 2), sel.start.x); + try testing.expectEqual(@as(usize, 0), sel.start.y); + try testing.expectEqual(@as(usize, 4), sel.end.x); + try testing.expectEqual(@as(usize, 0), sel.end.y); + } + + // On quote + // NOTE: this behavior is not ideal, so we can change this one day, + // but I think its also not that important compared to the above. + { + const sel = s.selectWord(.{ .x = 1, .y = 0 }).?; + try testing.expectEqual(@as(usize, 0), sel.start.x); + try testing.expectEqual(@as(usize, 0), sel.start.y); + try testing.expectEqual(@as(usize, 1), sel.end.x); + try testing.expectEqual(@as(usize, 0), sel.end.y); + } } } From eaa78477d517a61c48db37ac169ed530b1837736 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Mon, 4 Mar 2024 14:30:28 -0800 Subject: [PATCH 2/2] terminal: fix tests for brackets on selectWord --- src/terminal/Screen.zig | 39 ++++++++++++++++++++++++++++----------- 1 file changed, 28 insertions(+), 11 deletions(-) diff --git a/src/terminal/Screen.zig b/src/terminal/Screen.zig index 0841376af..dcef37328 100644 --- a/src/terminal/Screen.zig +++ b/src/terminal/Screen.zig @@ -1739,7 +1739,26 @@ pub fn selectWordBetween( /// this happens is if the point pt is outside of the written screen space. pub fn selectWord(self: *Screen, pt: point.ScreenPoint) ?Selection { // Boundary characters for selection purposes - const boundary = &[_]u32{ 0, ' ', '\t', '\'', '"', '│', '`', '|', ':', ',', '(', ')', '[', ']', '{', '}', '<', '>' }; + const boundary = &[_]u32{ + 0, + ' ', + '\t', + '\'', + '"', + '│', + '`', + '|', + ':', + ',', + '(', + ')', + '[', + ']', + '{', + '}', + '<', + '>', + }; // Impossible to select anything outside of the area we've written. const y_max = self.rowsWritten() - 1; @@ -4770,9 +4789,6 @@ test "Screen: selectWord with character boundary" { const testing = std.testing; const alloc = testing.allocator; - var s = try init(alloc, 10, 20, 0); - defer s.deinit(); - const cases = [_][]const u8{ " 'abc' \n123", " \"abc\" \n123", @@ -4783,16 +4799,17 @@ test "Screen: selectWord with character boundary" { " ,abc, \n123", " (abc( \n123", " )abc) \n123", - // " [abc[ \n123", - // " ]abc] \n123", - // " {abc{ \n123", - // " }abc} \n123", - // " abc> \n123", + " [abc[ \n123", + " ]abc] \n123", + " {abc{ \n123", + " }abc} \n123", + " abc> \n123", }; for (cases) |case| { - try s.clear(.history); + var s = try init(alloc, 10, 20, 0); + defer s.deinit(); try s.testWriteString(case); // Inside character forward