save and restore cursor

This commit is contained in:
Mitchell Hashimoto
2022-06-25 10:56:41 -07:00
parent fb6800c8ce
commit 245b9642f9
3 changed files with 47 additions and 3 deletions

View File

@ -781,3 +781,11 @@ pub fn tabClear(self: *Window, cmd: terminal.TabClear) !void {
pub fn tabSet(self: *Window) !void {
self.terminal.tabSet();
}
pub fn saveCursor(self: *Window) !void {
self.terminal.saveCursor();
}
pub fn restoreCursor(self: *Window) !void {
self.terminal.restoreCursor();
}

View File

@ -28,6 +28,9 @@ screen: Screen,
/// Cursor position.
cursor: Cursor,
/// Saved cursor saved with DECSC (ESC 7).
saved_cursor: Cursor,
/// Where the tabstops are.
tabstops: Tabstops,
@ -53,8 +56,8 @@ const ScrollingRegion = struct {
/// Cursor represents the cursor state.
const Cursor = struct {
// x, y where the cursor currently exists (0-indexed).
x: usize,
y: usize,
x: usize = 0,
y: usize = 0,
// pen is the current cell styling to apply to new cells.
pen: Screen.Cell = .{ .char = 0 },
@ -66,7 +69,8 @@ pub fn init(alloc: Allocator, cols: usize, rows: usize) !Terminal {
.cols = cols,
.rows = rows,
.screen = try Screen.init(alloc, rows, cols),
.cursor = .{ .x = 0, .y = 0 },
.cursor = .{},
.saved_cursor = .{},
.tabstops = try Tabstops.init(alloc, cols, TABSTOP_INTERVAL),
.scrolling_region = .{
.top = 0,
@ -119,6 +123,23 @@ pub fn plainString(self: Terminal, alloc: Allocator) ![]const u8 {
return try self.screen.testString(alloc);
}
/// Save cursor position and further state.
///
/// The primary and alternate screen have distinct save state. One saved state
/// is kept per screen (main / alternative). If for the current screen state
/// was already saved it is overwritten.
pub fn saveCursor(self: *Terminal) void {
self.saved_cursor = self.cursor;
}
/// Restore cursor position and other state.
///
/// The primary and alternate screen have distinct save state.
/// If no save was done before values are reset to their initial values.
pub fn restoreCursor(self: *Terminal) void {
self.cursor = self.saved_cursor;
}
/// TODO: test
pub fn setAttribute(self: *Terminal, attr: sgr.Attribute) !void {
switch (attr) {

View File

@ -379,8 +379,23 @@ pub fn Stream(comptime Handler: type) type {
action: Parser.Action.ESC,
) !void {
switch (action.final) {
// DECSC - Save Cursor
'7' => if (@hasDecl(T, "saveCursor")) switch (action.intermediates.len) {
0 => try self.handler.saveCursor(),
else => {
log.warn("invalid command: {}", .{action});
return;
},
} else log.warn("unimplemented ESC callback: {}", .{action}),
'8' => blk: {
switch (action.intermediates.len) {
// DECRC - Restore Cursor
0 => if (@hasDecl(T, "restoreCursor")) {
try self.handler.restoreCursor();
break :blk {};
} else log.warn("unimplemented restore cursor callback: {}", .{action}),
1 => switch (action.intermediates[0]) {
// DECALN - Fill Screen with E
'#' => if (@hasDecl(T, "decaln")) {