From 987f939bd88484331198de3a880c96ad9ad1f55e Mon Sep 17 00:00:00 2001 From: Tim Culverhouse Date: Fri, 7 Jun 2024 12:15:40 -0500 Subject: [PATCH] widgets(terminal): support cursor mode --- src/widgets/terminal/Screen.zig | 2 ++ src/widgets/terminal/Terminal.zig | 21 +++++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/src/widgets/terminal/Screen.zig b/src/widgets/terminal/Screen.zig index 00b754f..3f20e43 100644 --- a/src/widgets/terminal/Screen.zig +++ b/src/widgets/terminal/Screen.zig @@ -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; diff --git a/src/widgets/terminal/Terminal.zig b/src/widgets/terminal/Terminal.zig index 08b385b..6547372 100644 --- a/src/widgets/terminal/Terminal.zig +++ b/src/widgets/terminal/Terminal.zig @@ -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, + } +}