mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-16 16:56:09 +03:00
terminal: screen lineIterator
This commit is contained in:
@ -3717,6 +3717,7 @@ test "Screen: write long emoji" {
|
||||
try testing.expectEqual(@as(usize, 5), s.cursor.x);
|
||||
}
|
||||
|
||||
// X
|
||||
test "Screen: lineIterator" {
|
||||
const testing = std.testing;
|
||||
const alloc = testing.allocator;
|
||||
@ -3745,6 +3746,7 @@ test "Screen: lineIterator" {
|
||||
try testing.expect(iter.next() == null);
|
||||
}
|
||||
|
||||
// X
|
||||
test "Screen: lineIterator soft wrap" {
|
||||
const testing = std.testing;
|
||||
const alloc = testing.allocator;
|
||||
@ -3773,6 +3775,7 @@ test "Screen: lineIterator soft wrap" {
|
||||
try testing.expect(iter.next() == null);
|
||||
}
|
||||
|
||||
// X - selectLine in new screen
|
||||
test "Screen: getLine soft wrap" {
|
||||
const testing = std.testing;
|
||||
const alloc = testing.allocator;
|
||||
|
@ -10,6 +10,7 @@ const point = @import("point.zig");
|
||||
const pagepkg = @import("page.zig");
|
||||
const stylepkg = @import("style.zig");
|
||||
const size = @import("size.zig");
|
||||
const Selection = @import("Selection.zig");
|
||||
const OffsetBuf = size.OffsetBuf;
|
||||
const Capacity = pagepkg.Capacity;
|
||||
const Page = pagepkg.Page;
|
||||
|
@ -1247,7 +1247,7 @@ pub const SelectLine = struct {
|
||||
/// lines and will omit the leading and trailing whitespace. If the point is
|
||||
/// over whitespace but the line has non-whitespace characters elsewhere, the
|
||||
/// line will be selected.
|
||||
pub fn selectLine(self: *Screen, opts: SelectLine) ?Selection {
|
||||
pub fn selectLine(self: *const Screen, opts: SelectLine) ?Selection {
|
||||
_ = self;
|
||||
|
||||
// Get the current point semantic prompt state since that determines
|
||||
@ -1713,6 +1713,35 @@ pub fn selectPrompt(self: *Screen, pin: Pin) ?Selection {
|
||||
return Selection.init(start, end, false);
|
||||
}
|
||||
|
||||
pub const LineIterator = struct {
|
||||
screen: *const Screen,
|
||||
current: ?Pin = null,
|
||||
|
||||
pub fn next(self: *LineIterator) ?Selection {
|
||||
const current = self.current orelse return null;
|
||||
const result = self.screen.selectLine(.{
|
||||
.pin = current,
|
||||
.whitespace = null,
|
||||
.semantic_prompt_boundary = false,
|
||||
}) orelse {
|
||||
self.current = null;
|
||||
return null;
|
||||
};
|
||||
|
||||
self.current = result.end().down(1);
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
/// Returns an iterator to move through the soft-wrapped lines starting
|
||||
/// from pin.
|
||||
pub fn lineIterator(self: *const Screen, start: Pin) LineIterator {
|
||||
return LineIterator{
|
||||
.screen = self,
|
||||
.current = start,
|
||||
};
|
||||
}
|
||||
|
||||
/// Returns the change in x/y that is needed to reach "to" from "from"
|
||||
/// within a prompt. If "to" is before or after the prompt bounds then
|
||||
/// the result will be bounded to the prompt.
|
||||
@ -6355,3 +6384,54 @@ test "Screen: selectionString, rectangle, more complex w/breaks" {
|
||||
defer alloc.free(contents);
|
||||
try testing.expectEqualStrings(expected, contents);
|
||||
}
|
||||
|
||||
test "Screen: lineIterator" {
|
||||
const testing = std.testing;
|
||||
const alloc = testing.allocator;
|
||||
|
||||
var s = try init(alloc, 5, 5, 0);
|
||||
defer s.deinit();
|
||||
const str = "1ABCD\n2EFGH";
|
||||
try s.testWriteString(str);
|
||||
|
||||
// Test the line iterator
|
||||
var iter = s.lineIterator(s.pages.pin(.{ .viewport = .{} }).?);
|
||||
{
|
||||
const sel = iter.next().?;
|
||||
const actual = try s.selectionString(alloc, sel, false);
|
||||
defer alloc.free(actual);
|
||||
try testing.expectEqualStrings("1ABCD", actual);
|
||||
}
|
||||
{
|
||||
const sel = iter.next().?;
|
||||
const actual = try s.selectionString(alloc, sel, false);
|
||||
defer alloc.free(actual);
|
||||
try testing.expectEqualStrings("2EFGH", actual);
|
||||
}
|
||||
}
|
||||
|
||||
test "Screen: lineIterator soft wrap" {
|
||||
const testing = std.testing;
|
||||
const alloc = testing.allocator;
|
||||
|
||||
var s = try init(alloc, 5, 5, 0);
|
||||
defer s.deinit();
|
||||
const str = "1ABCD2EFGH\n3ABCD";
|
||||
try s.testWriteString(str);
|
||||
|
||||
// Test the line iterator
|
||||
var iter = s.lineIterator(s.pages.pin(.{ .viewport = .{} }).?);
|
||||
{
|
||||
const sel = iter.next().?;
|
||||
const actual = try s.selectionString(alloc, sel, false);
|
||||
defer alloc.free(actual);
|
||||
try testing.expectEqualStrings("1ABCD2EFGH", actual);
|
||||
}
|
||||
{
|
||||
const sel = iter.next().?;
|
||||
const actual = try s.selectionString(alloc, sel, false);
|
||||
defer alloc.free(actual);
|
||||
try testing.expectEqualStrings("3ABCD", actual);
|
||||
}
|
||||
// try testing.expect(iter.next() == null);
|
||||
}
|
||||
|
Reference in New Issue
Block a user