aboutsummaryrefslogtreecommitdiff
path: root/src/input/encode.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/input/encode.rs')
-rw-r--r--src/input/encode.rs73
1 files changed, 72 insertions, 1 deletions
diff --git a/src/input/encode.rs b/src/input/encode.rs
index b114935a..ee466f42 100644
--- a/src/input/encode.rs
+++ b/src/input/encode.rs
@@ -1,4 +1,4 @@
-use crossterm::event::{KeyCode, KeyEvent, KeyModifiers};
+use crossterm::event::{KeyCode, KeyEvent, KeyModifiers, MouseEventKind};
use super::{KeyboardProtocol, TerminalKey};
@@ -23,6 +23,77 @@ pub fn encode_terminal_key(key: TerminalKey, protocol: KeyboardProtocol) -> Vec<
encode_legacy(key.as_key_event())
}
+pub fn encode_cursor_key(code: KeyCode, application_cursor: bool) -> Vec<u8> {
+ match (code, application_cursor) {
+ (KeyCode::Up, true) => b"\x1bOA".to_vec(),
+ (KeyCode::Down, true) => b"\x1bOB".to_vec(),
+ (KeyCode::Right, true) => b"\x1bOC".to_vec(),
+ (KeyCode::Left, true) => b"\x1bOD".to_vec(),
+ (KeyCode::Up, false) => b"\x1b[A".to_vec(),
+ (KeyCode::Down, false) => b"\x1b[B".to_vec(),
+ (KeyCode::Right, false) => b"\x1b[C".to_vec(),
+ (KeyCode::Left, false) => b"\x1b[D".to_vec(),
+ _ => encode_legacy(KeyEvent::new(code, KeyModifiers::empty())),
+ }
+}
+
+pub fn encode_mouse_scroll(
+ kind: MouseEventKind,
+ column: u16,
+ row: u16,
+ modifiers: KeyModifiers,
+ encoding: vt100::MouseProtocolEncoding,
+) -> Option<Vec<u8>> {
+ let button = match kind {
+ MouseEventKind::ScrollUp => 64u16,
+ MouseEventKind::ScrollDown => 65u16,
+ MouseEventKind::ScrollLeft => 66u16,
+ MouseEventKind::ScrollRight => 67u16,
+ _ => return None,
+ };
+
+ let mut cb = button;
+ if modifiers.contains(KeyModifiers::SHIFT) {
+ cb += 4;
+ }
+ if modifiers.contains(KeyModifiers::ALT) {
+ cb += 8;
+ }
+ if modifiers.contains(KeyModifiers::CONTROL) {
+ cb += 16;
+ }
+
+ let column = column as u32 + 1;
+ let row = row as u32 + 1;
+
+ match encoding {
+ vt100::MouseProtocolEncoding::Sgr => {
+ Some(format!("\x1b[<{cb};{column};{row}M").into_bytes())
+ }
+ vt100::MouseProtocolEncoding::Default => {
+ let cb = u8::try_from(cb + 32).ok()?;
+ let column = u8::try_from(column + 32).ok()?;
+ let row = u8::try_from(row + 32).ok()?;
+ Some(vec![0x1b, b'[', b'M', cb, column, row])
+ }
+ vt100::MouseProtocolEncoding::Utf8 => {
+ let mut bytes = Vec::with_capacity(16);
+ bytes.extend_from_slice(b"\x1b[M");
+ push_mouse_codepoint(&mut bytes, cb as u32 + 32)?;
+ push_mouse_codepoint(&mut bytes, column + 32)?;
+ push_mouse_codepoint(&mut bytes, row + 32)?;
+ Some(bytes)
+ }
+ }
+}
+
+fn push_mouse_codepoint(bytes: &mut Vec<u8>, value: u32) -> Option<()> {
+ let ch = char::from_u32(value)?;
+ let mut buf = [0u8; 4];
+ bytes.extend_from_slice(ch.encode_utf8(&mut buf).as_bytes());
+ Some(())
+}
+
/// CSI u encoding: \e[{codepoint};{modifiers}u
/// Used when the child has pushed Kitty keyboard enhancement.
/// Returns None if the key doesn't need CSI u (unmodified basic keys).