basic "index" implementation

This commit is contained in:
Mitchell Hashimoto
2022-06-24 17:47:43 -07:00
parent f7aca2e493
commit 55db659d2b
2 changed files with 74 additions and 24 deletions

View File

@ -195,6 +195,33 @@ pub fn decaln(self: *Terminal) void {
}
}
/// Move the cursor to the next line in the scrolling region, possibly scrolling.
///
/// If the cursor is outside of the scrolling region: move the cursor one line
/// down if it is not on the bottom-most line of the screen.
///
/// If the cursor is inside the scrolling region:
/// If the cursor is on the bottom-most line of the scrolling region:
/// invoke scroll up with amount=1
/// If the cursor is not on the bottom-most line of the scrolling region:
/// move the cursor one line down
///
/// This unsets the pending wrap state without wrapping.
pub fn index(self: *Terminal) void {
// TODO: outside of scrolling region
// If we're at the end of the screen, scroll up. This is surprisingly
// common because most terminals live with a full screen so we do this
// check first.
if (self.cursor.y == self.rows - 1) {
self.scrollUp();
return;
}
// Increase cursor by 1
self.cursor.y += 1;
}
/// Move the cursor to the previous line in the scrolling region, possibly
/// scrolling.
///
@ -468,19 +495,7 @@ pub fn carriageReturn(self: *Terminal) void {
/// Linefeed moves the cursor to the next line.
pub fn linefeed(self: *Terminal) void {
const tracy = trace(@src());
defer tracy.end();
// If we're at the end of the screen, scroll up. This is surprisingly
// common because most terminals live with a full screen so we do this
// check first.
if (self.cursor.y == self.rows - 1) {
self.scrollUp();
return;
}
// Increase cursor by 1
self.cursor.y += 1;
self.index();
}
/// Insert amount lines at the current cursor row. The contents of the line
@ -998,6 +1013,39 @@ test "Terminal: reverseIndex from the top" {
}
}
test "Terminal: index" {
const alloc = testing.allocator;
var t = try init(alloc, 2, 5);
defer t.deinit(alloc);
t.index();
try t.print('A');
{
var str = try t.plainString(testing.allocator);
defer testing.allocator.free(str);
try testing.expectEqualStrings("\nA", str);
}
}
test "Terminal: index from the bottom" {
const alloc = testing.allocator;
var t = try init(alloc, 2, 5);
defer t.deinit(alloc);
t.setCursorPos(5, 1);
try t.print('A');
t.index();
try t.print('B');
{
var str = try t.plainString(testing.allocator);
defer testing.allocator.free(str);
try testing.expectEqualStrings("\n\n\nA\nB", str);
}
}
test "Terminal: DECALN" {
const alloc = testing.allocator;
var t = try init(alloc, 2, 2);

View File

@ -97,7 +97,19 @@ pub fn Stream(comptime Handler: type) type {
}
}
fn csiDispatch(self: *Self, action: Parser.Action.CSI) !void {
fn csiDispatch(self: *Self, input: Parser.Action.CSI) !void {
// Handles aliases first
const action = switch (input.final) {
// Alias for set cursor position
'f' => blk: {
var copy = input;
copy.final = 'H';
break :blk copy;
},
else => input,
};
switch (action.final) {
// CUU - Cursor Up
'A' => if (@hasDecl(T, "setCursorUp")) try self.handler.setCursorUp(
@ -281,16 +293,6 @@ pub fn Stream(comptime Handler: type) type {
},
) else log.warn("unimplemented CSI callback: {}", .{action}),
// Alias for set cursor position (H)
'f' => {
var alias = action;
alias.final = 'H';
// Try would be better here but recursive try on
// inferred error sets are not allowed.
return self.csiDispatch(alias);
},
// SM - Set Mode
'h' => if (@hasDecl(T, "setMode")) {
for (action.params) |mode|