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"); const std = @import("std");
pub fn main() !void { pub fn main() !void {
const stdout = std.io.getStdOut().writer(); const stdout = std.io.getStdOut().writer();
try stdout.print("\x1B[H", .{}); // move to top-left try stdout.print("A\nB\n", .{});
try stdout.print("\x1B[J", .{}); // clear screen
try stdout.print("\x1BM", .{}); try stdout.print("\x0D", .{}); // CR
try stdout.print("D\n", .{}); 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}); //log.debug("char: {}", .{c});
const actions = self.parser.next(c); const actions = self.parser.next(c);
for (actions) |action_opt| { for (actions) |action_opt| {
if (action_opt) |action| log.info("action: {}", .{action});
switch (action_opt orelse continue) { switch (action_opt orelse continue) {
.print => |p| try self.print(alloc, p), .print => |p| try self.print(alloc, p),
.execute => |code| try self.execute(alloc, code), .execute => |code| try self.execute(alloc, code),
@ -267,7 +268,7 @@ fn escDispatch(
switch (action.final) { switch (action.final) {
// RI - Reverse Index // RI - Reverse Index
'M' => switch (action.intermediates.len) { 'M' => switch (action.intermediates.len) {
0 => self.reverseIndex(), 0 => try self.reverseIndex(alloc),
else => { else => {
log.warn("invalid reverse index command: {}", .{action}); log.warn("invalid reverse index command: {}", .{action});
return; return;
@ -331,7 +332,10 @@ pub fn selectGraphicRendition(self: *Terminal, aspect: ansi.RenditionAspect) !vo
} }
// TODO: test // TODO: test
pub fn reverseIndex(self: *Terminal) void { pub fn reverseIndex(self: *Terminal, alloc: Allocator) !void {
if (self.cursor.y == 0)
try self.scrollDown(alloc)
else
self.cursor.y -|= 1; self.cursor.y -|= 1;
} }
@ -535,6 +539,34 @@ pub fn scrollUp(self: *Terminal, alloc: Allocator) void {
self.screen.items.len -= 1; 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 { fn getOrPutCell(self: *Terminal, alloc: Allocator, x: usize, y: usize) !*Cell {
const tracy = trace(@src()); const tracy = trace(@src());
defer tracy.end(); defer tracy.end();