terminal2: selectAll

This commit is contained in:
Mitchell Hashimoto
2024-03-06 13:54:03 -08:00
parent 7ffefc9487
commit f91624ab61
2 changed files with 128 additions and 2 deletions

View File

@ -4475,6 +4475,7 @@ test "Screen: clone one line active with extra space" {
try testing.expectEqual(@as(usize, 1), s.rowsWritten());
}
// X
test "Screen: selectLine" {
const testing = std.testing;
const alloc = testing.allocator;
@ -4523,6 +4524,8 @@ test "Screen: selectLine" {
try testing.expectEqual(@as(usize, 0), sel.end.y);
}
}
// X
test "Screen: selectAll" {
const testing = std.testing;
const alloc = testing.allocator;
@ -4549,6 +4552,7 @@ test "Screen: selectAll" {
}
}
// X
test "Screen: selectLine across soft-wrap" {
const testing = std.testing;
const alloc = testing.allocator;

View File

@ -866,7 +866,9 @@ pub fn selectLine(self: *Screen, pin: Pin) ?Selection {
// The real start of the row is the first row in the soft-wrap.
const start_pin: Pin = start_pin: {
var it = pin.rowIterator(.left_up, null);
var it_prev: Pin = pin;
while (it.next()) |p| {
it_prev = p;
const row = p.rowAndCell().row;
if (!row.wrap) {
@ -882,9 +884,11 @@ pub fn selectLine(self: *Screen, pin: Pin) ?Selection {
prev.x = 0;
break :start_pin prev;
}
} else {
var copy = it_prev;
copy.x = 0;
break :start_pin copy;
}
return null;
};
// The real end of the row is the final row in the soft-wrap.
@ -956,6 +960,62 @@ pub fn selectLine(self: *Screen, pin: Pin) ?Selection {
return Selection.init(start, end, false);
}
/// Return the selection for all contents on the screen. Surrounding
/// whitespace is omitted. If there is no selection, this returns null.
pub fn selectAll(self: *Screen) ?Selection {
const whitespace = &[_]u32{ 0, ' ', '\t' };
const start: Pin = start: {
var it = self.pages.cellIterator(
.right_down,
.{ .screen = .{} },
null,
);
while (it.next()) |p| {
const cell = p.rowAndCell().cell;
if (!cell.hasText()) continue;
// Non-empty means we found it.
const this_whitespace = std.mem.indexOfAny(
u32,
whitespace,
&[_]u32{cell.content.codepoint},
) != null;
if (this_whitespace) continue;
break :start p;
}
return null;
};
const end: Pin = end: {
var it = self.pages.cellIterator(
.left_up,
.{ .screen = .{} },
null,
);
while (it.next()) |p| {
const cell = p.rowAndCell().cell;
if (!cell.hasText()) continue;
// Non-empty means we found it.
const this_whitespace = std.mem.indexOfAny(
u32,
whitespace,
&[_]u32{cell.content.codepoint},
) != null;
if (this_whitespace) continue;
break :end p;
}
return null;
};
return Selection.init(start, end, false);
}
/// Dump the screen to a string. The writer given should be buffered;
/// this function does not attempt to efficiently write and generally writes
/// one byte at a time.
@ -3642,3 +3702,65 @@ test "Screen: selectLine" {
} }, s.pages.pointFromPin(.screen, sel.end().*).?);
}
}
test "Screen: selectLine across soft-wrap" {
const testing = std.testing;
const alloc = testing.allocator;
var s = try init(alloc, 5, 10, 0);
defer s.deinit();
try s.testWriteString(" 12 34012 \n 123");
// Going forward
{
var sel = s.selectLine(s.pages.pin(.{ .active = .{
.x = 1,
.y = 0,
} }).?).?;
defer sel.deinit(&s);
try testing.expectEqual(point.Point{ .screen = .{
.x = 1,
.y = 0,
} }, s.pages.pointFromPin(.screen, sel.start().*).?);
try testing.expectEqual(point.Point{ .screen = .{
.x = 3,
.y = 1,
} }, s.pages.pointFromPin(.screen, sel.end().*).?);
}
}
test "Screen: selectAll" {
const testing = std.testing;
const alloc = testing.allocator;
var s = try init(alloc, 10, 10, 0);
defer s.deinit();
{
try s.testWriteString("ABC DEF\n 123\n456");
var sel = s.selectAll().?;
defer sel.deinit(&s);
try testing.expectEqual(point.Point{ .screen = .{
.x = 0,
.y = 0,
} }, s.pages.pointFromPin(.screen, sel.start().*).?);
try testing.expectEqual(point.Point{ .screen = .{
.x = 2,
.y = 2,
} }, s.pages.pointFromPin(.screen, sel.end().*).?);
}
{
try s.testWriteString("\nFOO\n BAR\n BAZ\n QWERTY\n 12345678");
var sel = s.selectAll().?;
defer sel.deinit(&s);
try testing.expectEqual(point.Point{ .screen = .{
.x = 0,
.y = 0,
} }, s.pages.pointFromPin(.screen, sel.start().*).?);
try testing.expectEqual(point.Point{ .screen = .{
.x = 8,
.y = 7,
} }, s.pages.pointFromPin(.screen, sel.end().*).?);
}
}