From 0c91840b32eb0f6eb0309907bd8446cc10c944db Mon Sep 17 00:00:00 2001 From: Tim Culverhouse Date: Wed, 19 Jun 2024 09:23:11 -0500 Subject: [PATCH] widgets(terminal): implement OSC 7 for pwd reporting --- examples/vt.zig | 1 + src/Key.zig | 6 ++++++ src/widgets/terminal/Terminal.zig | 28 ++++++++++++++++++++++++++-- 3 files changed, 33 insertions(+), 2 deletions(-) diff --git a/examples/vt.zig b/examples/vt.zig index 40d0ed7..4a61307 100644 --- a/examples/vt.zig +++ b/examples/vt.zig @@ -70,6 +70,7 @@ pub fn main() !void { .title_change => {}, .exited => return, .redraw => {}, + .pwd_change => {}, } } while (loop.tryEvent()) |event| { diff --git a/src/Key.zig b/src/Key.zig index 981de69..066ae7c 100644 --- a/src/Key.zig +++ b/src/Key.zig @@ -43,6 +43,12 @@ base_layout_codepoint: ?u21 = null, mods: Modifiers = .{}, +/// Internal buffer to hold text contents. If text is longer than 16 bytes, it is stored in a +/// separate ring buffer by the main Vaxis object +buffer: [16]u8 = undefined, +/// Length of text stored in the buffer +text_len: u4 = 0, + // matches follows a loose matching algorithm for key matches. // 1. If the codepoint and modifiers are exact matches, after removing caps_lock // and num_lock diff --git a/src/widgets/terminal/Terminal.zig b/src/widgets/terminal/Terminal.zig index 9cda111..be0f3e5 100644 --- a/src/widgets/terminal/Terminal.zig +++ b/src/widgets/terminal/Terminal.zig @@ -20,7 +20,8 @@ pub const Event = union(enum) { exited, redraw, bell, - title_change, + title_change: []const u8, + pwd_change: []const u8, }; const grapheme = @import("grapheme"); @@ -78,6 +79,7 @@ mode: Mode = .{}, tab_stops: std.ArrayList(u16), title: std.ArrayList(u8), +working_directory: std.ArrayList(u8), last_printed: []const u8 = "", @@ -116,6 +118,7 @@ pub fn init( .unicode = unicode, .tab_stops = tabs, .title = std.ArrayList(u8).init(allocator), + .working_directory = std.ArrayList(u8).init(allocator), }; } @@ -148,6 +151,7 @@ pub fn deinit(self: *Terminal) void { self.back_screen_alt.deinit(self.allocator); self.tab_stops.deinit(); self.title.deinit(); + self.working_directory.deinit(); } pub fn spawn(self: *Terminal) !void { @@ -665,7 +669,27 @@ fn run(self: *Terminal) !void { 0 => { self.title.clearRetainingCapacity(); try self.title.appendSlice(osc[semicolon + 1 ..]); - self.event_queue.push(.title_change); + self.event_queue.push(.{ .title_change = self.title.items }); + }, + 7 => { + // OSC 7 ; file:// + log.err("osc: {s}", .{osc}); + self.working_directory.clearRetainingCapacity(); + const scheme = "file://"; + const start = std.mem.indexOfScalarPos(u8, osc, semicolon + 2 + scheme.len + 1, '/') orelse { + log.info("unknown OSC 7 format: {s}", .{osc}); + continue; + }; + const enc = osc[start..]; + var i: usize = 0; + while (i < enc.len) : (i += 1) { + const b = if (enc[i] == '%') blk: { + defer i += 2; + break :blk try std.fmt.parseUnsigned(u8, enc[i + 1 .. i + 3], 16); + } else enc[i]; + try self.working_directory.append(b); + } + self.event_queue.push(.{ .pwd_change = self.working_directory.items }); }, else => log.info("unhandled osc: {s}", .{osc}), }