aboutsummaryrefslogtreecommitdiff
path: root/vendor/libghostty-vt/src/input
diff options
context:
space:
mode:
authorOgulcan Celik <ogulcancelik@gmail.com>2026-05-07 18:29:21 +0300
committerOgulcan Celik <ogulcancelik@gmail.com>2026-05-07 18:29:21 +0300
commitdcfe11a7588fcd42471159453810abc9b7720a57 (patch)
treec32a77266028e73ca2382b96c96f8438a5fcd621 /vendor/libghostty-vt/src/input
parent2dfed860103c4e4505ac7f25def9fe37da1e1e6a (diff)
build: update libghostty-vt vendor
vendor ghostty 063ac3e and remove the musl libc++ link workaround. expose the new selection formatter and hyperlink uri apis for follow-up rendering work. add manual artifact validation for static linux builds.
Diffstat (limited to 'vendor/libghostty-vt/src/input')
-rw-r--r--vendor/libghostty-vt/src/input/Binding.zig47
-rw-r--r--vendor/libghostty-vt/src/input/function_keys.zig7
-rw-r--r--vendor/libghostty-vt/src/input/key_encode.zig120
3 files changed, 164 insertions, 10 deletions
diff --git a/vendor/libghostty-vt/src/input/Binding.zig b/vendor/libghostty-vt/src/input/Binding.zig
index 62a4e39a..d60f2933 100644
--- a/vendor/libghostty-vt/src/input/Binding.zig
+++ b/vendor/libghostty-vt/src/input/Binding.zig
@@ -347,6 +347,29 @@ pub const Action = union(enum) {
reset,
/// Copy the selected text to the clipboard.
+ ///
+ /// Valid values:
+ ///
+ /// - `plain`
+ ///
+ /// Copy the selection as plain text only.
+ ///
+ /// - `vt`
+ ///
+ /// Copy the selection as plain text, preserving terminal escape
+ /// sequences (such as colors and styles).
+ ///
+ /// - `html`
+ ///
+ /// Copy the selection as HTML, preserving colors and styles as
+ /// HTML markup.
+ ///
+ /// - `mixed` (default)
+ ///
+ /// Place multiple representations on the clipboard at once
+ /// (e.g. plain text and HTML), each tagged with its content type
+ /// so the receiving OS or application can pick the most appropriate
+ /// representation when pasting.
copy_to_clipboard: CopyToClipboard,
/// Paste the contents of the default clipboard.
@@ -398,6 +421,8 @@ pub const Action = union(enum) {
/// Navigate the search results. If there is no active search, this
/// is not performed.
+ ///
+ /// Valid values: `previous`, `next`.
navigate_search: NavigateSearch,
/// Start a search if it isn't started already. This doesn't set any
@@ -681,10 +706,21 @@ pub const Action = union(enum) {
/// of the `confirm-close-surface` configuration setting.
close_surface,
- /// Close the current tab and all splits therein, close all other tabs, or
- /// close every tab to the right of the current one depending on the mode.
+ /// Close the specified tabs and all splits therein.
+ ///
+ /// Valid values:
+ ///
+ /// - `this` (default)
+ ///
+ /// Close the current tab and all splits within it.
+ ///
+ /// - `other`
+ ///
+ /// Close every tab in the current window except the current tab.
+ ///
+ /// - `right`
///
- /// If the mode is not specified, defaults to closing the current tab.
+ /// Close every tab to the right of the current tab.
///
/// This might trigger a close confirmation popup, depending on the value
/// of the `confirm-close-surface` configuration setting.
@@ -2615,9 +2651,8 @@ pub const Set = struct {
/// Get an entry for the given key event. This will attempt to find
/// a binding using multiple parts of the event in the following order:
///
- /// 1. Translated key (event.key)
- /// 2. Physical key (event.physical_key)
- /// 3. Unshifted Unicode codepoint (event.unshifted_codepoint)
+ /// 1. Physical key (event.physical_key)
+ /// 2. Unshifted Unicode codepoint (event.unshifted_codepoint)
///
pub fn getEvent(self: *const Set, event: KeyEvent) ?Entry {
var trigger: Trigger = .{
diff --git a/vendor/libghostty-vt/src/input/function_keys.zig b/vendor/libghostty-vt/src/input/function_keys.zig
index efe86d9e..66ab4bc4 100644
--- a/vendor/libghostty-vt/src/input/function_keys.zig
+++ b/vendor/libghostty-vt/src/input/function_keys.zig
@@ -43,6 +43,9 @@ pub const Entry = struct {
/// The sequence to send to the pty if this entry matches.
sequence: []const u8,
+
+ /// Sequence to send to the PTY if DECBKM is set.
+ sequence_decbkm: ?[]const u8 = null,
};
/// The list of modifier combinations for modify other key sequences.
@@ -161,8 +164,8 @@ pub const keys = keys: {
.{ .mods = .{ .alt = true, .super = true, .ctrl = true }, .modify_other_keys = .set_other, .sequence = "\x1b[27;15;127~" },
.{ .mods = .{ .alt = true, .super = true, .ctrl = true, .shift = true }, .modify_other_keys = .set_other, .sequence = "\x1b[27;16;127~" },
- .{ .mods = .{ .ctrl = true }, .sequence = "\x08" },
- .{ .sequence = "\x7f" },
+ .{ .mods = .{ .ctrl = true }, .sequence = "\x08", .sequence_decbkm = "\x7f" },
+ .{ .sequence = "\x7f", .sequence_decbkm = "\x08" },
});
result.set(.tab, &.{
diff --git a/vendor/libghostty-vt/src/input/key_encode.zig b/vendor/libghostty-vt/src/input/key_encode.zig
index 52bb556e..6ab5a4cc 100644
--- a/vendor/libghostty-vt/src/input/key_encode.zig
+++ b/vendor/libghostty-vt/src/input/key_encode.zig
@@ -18,6 +18,12 @@ pub const Options = struct {
/// Terminal DEC mode 66
keypad_key_application: bool = false,
+ // DEC Backarrow Key Mode (DECBKM)
+ // See https://vt100.net/dec/ek-vt3xx-tp-002.pdf page 170
+ // If `false` (the default), `backspace` emits 0x7f
+ // If `true`, `backspace` emits 0x08
+ backarrow_key_mode: bool = false,
+
/// Terminal DEC mode 1035
ignore_keypad_with_numlock: bool = false,
@@ -55,6 +61,7 @@ pub const Options = struct {
.alt_esc_prefix = t.modes.get(.alt_esc_prefix),
.cursor_key_application = t.modes.get(.cursor_keys),
.keypad_key_application = t.modes.get(.keypad_keys),
+ .backarrow_key_mode = t.modes.get(.backarrow_key_mode),
.ignore_keypad_with_numlock = t.modes.get(.ignore_keypad_with_numlock),
.modify_other_keys_state_2 = t.flags.modify_other_keys_2,
.kitty_flags = t.screens.active.kitty_keyboard.current(),
@@ -338,6 +345,7 @@ fn legacy(
opts.keypad_key_application,
opts.ignore_keypad_with_numlock,
opts.modify_other_keys_state_2,
+ opts.backarrow_key_mode,
)) |sequence| pc_style: {
// If we have UTF-8 text, then we never emit PC style function
// keys. Many function keys (escape, enter, backspace) have
@@ -601,6 +609,7 @@ fn pcStyleFunctionKey(
keypad_key_application_req: bool,
ignore_keypad_with_numlock: bool,
modify_other_keys: bool, // True if state 2
+ backarrow_key_mode: bool,
) ?[]const u8 {
// We only want binding-sensitive mods because lock keys
// and directional modifiers (left/right) don't matter for
@@ -653,6 +662,10 @@ fn pcStyleFunctionKey(
continue;
}
+ if (backarrow_key_mode)
+ if (entry.sequence_decbkm) |sequence|
+ return sequence;
+
return entry.sequence;
}
@@ -1245,9 +1258,20 @@ test "kitty: enter, backspace, tab" {
try testing.expectEqualStrings("\r", writer.buffered());
}
{
+ // DECBKM reset
var writer: std.Io.Writer = .fixed(&buf);
try kitty(&writer, .{ .key = .backspace, .mods = .{}, .utf8 = "" }, .{
.kitty_flags = .{ .disambiguate = true },
+ .backarrow_key_mode = false,
+ });
+ try testing.expectEqualStrings("\x7f", writer.buffered());
+ }
+ {
+ // DECBKM set (Kitty does not support DECBKM so there should be no change)
+ var writer: std.Io.Writer = .fixed(&buf);
+ try kitty(&writer, .{ .key = .backspace, .mods = .{}, .utf8 = "" }, .{
+ .kitty_flags = .{ .disambiguate = true },
+ .backarrow_key_mode = true,
});
try testing.expectEqualStrings("\x7f", writer.buffered());
}
@@ -1888,6 +1912,43 @@ test "legacy: backspace with utf8 (dead key state)" {
try testing.expectEqualStrings("", writer.buffered());
}
+test "kitty: backspace (DECBKM reset) (report_all: true)" {
+ var buf: [128]u8 = undefined;
+ var writer: std.Io.Writer = .fixed(&buf);
+ try kitty(&writer, .{
+ .key = .backspace,
+ }, .{
+ .kitty_flags = .{
+ .disambiguate = true,
+ .report_events = true,
+ .report_alternates = true,
+ .report_all = true,
+ .report_associated = true,
+ },
+ .backarrow_key_mode = false,
+ });
+ try testing.expectEqualStrings("\x1b[127u", writer.buffered());
+}
+
+test "kitty: backspace (DECBKM set) (report_all: true)" {
+ // Kitty does not support DECBKM so there should be no difference.
+ var buf: [128]u8 = undefined;
+ var writer: std.Io.Writer = .fixed(&buf);
+ try kitty(&writer, .{
+ .key = .backspace,
+ }, .{
+ .kitty_flags = .{
+ .disambiguate = true,
+ .report_events = true,
+ .report_alternates = true,
+ .report_all = true,
+ .report_associated = true,
+ },
+ .backarrow_key_mode = true,
+ });
+ try testing.expectEqualStrings("\x1b[127u", writer.buffered());
+}
+
test "legacy: enter with utf8 (dead key state)" {
var buf: [128]u8 = undefined;
var writer: std.Io.Writer = .fixed(&buf);
@@ -2039,6 +2100,50 @@ test "legacy: ctrl+shift+backspace" {
try testing.expectEqualStrings("\x08", writer.buffered());
}
+test "legacy: backspace (DECBKM reset)" {
+ var buf: [128]u8 = undefined;
+ var writer: std.Io.Writer = .fixed(&buf);
+ try legacy(&writer, .{
+ .key = .backspace,
+ .mods = .{},
+ }, .{ .backarrow_key_mode = false });
+ try testing.expectEqualStrings("\x7f", writer.buffered());
+}
+
+test "legacy: backspace (DECBKM reset, with ctrl)" {
+ var buf: [128]u8 = undefined;
+ var writer: std.Io.Writer = .fixed(&buf);
+ try legacy(&writer, .{
+ .key = .backspace,
+ .mods = .{
+ .ctrl = true,
+ },
+ }, .{ .backarrow_key_mode = false });
+ try testing.expectEqualStrings("\x08", writer.buffered());
+}
+
+test "legacy: backspace (DECBKM set)" {
+ var buf: [128]u8 = undefined;
+ var writer: std.Io.Writer = .fixed(&buf);
+ try legacy(&writer, .{
+ .key = .backspace,
+ .mods = .{},
+ }, .{ .backarrow_key_mode = true });
+ try testing.expectEqualStrings("\x08", writer.buffered());
+}
+
+test "legacy: backspace (DECBKM set, with ctrl)" {
+ var buf: [128]u8 = undefined;
+ var writer: std.Io.Writer = .fixed(&buf);
+ try legacy(&writer, .{
+ .key = .backspace,
+ .mods = .{
+ .ctrl = true,
+ },
+ }, .{ .backarrow_key_mode = true });
+ try testing.expectEqualStrings("\x7f", writer.buffered());
+}
+
test "legacy: ctrl+shift+char with modify other state 2" {
var buf: [128]u8 = undefined;
var writer: std.Io.Writer = .fixed(&buf);
@@ -2355,17 +2460,28 @@ test "legacy: super and other mods on macOS with text" {
try testing.expectEqualStrings("", writer.buffered());
}
-test "legacy: backspace with DEL utf8" {
+test "legacy: backspace with DEL utf8 (DECBKM reset)" {
var buf: [128]u8 = undefined;
var writer: std.Io.Writer = .fixed(&buf);
try legacy(&writer, .{
.key = .backspace,
.utf8 = &.{0x7F},
.unshifted_codepoint = 0x08,
- }, .{});
+ }, .{ .backarrow_key_mode = false });
try testing.expectEqualStrings("\x7F", writer.buffered());
}
+test "legacy: backspace with DEL utf8 (DECBKM set)" {
+ var buf: [128]u8 = undefined;
+ var writer: std.Io.Writer = .fixed(&buf);
+ try legacy(&writer, .{
+ .key = .backspace,
+ .utf8 = &.{0x7F},
+ .unshifted_codepoint = 0x08,
+ }, .{ .backarrow_key_mode = true });
+ try testing.expectEqualStrings("\x08", writer.buffered());
+}
+
test "ctrlseq: normal ctrl c" {
const seq = ctrlSeq(.unidentified, "c", 'c', .{ .ctrl = true });
try testing.expectEqual(@as(u8, 0x03), seq.?);