widgets(terminal): support cursor mode

This commit is contained in:
Tim Culverhouse 2024-06-07 12:15:40 -05:00
parent 36854123fe
commit 987f939bd8
2 changed files with 23 additions and 0 deletions

View file

@ -27,6 +27,7 @@ pub const Cursor = struct {
row: usize = 0,
pending_wrap: bool = false,
shape: vaxis.Cell.CursorShape = .default,
visible: bool = true,
pub fn isOutsideScrollingRegion(self: Cursor, sr: ScrollingRegion) bool {
return self.row < sr.top or
@ -99,6 +100,7 @@ pub fn deinit(self: *Screen, alloc: std.mem.Allocator) void {
/// copies the visible area to the destination screen
pub fn copyTo(self: *Screen, dst: *Screen) !void {
dst.cursor = self.cursor;
for (self.buf, 0..) |cell, i| {
if (!cell.dirty) continue;
self.buf[i].dirty = false;

View file

@ -25,6 +25,7 @@ pub const Options = struct {
pub const Mode = struct {
origin: bool = false,
cursor: bool = true,
};
allocator: std.mem.Allocator,
@ -145,6 +146,9 @@ pub fn draw(self: *Terminal, win: vaxis.Window) !void {
col += @max(cell.char.width, 1);
}
}
if (self.front_screen.cursor.visible)
win.showCursor(self.front_screen.cursor.col, self.front_screen.cursor.row);
}
fn opaqueRead(ptr: *const anyopaque, buf: []u8) !usize {
@ -199,6 +203,14 @@ fn run(self: *Terminal) !void {
self.back_screen.cursor.col = col - 1;
self.back_screen.cursor.row = row - 1;
},
'h', 'l' => {
var iter = seq.iterator(u16);
const mode = iter.next() orelse continue;
// There is only one collision (mode = 4), and we don't support the private
// version of it
if (seq.private_marker != null and mode == 4) continue;
self.setMode(mode, seq.final == 'h');
},
'm' => {
if (seq.intermediate == null and seq.private_marker == null) {
self.back_screen.sgr(seq);
@ -234,3 +246,12 @@ inline fn handleC0(self: *Terminal, b: ansi.C0) !void {
else => log.warn("unhandled C0: 0x{x}", .{@intFromEnum(b)}),
}
}
pub fn setMode(self: *Terminal, mode: u16, val: bool) void {
switch (mode) {
25 => {
self.mode.cursor = val;
},
else => return,
}
}