aboutsummaryrefslogtreecommitdiff
path: root/vendor/libghostty-vt/src/terminfo
diff options
context:
space:
mode:
authorCan Celik <ogulcancelik@gmail.com>2026-09-10 21:51:57 +0300
committerGitHub <noreply@github.com>2026-09-10 21:51:57 +0300
commit425c86179791cd32e2d4ce0ae7f269940b4b0663 (patch)
treee52c4383a6d69216cbe2a32638bf90841d7e2189 /vendor/libghostty-vt/src/terminfo
parent90e947a6e26e02f10ec7f1694c4eb5b78a86406b (diff)
chore: upgrade libghostty and preserve terminal behavior (#3906)
Diffstat (limited to 'vendor/libghostty-vt/src/terminfo')
-rw-r--r--vendor/libghostty-vt/src/terminfo/Source.zig38
-rw-r--r--vendor/libghostty-vt/src/terminfo/ghostty.zig13
-rw-r--r--vendor/libghostty-vt/src/terminfo/main.zig1
3 files changed, 36 insertions, 16 deletions
diff --git a/vendor/libghostty-vt/src/terminfo/Source.zig b/vendor/libghostty-vt/src/terminfo/Source.zig
index 91fee1ac..357e0ca2 100644
--- a/vendor/libghostty-vt/src/terminfo/Source.zig
+++ b/vendor/libghostty-vt/src/terminfo/Source.zig
@@ -12,7 +12,7 @@ const std = @import("std");
/// and are used to look up this terminal. Historically, the final name in the
/// list was the most common name for the terminal and contains spaces and
/// other characters. See terminfo(5) for details.
-names: []const []const u8,
+names: []const [:0]const u8,
/// The set of capabilities in this terminfo file.
capabilities: []const Capability,
@@ -36,7 +36,7 @@ pub const Capability = struct {
/// because it is a common integer size but this may be wrong.
numeric: u32,
- string: []const u8,
+ string: [:0]const u8,
};
};
@@ -68,8 +68,12 @@ pub fn encode(self: Source, writer: *std.Io.Writer) !void {
/// Returns a StaticStringMap for all of the capabilities in this terminfo.
/// The value is the value that should be sent as a response to XTGETTCAP.
/// Important: the value is the FULL response included the escape sequences.
-pub fn xtgettcapMap(comptime self: Source) std.StaticStringMap([]const u8) {
- const KV = struct { []const u8, []const u8 };
+///
+/// The responses are null-terminated so that they can be handed directly
+/// to APIs that require a sentinel (e.g. the libghostty-vt write_pty
+/// callback) without copying.
+pub fn xtgettcapMap(comptime self: Source) std.StaticStringMap([:0]const u8) {
+ const KV = struct { []const u8, [:0]const u8 };
// We have all of our capabilities plus To, TN, and RGB which aren't
// in the capabilities list but are query-able.
@@ -82,7 +86,8 @@ pub fn xtgettcapMap(comptime self: Source) std.StaticStringMap([]const u8) {
kvs[2] = .{ "RGB", "8" };
for (self.capabilities, 3..) |cap, i| {
kvs[i] = .{
- cap.name, switch (cap.value) {
+ cap.name,
+ switch (cap.value) {
.canceled => @compileError("canceled not handled yet"),
.boolean => "",
.string => |v| string: {
@@ -114,11 +119,11 @@ pub fn xtgettcapMap(comptime self: Source) std.StaticStringMap([]const u8) {
break :string result;
},
.numeric => |v| numeric: {
- var buf: [10]u8 = undefined;
- var writer: std.Io.Writer = .fixed(&buf);
+ var buf: [11]u8 = @splat(0);
+ var writer: std.Io.Writer = .fixed(buf[0..10]);
writer.printInt(v, 10, .upper, .{}) catch unreachable;
const final = buf;
- break :numeric final[0..writer.end];
+ break :numeric final[0..writer.end :0];
},
},
};
@@ -129,8 +134,9 @@ pub fn xtgettcapMap(comptime self: Source) std.StaticStringMap([]const u8) {
// The key is just the raw hex-encoded string
entry[0] = hexencode(entry[0]);
- // The value is more complex
- var buf: [5 + entry[0].len + 1 + (entry[1].len * 2) + 2]u8 = undefined;
+ // The value is more complex. The buffer is zeroed so the byte
+ // after the response is already the null terminator.
+ var buf: [5 + entry[0].len + 1 + (entry[1].len * 2) + 2 + 1]u8 = @splat(0);
const out = if (std.mem.eql(u8, entry[1], "")) std.fmt.bufPrint(
&buf,
"\x1bP1+r{s}\x1b\\",
@@ -142,11 +148,11 @@ pub fn xtgettcapMap(comptime self: Source) std.StaticStringMap([]const u8) {
) catch unreachable;
const final = buf;
- entry[1] = final[0..out.len];
+ entry[1] = final[0..out.len :0];
}
const kvs_final = kvs;
- return std.StaticStringMap([]const u8).initComptime(&kvs_final);
+ return std.StaticStringMap([:0]const u8).initComptime(&kvs_final);
}
fn hexencode(comptime input: []const u8) []const u8 {
@@ -159,13 +165,13 @@ fn comptimeReplace(
input: []const u8,
needle: []const u8,
replacement: []const u8,
-) []const u8 {
+) [:0]const u8 {
comptime {
const len = std.mem.replacementSize(u8, input, needle, replacement);
- var buf: [len]u8 = undefined;
- _ = std.mem.replace(u8, input, needle, replacement, &buf);
+ var buf: [len + 1]u8 = @splat(0);
+ _ = std.mem.replace(u8, input, needle, replacement, buf[0..len]);
const final = buf;
- return &final;
+ return final[0..len :0];
}
}
diff --git a/vendor/libghostty-vt/src/terminfo/ghostty.zig b/vendor/libghostty-vt/src/terminfo/ghostty.zig
index 5788170e..ea64ffcf 100644
--- a/vendor/libghostty-vt/src/terminfo/ghostty.zig
+++ b/vendor/libghostty-vt/src/terminfo/ghostty.zig
@@ -106,6 +106,10 @@ pub const ghostty: Source = .{
// Curly, dashed, etc underlines
.{ .name = "Smulx", .value = .{ .string = "\\E[4:%p1%dm" } },
+ // Overline
+ .{ .name = "Smol", .value = .{ .string = "\\E[53m" } },
+ .{ .name = "Rmol", .value = .{ .string = "\\E[55m" } },
+
// Colored underlines
.{ .name = "Setulc", .value = .{ .string = "\\E[58:2::%p1%{65536}%/%d:%p1%{256}%/%{255}%&%d:%p1%{255}%&%d%;m" } },
@@ -388,6 +392,15 @@ pub const ghostty: Source = .{
},
};
+/// A content-derived version of the encoded terminfo source.
+pub const version = version: {
+ @setEvalBranchQuota(100_000);
+ var hashing: std.Io.Writer.Hashing(std.hash.Wyhash) =
+ .initHasher(.init(0), &.{});
+ ghostty.encode(&hashing.writer) catch unreachable;
+ break :version std.fmt.comptimePrint("{x}", .{hashing.hasher.final()});
+};
+
test "encode" {
// Encode
var buf: [1024 * 16]u8 = undefined;
diff --git a/vendor/libghostty-vt/src/terminfo/main.zig b/vendor/libghostty-vt/src/terminfo/main.zig
index c76c328c..f6c709b9 100644
--- a/vendor/libghostty-vt/src/terminfo/main.zig
+++ b/vendor/libghostty-vt/src/terminfo/main.zig
@@ -6,6 +6,7 @@
//! extract this into a more full-featured library on its own.
pub const ghostty = @import("ghostty.zig").ghostty;
+pub const version = @import("ghostty.zig").version;
pub const Source = @import("Source.zig");
test {