Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(keybindings): support multiple modifiers (eg. Ctrl+Alt) and the kitty keyboard protocol #3383

Merged
merged 15 commits into from
May 27, 2024
Prev Previous commit
Next Next commit
handle enabling/disabling properly on the client
  • Loading branch information
imsnif committed May 23, 2024
commit f9c0df70beef3770fe95aecc6b909cae8bcbf822
20 changes: 14 additions & 6 deletions zellij-client/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -179,11 +179,12 @@ pub fn start_client(
}
info!("Starting Zellij client!");

let explicitly_disable_kitty_keyboard_protocol = config_options.support_kitty_keyboard_protocol.map(|e| !e).unwrap_or(false);
let mut reconnect_to_session = None;
let clear_client_terminal_attributes = "\u{1b}[?1l\u{1b}=\u{1b}[r\u{1b}[?1000l\u{1b}[?1002l\u{1b}[?1003l\u{1b}[?1005l\u{1b}[?1006l\u{1b}[?12l";
let take_snapshot = "\u{1b}[?1049h";
let bracketed_paste = "\u{1b}[?2004h";
let enter_kitty_keyboard_mode = "\u{1b}[>1u"; // TODO: also exit on app close!
let enter_kitty_keyboard_mode = "\u{1b}[>1u";
os_input.unset_raw_mode(0).unwrap();

if !is_a_reconnect {
Expand All @@ -198,10 +199,12 @@ pub fn start_client(
.get_stdout_writer()
.write(clear_client_terminal_attributes.as_bytes())
.unwrap();
let _ = os_input
.get_stdout_writer()
.write(enter_kitty_keyboard_mode.as_bytes())
.unwrap();
if !explicitly_disable_kitty_keyboard_protocol {
let _ = os_input
.get_stdout_writer()
.write(enter_kitty_keyboard_mode.as_bytes())
.unwrap();
}
}
envs::set_zellij("0".to_string());
config.env.set_vars();
Expand Down Expand Up @@ -306,7 +309,7 @@ pub fn start_client(
let os_input = os_input.clone();
let send_input_instructions = send_input_instructions.clone();
let stdin_ansi_parser = stdin_ansi_parser.clone();
move || stdin_loop(os_input, send_input_instructions, stdin_ansi_parser)
move || stdin_loop(os_input, send_input_instructions, stdin_ansi_parser, explicitly_disable_kitty_keyboard_protocol)
});

let _input_thread = thread::Builder::new()
Expand Down Expand Up @@ -540,6 +543,11 @@ pub fn start_client(
info!("{}", exit_msg);
os_input.unset_raw_mode(0).unwrap();
let mut stdout = os_input.get_stdout_writer();
let exit_kitty_keyboard_mode = "\u{1b}[<1u";
if !explicitly_disable_kitty_keyboard_protocol {
let _ = stdout.write(exit_kitty_keyboard_mode.as_bytes()).unwrap();
stdout.flush().unwrap();
}
let _ = stdout.write(goodbye_message.as_bytes()).unwrap();
stdout.flush().unwrap();
} else {
Expand Down
29 changes: 16 additions & 13 deletions zellij-client/src/stdin_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ pub(crate) fn stdin_loop(
mut os_input: Box<dyn ClientOsApi>,
send_input_instructions: SenderWithContext<InputInstruction>,
stdin_ansi_parser: Arc<Mutex<StdinAnsiParser>>,
explicitly_disable_kitty_keyboard_protocol: bool,
) {
let mut holding_mouse = false;
let mut input_parser = InputParser::new();
Expand Down Expand Up @@ -87,19 +88,21 @@ pub(crate) fn stdin_loop(
}
current_buffer.append(&mut buf.to_vec());

// first we try to parse with the KittyKeyboardParser
// if we fail, we try to parse normally
match KittyKeyboardParser::new().parse(&buf) {
Some(key_with_modifier) => {
send_input_instructions
.send(InputInstruction::KeyWithModifierEvent(
key_with_modifier,
current_buffer.drain(..).collect(),
))
.unwrap();
continue;
},
None => {}
if !explicitly_disable_kitty_keyboard_protocol {
// first we try to parse with the KittyKeyboardParser
// if we fail, we try to parse normally
match KittyKeyboardParser::new().parse(&buf) {
Some(key_with_modifier) => {
send_input_instructions
.send(InputInstruction::KeyWithModifierEvent(
key_with_modifier,
current_buffer.drain(..).collect(),
))
.unwrap();
continue;
},
None => {}
}
}

let maybe_more = false; // read_from_stdin should (hopefully) always empty the STDIN buffer completely
Expand Down