From fbe030d85a80afa7818884f942d124d856224013 Mon Sep 17 00:00:00 2001 From: Tim Culverhouse Date: Wed, 20 Sep 2023 18:57:06 -0500 Subject: [PATCH] terminal: respond to XTVERSION query XTVERSION (CSI > 0 q) is used by some libraries to identify the terminal + version. Respond to this query with `ghostty {version_string}`. There is no formal format for this response. A roundup of a few tested terminals show two primary formats. This patch opts to save one byte and use the `name SP version` semantics. foot: foot(version) xterm: XTerm(version) contour: contour version wezterm: wezterm version Reference: https://github.com/dankamongmen/notcurses/blob/master/TERMINALS.md#notes-for-terminal-authors Signed-off-by: Tim Culverhouse --- src/terminal/stream.zig | 38 +++++++++++++++++++++----------------- src/termio/Exec.zig | 17 +++++++++++++++++ 2 files changed, 38 insertions(+), 17 deletions(-) diff --git a/src/terminal/stream.zig b/src/terminal/stream.zig index 3789d5611..585e49212 100644 --- a/src/terminal/stream.zig +++ b/src/terminal/stream.zig @@ -607,28 +607,32 @@ pub fn Stream(comptime Handler: type) type { ), }, - // DECSCUSR - Select Cursor Style - // TODO: test 'q' => switch (action.intermediates.len) { - 1 => cursor: { - if (action.intermediates[0] != ' ') { + 1 => switch (action.intermediates[0]) { + // DECSCUSR - Select Cursor Style + // TODO: test + ' ' => { + if (@hasDecl(T, "setCursorStyle")) try self.handler.setCursorStyle( + switch (action.params.len) { + 0 => ansi.CursorStyle.default, + 1 => @enumFromInt(action.params[0]), + else => { + log.warn("invalid set curor style command: {}", .{action}); + return; + }, + }, + ) else log.warn("unimplemented CSI callback: {}", .{action}); + }, + // XTVERSION + '>' => { + if (@hasDecl(T, "reportXtversion")) try self.handler.reportXtversion(); + }, + else => { log.warn( "ignoring unimplemented CSI q with intermediates: {s}", .{action.intermediates}, ); - break :cursor; - } - - if (@hasDecl(T, "setCursorStyle")) try self.handler.setCursorStyle( - switch (action.params.len) { - 0 => ansi.CursorStyle.default, - 1 => @enumFromInt(action.params[0]), - else => { - log.warn("invalid set curor style command: {}", .{action}); - return; - }, - }, - ) else log.warn("unimplemented CSI callback: {}", .{action}); + }, }, else => log.warn( diff --git a/src/termio/Exec.zig b/src/termio/Exec.zig index 739ae3702..ef2d796c7 100644 --- a/src/termio/Exec.zig +++ b/src/termio/Exec.zig @@ -1688,6 +1688,23 @@ const StreamHandler = struct { self.terminal.screen.kitty_keyboard.set(mode, flags); } + pub fn reportXtversion( + self: *StreamHandler, + ) !void { + log.debug("reporting XTVERSION: ghostty {s}", .{build_config.version_string}); + var msg: termio.Message = .{ .write_small = .{} }; + const resp = try std.fmt.bufPrint( + &msg.write_small.data, + "\x1BP>|{s} {s}\x07", + .{ + "ghostty", + build_config.version_string, + }, + ); + msg.write_small.len = @intCast(resp.len); + self.messageWriter(msg); + } + //------------------------------------------------------------------------- // OSC