aboutsummaryrefslogtreecommitdiff
path: root/vendor/libghostty-vt/src/terminal/charsets.zig
diff options
context:
space:
mode:
authorCan Celik <ogulcancelik@gmail.com>2026-04-04 19:22:04 +0300
committerCan Celik <ogulcancelik@gmail.com>2026-04-05 01:23:06 +0300
commit41dd733ca7123c9ac4bfc6c781697a660e95b052 (patch)
tree3fc91815ca139ef2e0b281bba0abda4ef15175f4 /vendor/libghostty-vt/src/terminal/charsets.zig
parent55c138263e190a1e79d4b997bfb9397306c0ec1f (diff)
feat: finish ghostty pane backend integration
Diffstat (limited to 'vendor/libghostty-vt/src/terminal/charsets.zig')
-rw-r--r--vendor/libghostty-vt/src/terminal/charsets.zig115
1 files changed, 115 insertions, 0 deletions
diff --git a/vendor/libghostty-vt/src/terminal/charsets.zig b/vendor/libghostty-vt/src/terminal/charsets.zig
new file mode 100644
index 00000000..00a2d8d1
--- /dev/null
+++ b/vendor/libghostty-vt/src/terminal/charsets.zig
@@ -0,0 +1,115 @@
+const std = @import("std");
+const build_options = @import("terminal_options");
+const assert = @import("../quirks.zig").inlineAssert;
+const LibEnum = @import("../lib/enum.zig").Enum;
+
+/// The available charset slots for a terminal.
+pub const Slots = LibEnum(
+ if (build_options.c_abi) .c else .zig,
+ &.{ "G0", "G1", "G2", "G3" },
+);
+
+/// The name of the active slots.
+pub const ActiveSlot = LibEnum(
+ if (build_options.c_abi) .c else .zig,
+ &.{ "GL", "GR" },
+);
+
+/// The list of supported character sets and their associated tables.
+pub const Charset = LibEnum(
+ if (build_options.c_abi) .c else .zig,
+ &.{ "utf8", "ascii", "british", "dec_special" },
+);
+
+/// The table for the given charset. This returns a pointer to a
+/// slice that is guaranteed to be 255 chars that can be used to map
+/// ASCII to the given charset.
+pub inline fn table(set: Charset) []const u16 {
+ return switch (set) {
+ .british => &british,
+ .dec_special => &dec_special,
+
+ // utf8 is not a table, callers should double-check if the
+ // charset is utf8 and NOT use tables.
+ .utf8 => unreachable,
+
+ // recommended that callers just map ascii directly but we can
+ // support a table
+ .ascii => &ascii,
+ };
+}
+
+/// Just a basic c => c ascii table
+const ascii = initTable();
+
+/// https://vt100.net/docs/vt220-rm/chapter2.html
+const british = british: {
+ var tbl = initTable();
+ tbl[0x23] = 0x00a3;
+ break :british tbl;
+};
+
+/// https://en.wikipedia.org/wiki/DEC_Special_Graphics
+const dec_special = tech: {
+ var tbl = initTable();
+ tbl[0x60] = 0x25C6;
+ tbl[0x61] = 0x2592;
+ tbl[0x62] = 0x2409;
+ tbl[0x63] = 0x240C;
+ tbl[0x64] = 0x240D;
+ tbl[0x65] = 0x240A;
+ tbl[0x66] = 0x00B0;
+ tbl[0x67] = 0x00B1;
+ tbl[0x68] = 0x2424;
+ tbl[0x69] = 0x240B;
+ tbl[0x6a] = 0x2518;
+ tbl[0x6b] = 0x2510;
+ tbl[0x6c] = 0x250C;
+ tbl[0x6d] = 0x2514;
+ tbl[0x6e] = 0x253C;
+ tbl[0x6f] = 0x23BA;
+ tbl[0x70] = 0x23BB;
+ tbl[0x71] = 0x2500;
+ tbl[0x72] = 0x23BC;
+ tbl[0x73] = 0x23BD;
+ tbl[0x74] = 0x251C;
+ tbl[0x75] = 0x2524;
+ tbl[0x76] = 0x2534;
+ tbl[0x77] = 0x252C;
+ tbl[0x78] = 0x2502;
+ tbl[0x79] = 0x2264;
+ tbl[0x7a] = 0x2265;
+ tbl[0x7b] = 0x03C0;
+ tbl[0x7c] = 0x2260;
+ tbl[0x7d] = 0x00A3;
+ tbl[0x7e] = 0x00B7;
+ break :tech tbl;
+};
+
+/// Our table length is 256 so we can contain all ASCII chars.
+const table_len = std.math.maxInt(u8) + 1;
+
+/// Creates a table that maps ASCII to ASCII as a getting started point.
+fn initTable() [table_len]u16 {
+ var result: [table_len]u16 = undefined;
+ var i: usize = 0;
+ while (i < table_len) : (i += 1) result[i] = @intCast(i);
+ assert(i == table_len);
+ return result;
+}
+
+test {
+ const testing = std.testing;
+ const info = @typeInfo(Charset).@"enum";
+ inline for (info.fields) |field| {
+ // utf8 has no table
+ if (@field(Charset, field.name) == .utf8) continue;
+
+ const tbl = table(@field(Charset, field.name));
+
+ // Yes, I could use `table_len` here, but I want to explicitly use a
+ // hardcoded constant so that if there are miscompilations or a comptime
+ // issue, we catch it.
+ try testing.expectEqual(@as(usize, 256), tbl.len);
+ }
+}