widgets(terminal): implement OSC 7 for pwd reporting

This commit is contained in:
Tim Culverhouse 2024-06-19 09:23:11 -05:00
parent 7005bb237c
commit 0c91840b32
3 changed files with 33 additions and 2 deletions

View file

@ -70,6 +70,7 @@ pub fn main() !void {
.title_change => {}, .title_change => {},
.exited => return, .exited => return,
.redraw => {}, .redraw => {},
.pwd_change => {},
} }
} }
while (loop.tryEvent()) |event| { while (loop.tryEvent()) |event| {

View file

@ -43,6 +43,12 @@ base_layout_codepoint: ?u21 = null,
mods: Modifiers = .{}, 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. // matches follows a loose matching algorithm for key matches.
// 1. If the codepoint and modifiers are exact matches, after removing caps_lock // 1. If the codepoint and modifiers are exact matches, after removing caps_lock
// and num_lock // and num_lock

View file

@ -20,7 +20,8 @@ pub const Event = union(enum) {
exited, exited,
redraw, redraw,
bell, bell,
title_change, title_change: []const u8,
pwd_change: []const u8,
}; };
const grapheme = @import("grapheme"); const grapheme = @import("grapheme");
@ -78,6 +79,7 @@ mode: Mode = .{},
tab_stops: std.ArrayList(u16), tab_stops: std.ArrayList(u16),
title: std.ArrayList(u8), title: std.ArrayList(u8),
working_directory: std.ArrayList(u8),
last_printed: []const u8 = "", last_printed: []const u8 = "",
@ -116,6 +118,7 @@ pub fn init(
.unicode = unicode, .unicode = unicode,
.tab_stops = tabs, .tab_stops = tabs,
.title = std.ArrayList(u8).init(allocator), .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.back_screen_alt.deinit(self.allocator);
self.tab_stops.deinit(); self.tab_stops.deinit();
self.title.deinit(); self.title.deinit();
self.working_directory.deinit();
} }
pub fn spawn(self: *Terminal) !void { pub fn spawn(self: *Terminal) !void {
@ -665,7 +669,27 @@ fn run(self: *Terminal) !void {
0 => { 0 => {
self.title.clearRetainingCapacity(); self.title.clearRetainingCapacity();
try self.title.appendSlice(osc[semicolon + 1 ..]); 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:// <hostname> <pwd>
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}), else => log.info("unhandled osc: {s}", .{osc}),
} }