mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-16 16:56:09 +03:00
save and restore cursor
This commit is contained in:
@ -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();
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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")) {
|
||||
|
Reference in New Issue
Block a user