mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-14 07:46:12 +03:00
Merge pull request #1160 from mitchellh/cursor-scroll
terminal: resize cols should treat old cursor pos as active point
This commit is contained in:
@ -2734,7 +2734,7 @@ pub fn resize(self: *Screen, rows: usize, cols: usize) !void {
|
||||
|
||||
// Convert our cursor coordinates to screen coordinates because
|
||||
// we may have to reflow the cursor if the line it is on is unwrapped.
|
||||
const cursor_pos = (point.Viewport{
|
||||
const cursor_pos = (point.Active{
|
||||
.x = old.cursor.x,
|
||||
.y = old.cursor.y,
|
||||
}).toScreen(&old);
|
||||
@ -2948,7 +2948,7 @@ pub fn resize(self: *Screen, rows: usize, cols: usize) !void {
|
||||
|
||||
// Convert our cursor coordinates to screen coordinates because
|
||||
// we may have to reflow the cursor if the line it is on is moved.
|
||||
const cursor_pos = (point.Viewport{
|
||||
const cursor_pos = (point.Active{
|
||||
.x = old.cursor.x,
|
||||
.y = old.cursor.y,
|
||||
}).toScreen(&old);
|
||||
@ -6372,6 +6372,72 @@ test "Screen: resize more cols perfect split" {
|
||||
try s.resize(3, 10);
|
||||
}
|
||||
|
||||
// https://github.com/mitchellh/ghostty/issues/1159
|
||||
test "Screen: resize (no reflow) more cols with scrollback scrolled up" {
|
||||
const testing = std.testing;
|
||||
const alloc = testing.allocator;
|
||||
|
||||
var s = try init(alloc, 3, 5, 5);
|
||||
defer s.deinit();
|
||||
const str = "1\n2\n3\n4\n5\n6\n7\n8";
|
||||
try s.testWriteString(str);
|
||||
|
||||
// Cursor at bottom
|
||||
try testing.expectEqual(@as(usize, 1), s.cursor.x);
|
||||
try testing.expectEqual(@as(usize, 2), s.cursor.y);
|
||||
|
||||
try s.scroll(.{ .viewport = -4 });
|
||||
{
|
||||
const contents = try s.testString(alloc, .viewport);
|
||||
defer alloc.free(contents);
|
||||
try testing.expectEqualStrings("2\n3\n4", contents);
|
||||
}
|
||||
|
||||
try s.resize(3, 8);
|
||||
{
|
||||
const contents = try s.testString(alloc, .screen);
|
||||
defer alloc.free(contents);
|
||||
try testing.expectEqualStrings(str, contents);
|
||||
}
|
||||
|
||||
// Cursor remains at bottom
|
||||
try testing.expectEqual(@as(usize, 1), s.cursor.x);
|
||||
try testing.expectEqual(@as(usize, 2), s.cursor.y);
|
||||
}
|
||||
|
||||
// https://github.com/mitchellh/ghostty/issues/1159
|
||||
test "Screen: resize (no reflow) less cols with scrollback scrolled up" {
|
||||
const testing = std.testing;
|
||||
const alloc = testing.allocator;
|
||||
|
||||
var s = try init(alloc, 3, 5, 5);
|
||||
defer s.deinit();
|
||||
const str = "1\n2\n3\n4\n5\n6\n7\n8";
|
||||
try s.testWriteString(str);
|
||||
|
||||
// Cursor at bottom
|
||||
try testing.expectEqual(@as(usize, 1), s.cursor.x);
|
||||
try testing.expectEqual(@as(usize, 2), s.cursor.y);
|
||||
|
||||
try s.scroll(.{ .viewport = -4 });
|
||||
{
|
||||
const contents = try s.testString(alloc, .viewport);
|
||||
defer alloc.free(contents);
|
||||
try testing.expectEqualStrings("2\n3\n4", contents);
|
||||
}
|
||||
|
||||
try s.resize(3, 4);
|
||||
{
|
||||
const contents = try s.testString(alloc, .screen);
|
||||
defer alloc.free(contents);
|
||||
try testing.expectEqualStrings(str, contents);
|
||||
}
|
||||
|
||||
// Cursor remains at bottom
|
||||
try testing.expectEqual(@as(usize, 1), s.cursor.x);
|
||||
try testing.expectEqual(@as(usize, 2), s.cursor.y);
|
||||
}
|
||||
|
||||
test "Screen: resize more cols no reflow preserves semantic prompt" {
|
||||
const testing = std.testing;
|
||||
const alloc = testing.allocator;
|
||||
|
@ -6,6 +6,34 @@ const Screen = terminal.Screen;
|
||||
// use different types so that we can lean on type-safety to get the
|
||||
// exact expected type of point.
|
||||
|
||||
/// Active is a point within the active part of the screen.
|
||||
pub const Active = struct {
|
||||
x: usize = 0,
|
||||
y: usize = 0,
|
||||
|
||||
pub fn toScreen(self: Active, screen: *const Screen) ScreenPoint {
|
||||
return .{
|
||||
.x = self.x,
|
||||
.y = screen.history + self.y,
|
||||
};
|
||||
}
|
||||
|
||||
test "toScreen with scrollback" {
|
||||
const testing = std.testing;
|
||||
const alloc = testing.allocator;
|
||||
|
||||
var s = try Screen.init(alloc, 3, 5, 3);
|
||||
defer s.deinit();
|
||||
const str = "1\n2\n3\n4\n5\n6\n7\n8";
|
||||
try s.testWriteString(str);
|
||||
|
||||
try testing.expectEqual(ScreenPoint{
|
||||
.x = 1,
|
||||
.y = 5,
|
||||
}, (Active{ .x = 1, .y = 2 }).toScreen(&s));
|
||||
}
|
||||
};
|
||||
|
||||
/// Viewport is a point within the viewport of the screen.
|
||||
pub const Viewport = struct {
|
||||
x: usize = 0,
|
||||
|
Reference in New Issue
Block a user