refactor: delete herdr's own key encoder

This commit is contained in:
Ogulcan Celik
2026-10-06 17:21:23 +03:00
parent 0d3c8456e9
commit 4312273e9f
10 changed files with 43 additions and 1357 deletions
+1 -4
View File
@@ -1241,10 +1241,7 @@ mod windows_tests {
};
assert_eq!(key.code, KeyCode::Char('d'));
assert_eq!(key.modifiers, KeyModifiers::CONTROL);
assert_eq!(
crate::input::encode_terminal_key(key, crate::input::KeyboardProtocol::Legacy),
b"\x04"
);
assert_eq!(crate::pane::test_encode_key_for_app(b"", key), b"\x04");
}
#[test]
+11 -18
View File
@@ -3157,10 +3157,12 @@ mod tests {
events
.into_iter()
.flat_map(|event| match event.to_raw_input_event() {
crate::raw_input::RawInputEvent::Key(key) => crate::input::encode_terminal_key(
key,
crate::input::KeyboardProtocol::Kitty { flags },
),
crate::raw_input::RawInputEvent::Key(key) => {
crate::pane::test_encode_key_for_app(
format!("\x1b[>{flags}u").as_bytes(),
key,
)
}
crate::raw_input::RawInputEvent::Text(text) => {
text.as_str().as_bytes().to_vec()
}
@@ -3291,23 +3293,14 @@ mod tests {
let crate::raw_input::RawInputEvent::Key(key) = events[0].to_raw_input_event() else {
panic!("expected translated key");
};
assert_eq!(crate::pane::test_encode_key_for_app(b"", key.clone()), b"/");
assert_eq!(
crate::input::encode_terminal_key(key.clone(), crate::input::KeyboardProtocol::Legacy),
crate::pane::test_encode_key_for_app(b"\x1b[>7u", key.clone()),
b"/"
);
assert_eq!(
crate::input::encode_terminal_key(
key.clone(),
crate::input::KeyboardProtocol::Kitty { flags: 7 },
),
b"/"
);
assert_eq!(
crate::input::encode_terminal_key(
key,
crate::input::KeyboardProtocol::Kitty { flags: 15 },
),
b"\x1b[47;2:1u"
crate::pane::test_encode_key_for_app(b"\x1b[>15u", key),
b"\x1b[47;2u"
);
}
@@ -3416,7 +3409,7 @@ mod tests {
assert_eq!(key.modifiers.bits(), modifiers, "{name}: modifiers");
assert_eq!(key.generated_text.as_deref(), text, "{name}: text");
assert_eq!(
crate::input::encode_terminal_key(key, crate::input::KeyboardProtocol::Legacy),
crate::pane::test_encode_key_for_app(b"", key),
expected,
"{name}: encoding"
);
-1309
View File
File diff suppressed because it is too large Load Diff
+3 -9
View File
@@ -1,4 +1,3 @@
mod encode;
mod keybind_help;
mod keybindings;
mod lease;
@@ -6,10 +5,6 @@ mod model;
pub(crate) mod mouse;
mod parse;
#[allow(unused_imports)]
pub use encode::{
encode_cursor_key, encode_key, encode_mouse_button, encode_mouse_scroll, encode_terminal_key,
};
pub(crate) use keybind_help::{
filter_keybind_help_groups, keybind_help_groups, keybind_help_text_char,
};
@@ -21,11 +16,10 @@ pub(crate) use keybindings::{
pub(crate) use lease::{InputLeaseKey, InputLeaseTable, RepeatPlan};
#[cfg(not(windows))]
pub use model::ime_compatible_keyboard_enhancement_flags;
#[cfg(any(unix, test))]
pub use model::MouseProtocolMode;
pub use model::WindowsKeyRecord;
pub use model::{
host_modify_other_keys_mode, KeyIdentity, KeyboardProtocol, MouseProtocolEncoding, TerminalKey,
TextCommit,
host_modify_other_keys_mode, KeyIdentity, KeyboardProtocol, TerminalKey, TextCommit,
};
#[cfg(any(unix, test))]
pub use model::{MouseProtocolEncoding, MouseProtocolMode};
pub use parse::parse_terminal_key_sequence;
+1
View File
@@ -358,6 +358,7 @@ impl MouseProtocolMode {
}
}
#[cfg(any(unix, test))]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum MouseProtocolEncoding {
+3 -7
View File
@@ -405,7 +405,6 @@ mod tests {
use crossterm::event::{KeyCode, KeyModifiers, ModifierKeyCode};
use super::*;
use crate::input::{encode_terminal_key, KeyboardProtocol};
fn assert_terminal_key_eq(
actual: TerminalKey,
@@ -586,7 +585,7 @@ mod tests {
crossterm::event::KeyEventKind::Press,
None,
);
assert_eq!(encode_terminal_key(key, KeyboardProtocol::Legacy), b"\x1bA");
assert_eq!(crate::pane::test_encode_key_for_app(b"", key), b"\x1bA");
}
#[test]
@@ -600,10 +599,7 @@ mod tests {
crossterm::event::KeyEventKind::Press,
None,
);
assert_eq!(
encode_terminal_key(key, KeyboardProtocol::Legacy),
b"\x1b\x06"
);
assert_eq!(crate::pane::test_encode_key_for_app(b"", key), b"\x1b\x06");
}
#[test]
@@ -954,7 +950,7 @@ mod tests {
#[test]
fn legacy_lf_roundtrips_as_lf() {
let key = parse_terminal_key_sequence("\n").unwrap();
assert_eq!(encode_terminal_key(key, KeyboardProtocol::Legacy), b"\n");
assert_eq!(crate::pane::test_encode_key_for_app(b"", key), b"\n");
}
#[test]
+2
View File
@@ -42,6 +42,8 @@ use self::agent_detection::{
AGENT_PENDING_IDLE_RECHECK, AGENT_STARTUP_GRACE_WINDOW,
};
use self::background_agent::{AgentJobStatus, AgentJobTracker};
#[cfg(test)]
pub(crate) use self::terminal::test_encode_key_for_app;
#[cfg(unix)]
pub use self::terminal::InputState;
use self::terminal::{GhosttyPaneTerminal, PaneTerminal};
+5 -1
View File
@@ -35,7 +35,11 @@ pub(super) fn ghostty_key_event_from_terminal_key(
event.set_unshifted_codepoint(base as u32);
let shifted = mods & crate::ghostty::MOD_SHIFT != 0;
if let Some(text) = key_text(key, base, shifted) {
if shifted && !text.starts_with(base) {
// Text the host reported with Shift held already includes Shift
// (e.g. Shift+7 = "/" on a German layout, where `base` cannot
// be recovered from the character alone).
let reported_shifted_text = key.generated_text.is_some() && text != " ";
if shifted && (!text.starts_with(base) || reported_shifted_text) {
event.set_consumed_mods(crate::ghostty::MOD_SHIFT);
}
event.set_utf8(&text);
+15
View File
@@ -3603,6 +3603,21 @@ fn should_probe_host_terminal_theme_restore(core: &GhosttyPaneCore) -> bool {
.unwrap_or(false)
}
/// Encode one `key` the way a Unix server's pane does after its app wrote
/// `app_output` (for example a Kitty keyboard push): the libghostty path,
/// without the Windows ConPTY record fallback (covered by the Windows harness).
#[cfg(test)]
pub(crate) fn test_encode_key_for_app(
app_output: &[u8],
key: crate::input::TerminalKey,
) -> Vec<u8> {
let (tx, _rx) = mpsc::channel(4);
let terminal = crate::ghostty::Terminal::new(80, 24, 0).expect("terminal");
let pane = GhosttyPaneTerminal::new(terminal, tx.clone()).expect("pane terminal");
pane.process_pty_bytes(PaneId::from_raw(1), 0, app_output, &tx);
pane.encode_terminal_key_once(key)
}
#[cfg(test)]
mod tests {
use super::*;
+2 -9
View File
@@ -2225,11 +2225,7 @@ mod tests {
};
assert!(key.is_windows_dead_key());
assert_eq!(key.windows_record(), None);
assert!(crate::input::encode_terminal_key(
key,
crate::input::KeyboardProtocol::Kitty { flags: 1 },
)
.is_empty());
assert!(crate::pane::test_encode_key_for_app(b"\x1b[>1u", key).is_empty());
}
#[tokio::test]
@@ -2307,10 +2303,7 @@ mod tests {
};
assert!(roundtripped.has_physical_identity());
let encoded = crate::input::encode_terminal_key(
roundtripped,
crate::input::KeyboardProtocol::Kitty { flags: 8 },
);
let encoded = crate::pane::test_encode_key_for_app(b"\x1b[>8u", roundtripped);
assert_ne!(encoded, b"/");
assert!(encoded.starts_with(b"\x1b["));
}