typing jumps scroll to bottom

This commit is contained in:
Mitchell Hashimoto
2022-07-12 21:07:58 -07:00
parent 354f2a73c9
commit dcc5fe34cf
3 changed files with 60 additions and 0 deletions

View File

@ -1,6 +1,8 @@
Bugs:
* Underline should use freetype underline thickness hint
* Any printing action forces scroll to jump to bottom, this makes it impossible
to scroll up while logs are coming in or something
Performance:

View File

@ -121,6 +121,15 @@ pub fn deinit(self: *Screen, alloc: Allocator) void {
self.* = undefined;
}
/// This returns true if the display area is anchored at the bottom currently.
pub fn displayIsBottom(self: Screen) bool {
return self.visible_offset == self.bottomOffset();
}
fn bottomOffset(self: Screen) usize {
return self.bottom - self.rows;
}
/// Returns an iterator that can be used to iterate over all of the rows
/// from index zero.
pub fn rowIterator(self: *const Screen) RowIterator {
@ -429,7 +438,12 @@ test "Screen: scrolling" {
var s = try init(alloc, 3, 5, 0);
defer s.deinit(alloc);
s.testWriteString("1ABCD\n2EFGH\n3IJKL");
try testing.expect(s.displayIsBottom());
// Scroll down, should still be bottom
s.scroll(.{ .delta = 1 });
try testing.expect(s.displayIsBottom());
// Test our row index
try testing.expectEqual(@as(usize, 5), s.rowIndex(0));
@ -462,6 +476,7 @@ test "Screen: scroll down from 0" {
defer s.deinit(alloc);
s.testWriteString("1ABCD\n2EFGH\n3IJKL");
s.scroll(.{ .delta = -1 });
try testing.expect(s.displayIsBottom());
{
// Test our contents rotated
@ -494,6 +509,7 @@ test "Screen: scrollback" {
// Scrolling to the bottom
s.scroll(.{ .bottom = {} });
try testing.expect(s.displayIsBottom());
{
// Test our contents rotated
@ -504,6 +520,7 @@ test "Screen: scrollback" {
// Scrolling back should make it visible again
s.scroll(.{ .delta = -1 });
try testing.expect(!s.displayIsBottom());
{
// Test our contents rotated

View File

@ -203,6 +203,9 @@ pub fn print(self: *Terminal, c: u21) !void {
const tracy = trace(@src());
defer tracy.end();
// If we're not at the bottom, then we need to move there
if (!self.screen.displayIsBottom()) self.screen.scroll(.{ .bottom = {} });
// If we're soft-wrapping, then handle that first.
if (self.cursor.pending_wrap and self.mode_autowrap) {
// Mark that the cell is wrapped, which guarantees that there is
@ -691,12 +694,15 @@ pub fn scrollDown(self: *Terminal, count: usize) void {
/// Options for scrolling the viewport of the terminal grid.
pub const ScrollViewport = union(enum) {
/// Scroll to the top of the scrollback
top: void,
delta: isize,
};
/// Scroll the viewport of the terminal grid.
pub fn scrollViewport(self: *Terminal, behavior: ScrollViewport) void {
self.screen.scroll(switch (behavior) {
.top => .{ .top = {} },
.delta => |delta| .{ .delta_no_grow = delta },
});
}
@ -766,6 +772,41 @@ test "Terminal: soft wrap" {
}
}
test "Terminal: print scrolls back to bottom" {
var t = try init(testing.allocator, 5, 2);
defer t.deinit(testing.allocator);
// Basic grid writing
for ("hello") |c| try t.print(c);
// Make newlines so we create scrollback
// 3 pushes hello off the screen
t.index();
t.index();
t.index();
{
var str = try t.plainString(testing.allocator);
defer testing.allocator.free(str);
try testing.expectEqualStrings("", str);
}
// Scroll to the top
t.scrollViewport(.{ .top = {} });
{
var str = try t.plainString(testing.allocator);
defer testing.allocator.free(str);
try testing.expectEqualStrings("hello", str);
}
// Type
try t.print('A');
{
var str = try t.plainString(testing.allocator);
defer testing.allocator.free(str);
try testing.expectEqualStrings("\nA", str);
}
}
test "Terminal: linefeed and carriage return" {
var t = try init(testing.allocator, 80, 80);
defer t.deinit(testing.allocator);