mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-25 13:16:11 +03:00
terminal: Coordinate uses CellCountInt
This commit is contained in:
@ -1908,7 +1908,7 @@ fn rebuildCells2(
|
|||||||
// font shaping by row. In the future, we will also do dirty tracking
|
// font shaping by row. In the future, we will also do dirty tracking
|
||||||
// by row.
|
// by row.
|
||||||
var row_it = screen.pages.rowIterator(.right_down, .{ .viewport = .{} }, null);
|
var row_it = screen.pages.rowIterator(.right_down, .{ .viewport = .{} }, null);
|
||||||
var y: usize = 0;
|
var y: terminal.size.CellCountInt = 0;
|
||||||
while (row_it.next()) |row| {
|
while (row_it.next()) |row| {
|
||||||
defer y += 1;
|
defer y += 1;
|
||||||
|
|
||||||
|
@ -232,7 +232,10 @@ test Contents {
|
|||||||
// Assert that get returns null for everything.
|
// Assert that get returns null for everything.
|
||||||
for (0..rows) |y| {
|
for (0..rows) |y| {
|
||||||
for (0..cols) |x| {
|
for (0..cols) |x| {
|
||||||
try testing.expect(c.get(.bg, .{ .x = x, .y = y }) == null);
|
try testing.expect(c.get(.bg, .{
|
||||||
|
.x = @intCast(x),
|
||||||
|
.y = @intCast(y),
|
||||||
|
}) == null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -250,7 +253,10 @@ test Contents {
|
|||||||
c.clear(1);
|
c.clear(1);
|
||||||
for (0..rows) |y| {
|
for (0..rows) |y| {
|
||||||
for (0..cols) |x| {
|
for (0..cols) |x| {
|
||||||
try testing.expect(c.get(.bg, .{ .x = x, .y = y }) == null);
|
try testing.expect(c.get(.bg, .{
|
||||||
|
.x = @intCast(x),
|
||||||
|
.y = @intCast(y),
|
||||||
|
}) == null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -287,12 +287,12 @@ fn initPostPipeline(
|
|||||||
/// This is a single parameter for the terminal cell shader.
|
/// This is a single parameter for the terminal cell shader.
|
||||||
pub const CellText = extern struct {
|
pub const CellText = extern struct {
|
||||||
mode: Mode,
|
mode: Mode,
|
||||||
grid_pos: [2]u16,
|
|
||||||
glyph_pos: [2]u32 = .{ 0, 0 },
|
glyph_pos: [2]u32 = .{ 0, 0 },
|
||||||
glyph_size: [2]u32 = .{ 0, 0 },
|
glyph_size: [2]u32 = .{ 0, 0 },
|
||||||
glyph_offset: [2]i32 = .{ 0, 0 },
|
glyph_offset: [2]i32 = .{ 0, 0 },
|
||||||
color: [4]u8,
|
color: [4]u8,
|
||||||
bg_color: [4]u8,
|
bg_color: [4]u8,
|
||||||
|
grid_pos: [2]u16,
|
||||||
cell_width: u8,
|
cell_width: u8,
|
||||||
|
|
||||||
pub const Mode = enum(u8) {
|
pub const Mode = enum(u8) {
|
||||||
|
@ -1421,7 +1421,7 @@ fn resizeWithoutReflowGrowCols(
|
|||||||
|
|
||||||
// Keeps track of all our copied rows. Assertions at the end is that
|
// Keeps track of all our copied rows. Assertions at the end is that
|
||||||
// we copied exactly our page size.
|
// we copied exactly our page size.
|
||||||
var copied: usize = 0;
|
var copied: size.CellCountInt = 0;
|
||||||
|
|
||||||
// This function has an unfortunate side effect in that it causes memory
|
// This function has an unfortunate side effect in that it causes memory
|
||||||
// fragmentation on rows if the columns are increasing in a way that
|
// fragmentation on rows if the columns are increasing in a way that
|
||||||
@ -2545,7 +2545,7 @@ pub fn cellIterator(
|
|||||||
pub const RowIterator = struct {
|
pub const RowIterator = struct {
|
||||||
page_it: PageIterator,
|
page_it: PageIterator,
|
||||||
chunk: ?PageIterator.Chunk = null,
|
chunk: ?PageIterator.Chunk = null,
|
||||||
offset: usize = 0,
|
offset: size.CellCountInt = 0,
|
||||||
|
|
||||||
pub fn next(self: *RowIterator) ?Pin {
|
pub fn next(self: *RowIterator) ?Pin {
|
||||||
const chunk = self.chunk orelse return null;
|
const chunk = self.chunk orelse return null;
|
||||||
@ -2767,8 +2767,8 @@ pub const PageIterator = struct {
|
|||||||
|
|
||||||
pub const Chunk = struct {
|
pub const Chunk = struct {
|
||||||
page: *List.Node,
|
page: *List.Node,
|
||||||
start: usize,
|
start: size.CellCountInt,
|
||||||
end: usize,
|
end: size.CellCountInt,
|
||||||
|
|
||||||
pub fn rows(self: Chunk) []Row {
|
pub fn rows(self: Chunk) []Row {
|
||||||
const rows_ptr = self.page.data.rows.ptr(self.page.data.memory);
|
const rows_ptr = self.page.data.rows.ptr(self.page.data.memory);
|
||||||
@ -2944,8 +2944,8 @@ fn growRows(self: *PageList, n: usize) !void {
|
|||||||
/// should limit the number of active pins as much as possible.
|
/// should limit the number of active pins as much as possible.
|
||||||
pub const Pin = struct {
|
pub const Pin = struct {
|
||||||
page: *List.Node,
|
page: *List.Node,
|
||||||
y: usize = 0,
|
y: size.CellCountInt = 0,
|
||||||
x: usize = 0,
|
x: size.CellCountInt = 0,
|
||||||
|
|
||||||
pub fn rowAndCell(self: Pin) struct {
|
pub fn rowAndCell(self: Pin) struct {
|
||||||
row: *pagepkg.Row,
|
row: *pagepkg.Row,
|
||||||
@ -3104,7 +3104,7 @@ pub const Pin = struct {
|
|||||||
pub fn left(self: Pin, n: usize) Pin {
|
pub fn left(self: Pin, n: usize) Pin {
|
||||||
assert(n <= self.x);
|
assert(n <= self.x);
|
||||||
var result = self;
|
var result = self;
|
||||||
result.x -= n;
|
result.x -= std.math.cast(size.CellCountInt, n) orelse result.x;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3112,7 +3112,8 @@ pub const Pin = struct {
|
|||||||
pub fn right(self: Pin, n: usize) Pin {
|
pub fn right(self: Pin, n: usize) Pin {
|
||||||
assert(self.x + n < self.page.data.size.cols);
|
assert(self.x + n < self.page.data.size.cols);
|
||||||
var result = self;
|
var result = self;
|
||||||
result.x += n;
|
result.x +|= std.math.cast(size.CellCountInt, n) orelse
|
||||||
|
std.math.maxInt(size.CellCountInt);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3147,7 +3148,8 @@ pub const Pin = struct {
|
|||||||
const rows = self.page.data.size.rows - (self.y + 1);
|
const rows = self.page.data.size.rows - (self.y + 1);
|
||||||
if (n <= rows) return .{ .offset = .{
|
if (n <= rows) return .{ .offset = .{
|
||||||
.page = self.page,
|
.page = self.page,
|
||||||
.y = n + self.y,
|
.y = std.math.cast(size.CellCountInt, self.y + n) orelse
|
||||||
|
std.math.maxInt(size.CellCountInt),
|
||||||
.x = self.x,
|
.x = self.x,
|
||||||
} };
|
} };
|
||||||
|
|
||||||
@ -3165,7 +3167,8 @@ pub const Pin = struct {
|
|||||||
} };
|
} };
|
||||||
if (n_left <= page.data.size.rows) return .{ .offset = .{
|
if (n_left <= page.data.size.rows) return .{ .offset = .{
|
||||||
.page = page,
|
.page = page,
|
||||||
.y = n_left - 1,
|
.y = std.math.cast(size.CellCountInt, n_left - 1) orelse
|
||||||
|
std.math.maxInt(size.CellCountInt),
|
||||||
.x = self.x,
|
.x = self.x,
|
||||||
} };
|
} };
|
||||||
n_left -= page.data.size.rows;
|
n_left -= page.data.size.rows;
|
||||||
@ -3184,7 +3187,8 @@ pub const Pin = struct {
|
|||||||
// Index fits within this page
|
// Index fits within this page
|
||||||
if (n <= self.y) return .{ .offset = .{
|
if (n <= self.y) return .{ .offset = .{
|
||||||
.page = self.page,
|
.page = self.page,
|
||||||
.y = self.y - n,
|
.y = std.math.cast(size.CellCountInt, self.y - n) orelse
|
||||||
|
std.math.maxInt(size.CellCountInt),
|
||||||
.x = self.x,
|
.x = self.x,
|
||||||
} };
|
} };
|
||||||
|
|
||||||
@ -3198,7 +3202,8 @@ pub const Pin = struct {
|
|||||||
} };
|
} };
|
||||||
if (n_left <= page.data.size.rows) return .{ .offset = .{
|
if (n_left <= page.data.size.rows) return .{ .offset = .{
|
||||||
.page = page,
|
.page = page,
|
||||||
.y = page.data.size.rows - n_left,
|
.y = std.math.cast(size.CellCountInt, page.data.size.rows - n_left) orelse
|
||||||
|
std.math.maxInt(size.CellCountInt),
|
||||||
.x = self.x,
|
.x = self.x,
|
||||||
} };
|
} };
|
||||||
n_left -= page.data.size.rows;
|
n_left -= page.data.size.rows;
|
||||||
@ -3210,8 +3215,8 @@ const Cell = struct {
|
|||||||
page: *List.Node,
|
page: *List.Node,
|
||||||
row: *pagepkg.Row,
|
row: *pagepkg.Row,
|
||||||
cell: *pagepkg.Cell,
|
cell: *pagepkg.Cell,
|
||||||
row_idx: usize,
|
row_idx: size.CellCountInt,
|
||||||
col_idx: usize,
|
col_idx: size.CellCountInt,
|
||||||
|
|
||||||
/// Get the cell style.
|
/// Get the cell style.
|
||||||
///
|
///
|
||||||
@ -3231,7 +3236,7 @@ const Cell = struct {
|
|||||||
/// this file then consider a different approach and ask yourself very
|
/// this file then consider a different approach and ask yourself very
|
||||||
/// carefully if you really need this.
|
/// carefully if you really need this.
|
||||||
pub fn screenPoint(self: Cell) point.Point {
|
pub fn screenPoint(self: Cell) point.Point {
|
||||||
var y: usize = self.row_idx;
|
var y: size.CellCountInt = self.row_idx;
|
||||||
var page = self.page;
|
var page = self.page;
|
||||||
while (page.prev) |prev| {
|
while (page.prev) |prev| {
|
||||||
y += prev.data.size.rows;
|
y += prev.data.size.rows;
|
||||||
@ -3402,7 +3407,7 @@ test "PageList pointFromPin traverse pages" {
|
|||||||
|
|
||||||
try testing.expectEqual(point.Point{
|
try testing.expectEqual(point.Point{
|
||||||
.screen = .{
|
.screen = .{
|
||||||
.y = expected_y,
|
.y = @intCast(expected_y),
|
||||||
.x = 2,
|
.x = 2,
|
||||||
},
|
},
|
||||||
}, s.pointFromPin(.screen, .{
|
}, s.pointFromPin(.screen, .{
|
||||||
@ -5629,7 +5634,7 @@ test "PageList resize (no reflow) more rows adds blank rows if cursor at bottom"
|
|||||||
|
|
||||||
// Go through our active, we should get only 3,4,5
|
// Go through our active, we should get only 3,4,5
|
||||||
for (0..3) |y| {
|
for (0..3) |y| {
|
||||||
const get = s.getCell(.{ .active = .{ .y = y } }).?;
|
const get = s.getCell(.{ .active = .{ .y = @intCast(y) } }).?;
|
||||||
const expected: u21 = @intCast(y + 2);
|
const expected: u21 = @intCast(y + 2);
|
||||||
try testing.expectEqual(expected, get.cell.content.codepoint);
|
try testing.expectEqual(expected, get.cell.content.codepoint);
|
||||||
}
|
}
|
||||||
@ -6557,7 +6562,7 @@ test "PageList resize reflow less cols no wrapped rows" {
|
|||||||
while (it.next()) |offset| {
|
while (it.next()) |offset| {
|
||||||
for (0..4) |x| {
|
for (0..4) |x| {
|
||||||
var offset_copy = offset;
|
var offset_copy = offset;
|
||||||
offset_copy.x = x;
|
offset_copy.x = @intCast(x);
|
||||||
const rac = offset_copy.rowAndCell();
|
const rac = offset_copy.rowAndCell();
|
||||||
const cells = offset.page.data.getCells(rac.row);
|
const cells = offset.page.data.getCells(rac.row);
|
||||||
try testing.expectEqual(@as(usize, 5), cells.len);
|
try testing.expectEqual(@as(usize, 5), cells.len);
|
||||||
@ -7247,7 +7252,7 @@ test "PageList resize reflow less cols copy style" {
|
|||||||
while (it.next()) |offset| {
|
while (it.next()) |offset| {
|
||||||
for (0..s.cols - 1) |x| {
|
for (0..s.cols - 1) |x| {
|
||||||
var offset_copy = offset;
|
var offset_copy = offset;
|
||||||
offset_copy.x = x;
|
offset_copy.x = @intCast(x);
|
||||||
const rac = offset_copy.rowAndCell();
|
const rac = offset_copy.rowAndCell();
|
||||||
const style_id = rac.cell.style_id;
|
const style_id = rac.cell.style_id;
|
||||||
try testing.expect(style_id != 0);
|
try testing.expect(style_id != 0);
|
||||||
|
@ -1412,8 +1412,8 @@ pub fn selectionString(self: *Screen, alloc: Allocator, opts: SelectionString) !
|
|||||||
if (mapbuilder) |*b| {
|
if (mapbuilder) |*b| {
|
||||||
for (0..encode_len) |_| try b.append(.{
|
for (0..encode_len) |_| try b.append(.{
|
||||||
.page = chunk.page,
|
.page = chunk.page,
|
||||||
.y = y,
|
.y = @intCast(y),
|
||||||
.x = x,
|
.x = @intCast(x),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1425,8 +1425,8 @@ pub fn selectionString(self: *Screen, alloc: Allocator, opts: SelectionString) !
|
|||||||
if (mapbuilder) |*b| {
|
if (mapbuilder) |*b| {
|
||||||
for (0..encode_len) |_| try b.append(.{
|
for (0..encode_len) |_| try b.append(.{
|
||||||
.page = chunk.page,
|
.page = chunk.page,
|
||||||
.y = y,
|
.y = @intCast(y),
|
||||||
.x = x,
|
.x = @intCast(x),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1441,7 +1441,7 @@ pub fn selectionString(self: *Screen, alloc: Allocator, opts: SelectionString) !
|
|||||||
try strbuilder.append('\n');
|
try strbuilder.append('\n');
|
||||||
if (mapbuilder) |*b| try b.append(.{
|
if (mapbuilder) |*b| try b.append(.{
|
||||||
.page = chunk.page,
|
.page = chunk.page,
|
||||||
.y = y,
|
.y = @intCast(y),
|
||||||
.x = chunk.page.data.size.cols - 1,
|
.x = chunk.page.data.size.cols - 1,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -3959,7 +3959,10 @@ test "Screen: resize (no reflow) less rows trims blank lines" {
|
|||||||
|
|
||||||
// Write only a background color into the remaining rows
|
// Write only a background color into the remaining rows
|
||||||
for (1..s.pages.rows) |y| {
|
for (1..s.pages.rows) |y| {
|
||||||
const list_cell = s.pages.getCell(.{ .active = .{ .x = 0, .y = y } }).?;
|
const list_cell = s.pages.getCell(.{ .active = .{
|
||||||
|
.x = 0,
|
||||||
|
.y = @intCast(y),
|
||||||
|
} }).?;
|
||||||
list_cell.cell.* = .{
|
list_cell.cell.* = .{
|
||||||
.content_tag = .bg_color_rgb,
|
.content_tag = .bg_color_rgb,
|
||||||
.content = .{ .color_rgb = .{ .r = 0xFF, .g = 0, .b = 0 } },
|
.content = .{ .color_rgb = .{ .r = 0xFF, .g = 0, .b = 0 } },
|
||||||
@ -3991,7 +3994,10 @@ test "Screen: resize (no reflow) more rows trims blank lines" {
|
|||||||
|
|
||||||
// Write only a background color into the remaining rows
|
// Write only a background color into the remaining rows
|
||||||
for (1..s.pages.rows) |y| {
|
for (1..s.pages.rows) |y| {
|
||||||
const list_cell = s.pages.getCell(.{ .active = .{ .x = 0, .y = y } }).?;
|
const list_cell = s.pages.getCell(.{ .active = .{
|
||||||
|
.x = 0,
|
||||||
|
.y = @intCast(y),
|
||||||
|
} }).?;
|
||||||
list_cell.cell.* = .{
|
list_cell.cell.* = .{
|
||||||
.content_tag = .bg_color_rgb,
|
.content_tag = .bg_color_rgb,
|
||||||
.content = .{ .color_rgb = .{ .r = 0xFF, .g = 0, .b = 0 } },
|
.content = .{ .color_rgb = .{ .r = 0xFF, .g = 0, .b = 0 } },
|
||||||
@ -4118,7 +4124,10 @@ test "Screen: resize (no reflow) more rows with soft wrapping" {
|
|||||||
|
|
||||||
// Every second row should be wrapped
|
// Every second row should be wrapped
|
||||||
for (0..6) |y| {
|
for (0..6) |y| {
|
||||||
const list_cell = s.pages.getCell(.{ .screen = .{ .x = 0, .y = y } }).?;
|
const list_cell = s.pages.getCell(.{ .screen = .{
|
||||||
|
.x = 0,
|
||||||
|
.y = @intCast(y),
|
||||||
|
} }).?;
|
||||||
const row = list_cell.row;
|
const row = list_cell.row;
|
||||||
const wrapped = (y % 2 == 0);
|
const wrapped = (y % 2 == 0);
|
||||||
try testing.expectEqual(wrapped, row.wrap);
|
try testing.expectEqual(wrapped, row.wrap);
|
||||||
@ -4135,7 +4144,10 @@ test "Screen: resize (no reflow) more rows with soft wrapping" {
|
|||||||
|
|
||||||
// Every second row should be wrapped
|
// Every second row should be wrapped
|
||||||
for (0..6) |y| {
|
for (0..6) |y| {
|
||||||
const list_cell = s.pages.getCell(.{ .screen = .{ .x = 0, .y = y } }).?;
|
const list_cell = s.pages.getCell(.{ .screen = .{
|
||||||
|
.x = 0,
|
||||||
|
.y = @intCast(y),
|
||||||
|
} }).?;
|
||||||
const row = list_cell.row;
|
const row = list_cell.row;
|
||||||
const wrapped = (y % 2 == 0);
|
const wrapped = (y % 2 == 0);
|
||||||
try testing.expectEqual(wrapped, row.wrap);
|
try testing.expectEqual(wrapped, row.wrap);
|
||||||
|
@ -435,7 +435,7 @@ pub fn adjust(
|
|||||||
const cells = next.page.data.getCells(rac.row);
|
const cells = next.page.data.getCells(rac.row);
|
||||||
if (page.Cell.hasTextAny(cells)) {
|
if (page.Cell.hasTextAny(cells)) {
|
||||||
end_pin.* = next;
|
end_pin.* = next;
|
||||||
end_pin.x = cells.len - 1;
|
end_pin.x = @intCast(cells.len - 1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4169,7 +4169,10 @@ test "Terminal: insertLines colors with bg color" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (0..t.cols) |x| {
|
for (0..t.cols) |x| {
|
||||||
const list_cell = t.screen.pages.getCell(.{ .active = .{ .x = x, .y = 1 } }).?;
|
const list_cell = t.screen.pages.getCell(.{ .active = .{
|
||||||
|
.x = @intCast(x),
|
||||||
|
.y = 1,
|
||||||
|
} }).?;
|
||||||
try testing.expect(list_cell.cell.content_tag == .bg_color_rgb);
|
try testing.expect(list_cell.cell.content_tag == .bg_color_rgb);
|
||||||
try testing.expectEqual(Cell.RGB{
|
try testing.expectEqual(Cell.RGB{
|
||||||
.r = 0xFF,
|
.r = 0xFF,
|
||||||
@ -5297,7 +5300,10 @@ test "Terminal: index bottom of primary screen background sgr" {
|
|||||||
defer testing.allocator.free(str);
|
defer testing.allocator.free(str);
|
||||||
try testing.expectEqualStrings("\n\n\nA", str);
|
try testing.expectEqualStrings("\n\n\nA", str);
|
||||||
for (0..5) |x| {
|
for (0..5) |x| {
|
||||||
const list_cell = t.screen.pages.getCell(.{ .active = .{ .x = x, .y = 4 } }).?;
|
const list_cell = t.screen.pages.getCell(.{ .active = .{
|
||||||
|
.x = @intCast(x),
|
||||||
|
.y = 4,
|
||||||
|
} }).?;
|
||||||
try testing.expect(list_cell.cell.content_tag == .bg_color_rgb);
|
try testing.expect(list_cell.cell.content_tag == .bg_color_rgb);
|
||||||
try testing.expectEqual(Cell.RGB{
|
try testing.expectEqual(Cell.RGB{
|
||||||
.r = 0xFF,
|
.r = 0xFF,
|
||||||
@ -5349,7 +5355,10 @@ test "Terminal: index bottom of scroll region with background SGR" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (0..t.cols) |x| {
|
for (0..t.cols) |x| {
|
||||||
const list_cell = t.screen.pages.getCell(.{ .active = .{ .x = x, .y = 2 } }).?;
|
const list_cell = t.screen.pages.getCell(.{ .active = .{
|
||||||
|
.x = @intCast(x),
|
||||||
|
.y = 2,
|
||||||
|
} }).?;
|
||||||
try testing.expect(list_cell.cell.content_tag == .bg_color_rgb);
|
try testing.expect(list_cell.cell.content_tag == .bg_color_rgb);
|
||||||
try testing.expectEqual(Cell.RGB{
|
try testing.expectEqual(Cell.RGB{
|
||||||
.r = 0xFF,
|
.r = 0xFF,
|
||||||
@ -5961,7 +5970,10 @@ test "Terminal: deleteLines colors with bg color" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (0..t.cols) |x| {
|
for (0..t.cols) |x| {
|
||||||
const list_cell = t.screen.pages.getCell(.{ .active = .{ .x = x, .y = 4 } }).?;
|
const list_cell = t.screen.pages.getCell(.{ .active = .{
|
||||||
|
.x = @intCast(x),
|
||||||
|
.y = 4,
|
||||||
|
} }).?;
|
||||||
try testing.expect(list_cell.cell.content_tag == .bg_color_rgb);
|
try testing.expect(list_cell.cell.content_tag == .bg_color_rgb);
|
||||||
try testing.expectEqual(Cell.RGB{
|
try testing.expectEqual(Cell.RGB{
|
||||||
.r = 0xFF,
|
.r = 0xFF,
|
||||||
@ -6148,7 +6160,10 @@ test "Terminal: deleteLines resets wrap" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (0..t.rows) |y| {
|
for (0..t.rows) |y| {
|
||||||
const list_cell = t.screen.pages.getCell(.{ .active = .{ .x = 0, .y = y } }).?;
|
const list_cell = t.screen.pages.getCell(.{ .active = .{
|
||||||
|
.x = 0,
|
||||||
|
.y = @intCast(y),
|
||||||
|
} }).?;
|
||||||
const row = list_cell.row;
|
const row = list_cell.row;
|
||||||
try testing.expect(!row.wrap);
|
try testing.expect(!row.wrap);
|
||||||
}
|
}
|
||||||
@ -7183,7 +7198,10 @@ test "Terminal: deleteChars preserves background sgr" {
|
|||||||
try testing.expectEqualStrings("AB23", str);
|
try testing.expectEqualStrings("AB23", str);
|
||||||
}
|
}
|
||||||
for (t.cols - 2..t.cols) |x| {
|
for (t.cols - 2..t.cols) |x| {
|
||||||
const list_cell = t.screen.pages.getCell(.{ .active = .{ .x = x, .y = 0 } }).?;
|
const list_cell = t.screen.pages.getCell(.{ .active = .{
|
||||||
|
.x = @intCast(x),
|
||||||
|
.y = 0,
|
||||||
|
} }).?;
|
||||||
try testing.expect(list_cell.cell.content_tag == .bg_color_rgb);
|
try testing.expect(list_cell.cell.content_tag == .bg_color_rgb);
|
||||||
try testing.expectEqual(Cell.RGB{
|
try testing.expectEqual(Cell.RGB{
|
||||||
.r = 0xFF,
|
.r = 0xFF,
|
||||||
@ -7573,7 +7591,10 @@ test "Terminal: eraseLine right preserves background sgr" {
|
|||||||
defer testing.allocator.free(str);
|
defer testing.allocator.free(str);
|
||||||
try testing.expectEqualStrings("A", str);
|
try testing.expectEqualStrings("A", str);
|
||||||
for (1..5) |x| {
|
for (1..5) |x| {
|
||||||
const list_cell = t.screen.pages.getCell(.{ .active = .{ .x = x, .y = 0 } }).?;
|
const list_cell = t.screen.pages.getCell(.{ .active = .{
|
||||||
|
.x = @intCast(x),
|
||||||
|
.y = 0,
|
||||||
|
} }).?;
|
||||||
try testing.expect(list_cell.cell.content_tag == .bg_color_rgb);
|
try testing.expect(list_cell.cell.content_tag == .bg_color_rgb);
|
||||||
try testing.expectEqual(Cell.RGB{
|
try testing.expectEqual(Cell.RGB{
|
||||||
.r = 0xFF,
|
.r = 0xFF,
|
||||||
@ -7727,7 +7748,10 @@ test "Terminal: eraseLine left preserves background sgr" {
|
|||||||
defer testing.allocator.free(str);
|
defer testing.allocator.free(str);
|
||||||
try testing.expectEqualStrings(" CDE", str);
|
try testing.expectEqualStrings(" CDE", str);
|
||||||
for (0..2) |x| {
|
for (0..2) |x| {
|
||||||
const list_cell = t.screen.pages.getCell(.{ .active = .{ .x = x, .y = 0 } }).?;
|
const list_cell = t.screen.pages.getCell(.{ .active = .{
|
||||||
|
.x = @intCast(x),
|
||||||
|
.y = 0,
|
||||||
|
} }).?;
|
||||||
try testing.expect(list_cell.cell.content_tag == .bg_color_rgb);
|
try testing.expect(list_cell.cell.content_tag == .bg_color_rgb);
|
||||||
try testing.expectEqual(Cell.RGB{
|
try testing.expectEqual(Cell.RGB{
|
||||||
.r = 0xFF,
|
.r = 0xFF,
|
||||||
@ -7847,7 +7871,10 @@ test "Terminal: eraseLine complete preserves background sgr" {
|
|||||||
defer testing.allocator.free(str);
|
defer testing.allocator.free(str);
|
||||||
try testing.expectEqualStrings("", str);
|
try testing.expectEqualStrings("", str);
|
||||||
for (0..5) |x| {
|
for (0..5) |x| {
|
||||||
const list_cell = t.screen.pages.getCell(.{ .active = .{ .x = x, .y = 0 } }).?;
|
const list_cell = t.screen.pages.getCell(.{ .active = .{
|
||||||
|
.x = @intCast(x),
|
||||||
|
.y = 0,
|
||||||
|
} }).?;
|
||||||
try testing.expect(list_cell.cell.content_tag == .bg_color_rgb);
|
try testing.expect(list_cell.cell.content_tag == .bg_color_rgb);
|
||||||
try testing.expectEqual(Cell.RGB{
|
try testing.expectEqual(Cell.RGB{
|
||||||
.r = 0xFF,
|
.r = 0xFF,
|
||||||
@ -8096,7 +8123,10 @@ test "Terminal: eraseDisplay erase below preserves SGR bg" {
|
|||||||
defer testing.allocator.free(str);
|
defer testing.allocator.free(str);
|
||||||
try testing.expectEqualStrings("ABC\nD", str);
|
try testing.expectEqualStrings("ABC\nD", str);
|
||||||
for (1..5) |x| {
|
for (1..5) |x| {
|
||||||
const list_cell = t.screen.pages.getCell(.{ .active = .{ .x = x, .y = 1 } }).?;
|
const list_cell = t.screen.pages.getCell(.{ .active = .{
|
||||||
|
.x = @intCast(x),
|
||||||
|
.y = 1,
|
||||||
|
} }).?;
|
||||||
try testing.expect(list_cell.cell.content_tag == .bg_color_rgb);
|
try testing.expect(list_cell.cell.content_tag == .bg_color_rgb);
|
||||||
try testing.expectEqual(Cell.RGB{
|
try testing.expectEqual(Cell.RGB{
|
||||||
.r = 0xFF,
|
.r = 0xFF,
|
||||||
@ -8271,7 +8301,10 @@ test "Terminal: eraseDisplay erase above preserves SGR bg" {
|
|||||||
defer testing.allocator.free(str);
|
defer testing.allocator.free(str);
|
||||||
try testing.expectEqualStrings("\n F\nGHI", str);
|
try testing.expectEqualStrings("\n F\nGHI", str);
|
||||||
for (0..2) |x| {
|
for (0..2) |x| {
|
||||||
const list_cell = t.screen.pages.getCell(.{ .active = .{ .x = x, .y = 1 } }).?;
|
const list_cell = t.screen.pages.getCell(.{ .active = .{
|
||||||
|
.x = @intCast(x),
|
||||||
|
.y = 1,
|
||||||
|
} }).?;
|
||||||
try testing.expect(list_cell.cell.content_tag == .bg_color_rgb);
|
try testing.expect(list_cell.cell.content_tag == .bg_color_rgb);
|
||||||
try testing.expectEqual(Cell.RGB{
|
try testing.expectEqual(Cell.RGB{
|
||||||
.r = 0xFF,
|
.r = 0xFF,
|
||||||
|
@ -5,6 +5,7 @@ const ArenaAllocator = std.heap.ArenaAllocator;
|
|||||||
|
|
||||||
const terminal = @import("../main.zig");
|
const terminal = @import("../main.zig");
|
||||||
const point = @import("../point.zig");
|
const point = @import("../point.zig");
|
||||||
|
const size = @import("../size.zig");
|
||||||
const command = @import("graphics_command.zig");
|
const command = @import("graphics_command.zig");
|
||||||
const PageList = @import("../PageList.zig");
|
const PageList = @import("../PageList.zig");
|
||||||
const Screen = @import("../Screen.zig");
|
const Screen = @import("../Screen.zig");
|
||||||
@ -265,13 +266,13 @@ pub const ImageStorage = struct {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
.intersect_cell => |v| {
|
.intersect_cell => |v| intersect_cell: {
|
||||||
self.deleteIntersecting(
|
self.deleteIntersecting(
|
||||||
alloc,
|
alloc,
|
||||||
t,
|
t,
|
||||||
.{ .active = .{
|
.{ .active = .{
|
||||||
.x = v.x,
|
.x = std.math.cast(size.CellCountInt, v.x) orelse break :intersect_cell,
|
||||||
.y = v.y,
|
.y = std.math.cast(size.CellCountInt, v.y) orelse break :intersect_cell,
|
||||||
} },
|
} },
|
||||||
v.delete,
|
v.delete,
|
||||||
{},
|
{},
|
||||||
@ -279,13 +280,13 @@ pub const ImageStorage = struct {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
.intersect_cell_z => |v| {
|
.intersect_cell_z => |v| intersect_cell_z: {
|
||||||
self.deleteIntersecting(
|
self.deleteIntersecting(
|
||||||
alloc,
|
alloc,
|
||||||
t,
|
t,
|
||||||
.{ .active = .{
|
.{ .active = .{
|
||||||
.x = v.x,
|
.x = std.math.cast(size.CellCountInt, v.x) orelse break :intersect_cell_z,
|
||||||
.y = v.y,
|
.y = std.math.cast(size.CellCountInt, v.y) orelse break :intersect_cell_z,
|
||||||
} },
|
} },
|
||||||
v.delete,
|
v.delete,
|
||||||
v.z,
|
v.z,
|
||||||
@ -317,7 +318,7 @@ pub const ImageStorage = struct {
|
|||||||
// v.y is in active coords so we want to convert it to a pin
|
// v.y is in active coords so we want to convert it to a pin
|
||||||
// so we can compare by page offsets.
|
// so we can compare by page offsets.
|
||||||
const target_pin = t.screen.pages.pin(.{ .active = .{
|
const target_pin = t.screen.pages.pin(.{ .active = .{
|
||||||
.y = v.y,
|
.y = std.math.cast(size.CellCountInt, v.y) orelse break :row,
|
||||||
} }) orelse break :row;
|
} }) orelse break :row;
|
||||||
|
|
||||||
var it = self.placements.iterator();
|
var it = self.placements.iterator();
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const Allocator = std.mem.Allocator;
|
const Allocator = std.mem.Allocator;
|
||||||
const assert = std.debug.assert;
|
const assert = std.debug.assert;
|
||||||
|
const size = @import("size.zig");
|
||||||
|
|
||||||
/// The possible reference locations for a point. When someone says "(42, 80)" in the context of a terminal, that could mean multiple
|
/// The possible reference locations for a point. When someone says "(42, 80)" in the context of a terminal, that could mean multiple
|
||||||
/// things: it is in the current visible viewport? the current active
|
/// things: it is in the current visible viewport? the current active
|
||||||
@ -65,8 +66,8 @@ pub const Point = union(Tag) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub const Coordinate = struct {
|
pub const Coordinate = struct {
|
||||||
x: usize = 0,
|
x: size.CellCountInt = 0,
|
||||||
y: usize = 0,
|
y: size.CellCountInt = 0,
|
||||||
|
|
||||||
pub fn eql(self: Coordinate, other: Coordinate) bool {
|
pub fn eql(self: Coordinate, other: Coordinate) bool {
|
||||||
return self.x == other.x and self.y == other.y;
|
return self.x == other.x and self.y == other.y;
|
||||||
|
Reference in New Issue
Block a user