mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-16 16:56:09 +03:00
resize increasing column width without reflow
This commit is contained in:
@ -444,12 +444,12 @@ pub fn copyRow(self: *Screen, dst: usize, src: usize) void {
|
|||||||
pub fn resize2(self: *Screen, alloc: Allocator, rows: usize, cols: usize) !void {
|
pub fn resize2(self: *Screen, alloc: Allocator, rows: usize, cols: usize) !void {
|
||||||
_ = cols;
|
_ = cols;
|
||||||
|
|
||||||
// We always grow first so we don't lose any data.
|
// If the rows increased, we alloc space for the new rows (w/ existing cols)
|
||||||
var storage = self.storage;
|
// and move the viewport such that the bottom is in view.
|
||||||
if (rows > self.rows) {
|
if (rows > self.rows) {
|
||||||
storage = try alloc.alloc(
|
var storage = try alloc.alloc(
|
||||||
Cell,
|
Cell,
|
||||||
(rows + self.max_scrollback) * cols,
|
(rows + self.max_scrollback) * self.cols,
|
||||||
);
|
);
|
||||||
|
|
||||||
// Copy our screen into the new storage area. Since we're growing
|
// Copy our screen into the new storage area. Since we're growing
|
||||||
@ -474,6 +474,44 @@ pub fn resize2(self: *Screen, alloc: Allocator, rows: usize, cols: usize) !void
|
|||||||
self.bottom = @maximum(rows, self.bottom);
|
self.bottom = @maximum(rows, self.bottom);
|
||||||
self.scroll(.{ .bottom = {} });
|
self.scroll(.{ .bottom = {} });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If our columns increased, we alloc space for the new column width
|
||||||
|
// and go through each row and reflow if necessary.
|
||||||
|
if (cols > self.cols) {
|
||||||
|
var storage = try alloc.alloc(
|
||||||
|
Cell,
|
||||||
|
(self.rows + self.max_scrollback) * cols,
|
||||||
|
);
|
||||||
|
std.mem.set(Cell, storage, .{ .char = 0 });
|
||||||
|
|
||||||
|
// Nothing can fail from this point forward (no "try" expressions)
|
||||||
|
// so replace our storage. We defer freeing the "old" value because
|
||||||
|
// we need to access the old screen to copy.
|
||||||
|
var old = self.*;
|
||||||
|
defer {
|
||||||
|
assert(old.storage.ptr != self.storage.ptr);
|
||||||
|
old.deinit(alloc);
|
||||||
|
}
|
||||||
|
self.storage = storage;
|
||||||
|
self.cols = cols;
|
||||||
|
|
||||||
|
// Iterate over the screen since we need to check for reflow.
|
||||||
|
var iter = old.rowIterator(.screen);
|
||||||
|
var y: usize = 0;
|
||||||
|
while (iter.next()) |row| {
|
||||||
|
// No matter what we copy this row
|
||||||
|
var new_row = self.getRow(.{ .screen = y });
|
||||||
|
std.mem.copy(Cell, new_row, row);
|
||||||
|
|
||||||
|
// If no reflow, just keep going
|
||||||
|
if (row[row.len - 1].attrs.wrap == 0) {
|
||||||
|
y += 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
@panic("REFLOW");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Resize the screen. The rows or cols can be bigger or smaller. This
|
/// Resize the screen. The rows or cols can be bigger or smaller. This
|
||||||
@ -1144,6 +1182,7 @@ test "Screen: resize more rows with empty scrollback" {
|
|||||||
const str = "1ABCD\n2EFGH\n3IJKL";
|
const str = "1ABCD\n2EFGH\n3IJKL";
|
||||||
s.testWriteString(str);
|
s.testWriteString(str);
|
||||||
try s.resize2(alloc, 10, 5);
|
try s.resize2(alloc, 10, 5);
|
||||||
|
try testing.expectEqual(@as(usize, 20), s.totalRows());
|
||||||
|
|
||||||
{
|
{
|
||||||
var contents = try s.testString(alloc, .viewport);
|
var contents = try s.testString(alloc, .viewport);
|
||||||
@ -1174,6 +1213,7 @@ test "Screen: resize more rows with populated scrollback" {
|
|||||||
|
|
||||||
// Resize
|
// Resize
|
||||||
try s.resize2(alloc, 10, 5);
|
try s.resize2(alloc, 10, 5);
|
||||||
|
try testing.expectEqual(@as(usize, 15), s.totalRows());
|
||||||
|
|
||||||
{
|
{
|
||||||
var contents = try s.testString(alloc, .viewport);
|
var contents = try s.testString(alloc, .viewport);
|
||||||
@ -1181,3 +1221,51 @@ test "Screen: resize more rows with populated scrollback" {
|
|||||||
try testing.expectEqualStrings(str, contents);
|
try testing.expectEqualStrings(str, contents);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test "Screen: resize more cols no reflow" {
|
||||||
|
const testing = std.testing;
|
||||||
|
const alloc = testing.allocator;
|
||||||
|
|
||||||
|
var s = try init(alloc, 3, 5, 0);
|
||||||
|
defer s.deinit(alloc);
|
||||||
|
const str = "1ABCD\n2EFGH\n3IJKL";
|
||||||
|
s.testWriteString(str);
|
||||||
|
try s.resize2(alloc, 3, 10);
|
||||||
|
|
||||||
|
{
|
||||||
|
var contents = try s.testString(alloc, .viewport);
|
||||||
|
defer alloc.free(contents);
|
||||||
|
try testing.expectEqualStrings(str, contents);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
var contents = try s.testString(alloc, .screen);
|
||||||
|
defer alloc.free(contents);
|
||||||
|
try testing.expectEqualStrings(str, contents);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// test "Screen: resize more cols with reflow that fits full width" {
|
||||||
|
// const testing = std.testing;
|
||||||
|
// const alloc = testing.allocator;
|
||||||
|
//
|
||||||
|
// var s = try init(alloc, 3, 5, 0);
|
||||||
|
// defer s.deinit(alloc);
|
||||||
|
// const str = "1ABCD2EFGH\n3IJKL";
|
||||||
|
// s.testWriteString(str);
|
||||||
|
//
|
||||||
|
// // Verify we soft wrapped
|
||||||
|
// {
|
||||||
|
// var contents = try s.testString(alloc, .viewport);
|
||||||
|
// defer alloc.free(contents);
|
||||||
|
// const expected = "1ABCD\n2EFGH\n3IJKL";
|
||||||
|
// try testing.expectEqualStrings(expected, contents);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // Resize and verify we undid the soft wrap because we have space now
|
||||||
|
// try s.resize2(alloc, 3, 10);
|
||||||
|
// {
|
||||||
|
// var contents = try s.testString(alloc, .viewport);
|
||||||
|
// defer alloc.free(contents);
|
||||||
|
// try testing.expectEqualStrings(str, contents);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
Reference in New Issue
Block a user