implement scroll behavior for reverse index, add conformance

This commit is contained in:
Mitchell Hashimoto
2022-05-09 20:39:22 -07:00
parent 354ed6c21a
commit 32ccfee94f
2 changed files with 55 additions and 8 deletions

View File

@ -1,10 +1,25 @@
//! Reverse Index (RI) - ESC M at the top of the screen.
//! Reverse Index (RI) - ESC M
//! Case: test that if the cursor is at the top, it scrolls down.
const std = @import("std");
pub fn main() !void {
const stdout = std.io.getStdOut().writer();
try stdout.print("\x1B[H", .{}); // move to top-left
try stdout.print("\x1B[J", .{}); // clear screen
try stdout.print("\x1BM", .{});
try stdout.print("D\n", .{});
try stdout.print("A\nB\n", .{});
try stdout.print("\x0D", .{}); // CR
try stdout.print("\x0A", .{}); // LF
try stdout.print("\x1B[H", .{}); // Top-left
try stdout.print("\x1BM", .{}); // Reverse-Index
try stdout.print("D", .{});
try stdout.print("\x0D", .{}); // CR
try stdout.print("\x0A", .{}); // LF
try stdout.print("\x1B[H", .{}); // Top-left
try stdout.print("\x1BM", .{}); // Reverse-Index
try stdout.print("E", .{});
try stdout.print("\n", .{});
// const stdin = std.io.getStdIn().reader();
// _ = try stdin.readByte();
}

View File

@ -131,6 +131,7 @@ pub fn appendChar(self: *Terminal, alloc: Allocator, c: u8) !void {
//log.debug("char: {}", .{c});
const actions = self.parser.next(c);
for (actions) |action_opt| {
if (action_opt) |action| log.info("action: {}", .{action});
switch (action_opt orelse continue) {
.print => |p| try self.print(alloc, p),
.execute => |code| try self.execute(alloc, code),
@ -267,7 +268,7 @@ fn escDispatch(
switch (action.final) {
// RI - Reverse Index
'M' => switch (action.intermediates.len) {
0 => self.reverseIndex(),
0 => try self.reverseIndex(alloc),
else => {
log.warn("invalid reverse index command: {}", .{action});
return;
@ -331,8 +332,11 @@ pub fn selectGraphicRendition(self: *Terminal, aspect: ansi.RenditionAspect) !vo
}
// TODO: test
pub fn reverseIndex(self: *Terminal) void {
self.cursor.y -|= 1;
pub fn reverseIndex(self: *Terminal, alloc: Allocator) !void {
if (self.cursor.y == 0)
try self.scrollDown(alloc)
else
self.cursor.y -|= 1;
}
// Set Cursor Position. Move cursor to the position indicated
@ -535,6 +539,34 @@ pub fn scrollUp(self: *Terminal, alloc: Allocator) void {
self.screen.items.len -= 1;
}
/// Scroll the text down by one row.
/// TODO: test
pub fn scrollDown(self: *Terminal, alloc: Allocator) !void {
const tracy = trace(@src());
defer tracy.end();
// TODO: this is horribly expensive. we need to optimize the screen repr
// We need space for one more row if we aren't at the max.
if (self.screen.capacity < self.rows) {
try self.screen.ensureTotalCapacity(alloc, self.screen.items.len + 1);
}
// Add one more item if we aren't at the max
if (self.screen.items.len < self.rows) {
self.screen.items.len += 1;
}
// Shift everything down
var i: usize = self.screen.items.len - 1;
while (i > 0) : (i -= 1) {
self.screen.items[i] = self.screen.items[i - 1];
}
// Clear this row
self.screen.items[0] = .{};
}
fn getOrPutCell(self: *Terminal, alloc: Allocator, x: usize, y: usize) !*Cell {
const tracy = trace(@src());
defer tracy.end();