mirror of
https://github.com/fish-shell/fish-shell.git
synced 2025-02-14 05:22:46 +08:00
Probe for kitty keyboard protocol support
Some checks are pending
make test / ubuntu (push) Waiting to run
make test / ubuntu-32bit-static-pcre2 (push) Waiting to run
make test / ubuntu-asan (push) Waiting to run
make test / macos (push) Waiting to run
Rust checks / rustfmt (push) Waiting to run
Rust checks / clippy (push) Waiting to run
Some checks are pending
make test / ubuntu (push) Waiting to run
make test / ubuntu-32bit-static-pcre2 (push) Waiting to run
make test / ubuntu-asan (push) Waiting to run
make test / macos (push) Waiting to run
Rust checks / rustfmt (push) Waiting to run
Rust checks / clippy (push) Waiting to run
I believe this fixes more cases than it breaks. For example this should fix Termux which seems to be popular among fish users. Unfortunately I haven't yet managed to test that one. Cherry-pick of all of -e49dde87cc
(Probe for kitty keyboard protocol support, 2025-01-03) -10f1f21a4f
(Don't send kitty kbd protocol probe until ECHO is disabled, 2025-01-05) -dda4371679
(Stop sending CSI 5n when querying for kitty keyboard support, 2025-01-05)
This commit is contained in:
parent
620eed466b
commit
4decacb933
|
@ -9,19 +9,19 @@
|
|||
|
||||
use std::{ops::ControlFlow, os::unix::prelude::OsStrExt};
|
||||
|
||||
use libc::{STDIN_FILENO, TCSANOW, VEOF, VINTR};
|
||||
use libc::{STDIN_FILENO, STDOUT_FILENO, TCSANOW, VEOF, VINTR};
|
||||
|
||||
#[allow(unused_imports)]
|
||||
use fish::future::IsSomeAnd;
|
||||
use fish::{
|
||||
builtins::shared::BUILTIN_ERR_UNKNOWN,
|
||||
common::{shell_modes, str2wcstring, PROGRAM_NAME},
|
||||
common::{shell_modes, str2wcstring, write_loop, PROGRAM_NAME},
|
||||
env::env_init,
|
||||
eprintf, fprintf,
|
||||
input::input_terminfo_get_name,
|
||||
input_common::{
|
||||
terminal_protocol_hacks, terminal_protocols_enable_ifn, CharEvent, InputEventQueue,
|
||||
InputEventQueuer,
|
||||
InputEventQueuer, KITTY_PROGRESSIVE_ENHANCEMENTS_QUERY,
|
||||
},
|
||||
key::{self, char_to_symbol, Key},
|
||||
panic::panic_handler,
|
||||
|
@ -140,6 +140,7 @@ fn setup_and_process_keys(continuous_mode: bool, verbose: bool) -> i32 {
|
|||
unsafe { libc::tcsetattr(STDIN_FILENO, TCSANOW, &*shell_modes()) };
|
||||
|
||||
terminal_protocol_hacks();
|
||||
let _ = write_loop(&STDOUT_FILENO, KITTY_PROGRESSIVE_ENHANCEMENTS_QUERY);
|
||||
|
||||
if continuous_mode {
|
||||
eprintf!("\n");
|
||||
|
|
|
@ -431,10 +431,19 @@ pub fn update_wait_on_sequence_key_ms(vars: &EnvStack) {
|
|||
|
||||
static TERMINAL_PROTOCOLS: AtomicBool = AtomicBool::new(false);
|
||||
|
||||
static KITTY_KEYBOARD_SUPPORTED: RelaxedAtomicBool = RelaxedAtomicBool::new(false);
|
||||
|
||||
macro_rules! kitty_progressive_enhancements {
|
||||
() => {
|
||||
"\x1b[=5u"
|
||||
};
|
||||
}
|
||||
|
||||
pub const KITTY_PROGRESSIVE_ENHANCEMENTS_QUERY: &[u8] = b"\x1b[?u";
|
||||
|
||||
static IS_TMUX: RelaxedAtomicBool = RelaxedAtomicBool::new(false);
|
||||
pub static IN_MIDNIGHT_COMMANDER_PRE_CSI_U: RelaxedAtomicBool = RelaxedAtomicBool::new(false);
|
||||
static IN_ITERM_PRE_CSI_U: RelaxedAtomicBool = RelaxedAtomicBool::new(false);
|
||||
static IN_JETBRAINS: RelaxedAtomicBool = RelaxedAtomicBool::new(false);
|
||||
|
||||
pub fn terminal_protocol_hacks() {
|
||||
use std::env::var_os;
|
||||
|
@ -449,10 +458,6 @@ pub fn terminal_protocol_hacks() {
|
|||
version < (3, 5, 6)
|
||||
}),
|
||||
);
|
||||
IN_JETBRAINS.store(
|
||||
var_os("TERMINAL_EMULATOR")
|
||||
.is_some_and(|term| term.as_os_str().as_bytes() == b"JetBrains-JediTerm"),
|
||||
);
|
||||
}
|
||||
|
||||
fn parse_version(version: &wstr) -> Option<(i64, i64, i64)> {
|
||||
|
@ -483,15 +488,14 @@ pub fn terminal_protocols_enable_ifn() {
|
|||
"\x1b[?2004h"
|
||||
} else if IN_ITERM_PRE_CSI_U.load() {
|
||||
concat!("\x1b[?2004h", "\x1b[>4;1m", "\x1b[>5u", "\x1b=",)
|
||||
} else if IN_JETBRAINS.load() {
|
||||
// Jetbrains IDE terminals vomit CSI u
|
||||
} else if !KITTY_KEYBOARD_SUPPORTED.load() {
|
||||
concat!("\x1b[?2004h", "\x1b[>4;1m", "\x1b=",)
|
||||
} else {
|
||||
concat!(
|
||||
"\x1b[?2004h", // Bracketed paste
|
||||
"\x1b[>4;1m", // XTerm's modifyOtherKeys
|
||||
"\x1b[=5u", // CSI u with kitty progressive enhancement
|
||||
"\x1b=", // set application keypad mode, so the keypad keys send unique codes
|
||||
kitty_progressive_enhancements!(),
|
||||
"\x1b=", // set application keypad mode, so the keypad keys send unique codes
|
||||
)
|
||||
};
|
||||
FLOG!(term_protocols, "Enabling extended keys and bracketed paste");
|
||||
|
@ -508,7 +512,7 @@ pub(crate) fn terminal_protocols_disable_ifn() {
|
|||
}
|
||||
let sequences = if IN_ITERM_PRE_CSI_U.load() {
|
||||
concat!("\x1b[?2004l", "\x1b[>4;0m", "\x1b[<1u", "\x1b>",)
|
||||
} else if IN_JETBRAINS.load() {
|
||||
} else if !KITTY_KEYBOARD_SUPPORTED.load() {
|
||||
concat!("\x1b[?2004l", "\x1b[>4;0m", "\x1b>",)
|
||||
} else {
|
||||
concat!(
|
||||
|
@ -989,6 +993,21 @@ pub trait InputEventQueuer {
|
|||
_ => return None,
|
||||
},
|
||||
b'u' => {
|
||||
if private_mode == Some(b'?') {
|
||||
FLOG!(
|
||||
reader,
|
||||
"Received kitty progressive enhancement flags, marking as supported"
|
||||
);
|
||||
KITTY_KEYBOARD_SUPPORTED.store(true);
|
||||
if !IN_MIDNIGHT_COMMANDER_PRE_CSI_U.load() && !IN_ITERM_PRE_CSI_U.load() {
|
||||
let _ = write_loop(
|
||||
&STDOUT_FILENO,
|
||||
kitty_progressive_enhancements!().as_bytes(),
|
||||
);
|
||||
}
|
||||
return None;
|
||||
}
|
||||
|
||||
// Treat numpad keys the same as their non-numpad counterparts. Could add a numpad modifier here.
|
||||
let key = match params[0][0] {
|
||||
57399 => '0',
|
||||
|
|
|
@ -78,6 +78,7 @@ use crate::history::{
|
|||
use crate::input::init_input;
|
||||
use crate::input_common::terminal_protocols_disable_ifn;
|
||||
use crate::input_common::IN_MIDNIGHT_COMMANDER_PRE_CSI_U;
|
||||
use crate::input_common::KITTY_PROGRESSIVE_ENHANCEMENTS_QUERY;
|
||||
use crate::input_common::{
|
||||
terminal_protocol_hacks, terminal_protocols_enable_ifn, CharEvent, CharInputStyle, InputData,
|
||||
ReadlineCmd,
|
||||
|
@ -1932,6 +1933,13 @@ impl<'a> Reader<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
static queried: RelaxedAtomicBool = RelaxedAtomicBool::new(false);
|
||||
if !queried.load() {
|
||||
queried.store(true);
|
||||
// Query for kitty keyboard protocol support.
|
||||
let _ = write_loop(&STDOUT_FILENO, KITTY_PROGRESSIVE_ENHANCEMENTS_QUERY);
|
||||
}
|
||||
|
||||
// HACK: Don't abandon line for the first prompt, because
|
||||
// if we're started with the terminal it might not have settled,
|
||||
// so the width is quite likely to be in flight.
|
||||
|
|
Loading…
Reference in New Issue
Block a user