fix(compatibility): home and end key fix (#815)

* fix(compatibility): handle home/end keys properly from terminfo

* style(fmt): make rustfmt happy

* style(fmt): remove unused import
This commit is contained in:
Aram Drevekenin 2021-10-29 15:28:36 +02:00 committed by GitHub
parent 2ac1454ec0
commit 6d47d360e1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 196 additions and 10 deletions

171
Cargo.lock generated
View file

@ -653,6 +653,27 @@ dependencies = [
"dirs-sys-next",
]
[[package]]
name = "dirs"
version = "2.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13aea89a5c93364a98e9b37b2fa237effbb694d5cfe01c5b70941f7eb087d5e3"
dependencies = [
"cfg-if 0.1.10",
"dirs-sys",
]
[[package]]
name = "dirs-sys"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "03d86534ed367a67548dc68113a0f5db55432fdfbb6e6f9d77704397d95d5780"
dependencies = [
"libc",
"redox_users",
"winapi",
]
[[package]]
name = "dirs-sys-next"
version = "0.1.2"
@ -883,6 +904,17 @@ dependencies = [
"unicode-width",
]
[[package]]
name = "getrandom"
version = "0.1.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce"
dependencies = [
"cfg-if 1.0.0",
"libc",
"wasi 0.9.0+wasi-snapshot-preview1",
]
[[package]]
name = "getrandom"
version = "0.2.3"
@ -891,7 +923,7 @@ checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753"
dependencies = [
"cfg-if 1.0.0",
"libc",
"wasi",
"wasi 0.10.0+wasi-snapshot-preview1",
]
[[package]]
@ -1304,6 +1336,16 @@ dependencies = [
"libc",
]
[[package]]
name = "nom"
version = "5.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ffb4262d26ed83a1c0a33a38fe2bb15797329c85770da05e6b828ddb782627af"
dependencies = [
"memchr",
"version_check",
]
[[package]]
name = "ntapi"
version = "0.3.6"
@ -1429,6 +1471,44 @@ version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
[[package]]
name = "phf"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3dfb61232e34fcb633f43d12c58f83c1df82962dcdfa565a4e866ffc17dafe12"
dependencies = [
"phf_shared",
]
[[package]]
name = "phf_codegen"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cbffee61585b0411840d3ece935cce9cb6321f01c45477d30066498cd5e1a815"
dependencies = [
"phf_generator",
"phf_shared",
]
[[package]]
name = "phf_generator"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "17367f0cc86f2d25802b2c26ee58a7b23faeccf78a396094c13dced0d0182526"
dependencies = [
"phf_shared",
"rand 0.7.3",
]
[[package]]
name = "phf_shared"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c00cf8b9eafe68dde5e9eaa2cef8ee84a9336a47d566ec55ca16589633b65af7"
dependencies = [
"siphasher",
]
[[package]]
name = "pin-project-lite"
version = "0.2.7"
@ -1553,6 +1633,20 @@ dependencies = [
"winapi",
]
[[package]]
name = "rand"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
dependencies = [
"getrandom 0.1.16",
"libc",
"rand_chacha 0.2.2",
"rand_core 0.5.1",
"rand_hc 0.2.0",
"rand_pcg",
]
[[package]]
name = "rand"
version = "0.8.4"
@ -1560,9 +1654,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8"
dependencies = [
"libc",
"rand_chacha",
"rand_chacha 0.3.1",
"rand_core 0.6.3",
"rand_hc",
"rand_hc 0.3.1",
]
[[package]]
name = "rand_chacha"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402"
dependencies = [
"ppv-lite86",
"rand_core 0.5.1",
]
[[package]]
@ -1590,13 +1694,31 @@ version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc"
[[package]]
name = "rand_core"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
dependencies = [
"getrandom 0.1.16",
]
[[package]]
name = "rand_core"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7"
dependencies = [
"getrandom",
"getrandom 0.2.3",
]
[[package]]
name = "rand_hc"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
dependencies = [
"rand_core 0.5.1",
]
[[package]]
@ -1608,6 +1730,15 @@ dependencies = [
"rand_core 0.6.3",
]
[[package]]
name = "rand_pcg"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429"
dependencies = [
"rand_core 0.5.1",
]
[[package]]
name = "rayon"
version = "1.5.1"
@ -1672,7 +1803,7 @@ version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "528532f3d801c87aec9def2add9ca802fe569e44a544afe633765267840abe64"
dependencies = [
"getrandom",
"getrandom 0.2.3",
"redox_syscall 0.2.10",
]
@ -1847,6 +1978,12 @@ version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ad1d488a557b235fc46dae55512ffbfc429d2482b08b4d9435ab07384ca8aec"
[[package]]
name = "siphasher"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "533494a8f9b724d33625ab53c6c4800f7cc445895924a8ef649222dcb76e938b"
[[package]]
name = "slab"
version = "0.4.5"
@ -2041,6 +2178,19 @@ dependencies = [
"winapi",
]
[[package]]
name = "terminfo"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "76971977e6121664ec1b960d1313aacfa75642adc93b9d4d53b247bd4cb1747e"
dependencies = [
"dirs",
"fnv",
"nom",
"phf",
"phf_codegen",
]
[[package]]
name = "termion"
version = "1.5.6"
@ -2100,7 +2250,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255"
dependencies = [
"libc",
"wasi",
"wasi 0.10.0+wasi-snapshot-preview1",
"winapi",
]
@ -2313,6 +2463,12 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca"
[[package]]
name = "wasi"
version = "0.9.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
[[package]]
name = "wasi"
version = "0.10.0+wasi-snapshot-preview1"
@ -2568,7 +2724,7 @@ dependencies = [
"bincode",
"byteorder",
"generational-arena",
"getrandom",
"getrandom 0.2.3",
"libc",
"serde",
"thiserror",
@ -2686,6 +2842,7 @@ dependencies = [
"log",
"mio",
"termbg",
"terminfo",
"zellij-tile",
"zellij-utils",
]

View file

@ -14,6 +14,7 @@ termbg = "0.2.3"
zellij-utils = { path = "../zellij-utils/", version = "0.20.0" }
zellij-tile = { path = "../zellij-tile/", version = "0.20.0" }
log = "0.4.14"
terminfo = "0.7.3"
[dev-dependencies]
insta = "1.6.0"

View file

@ -1,10 +1,34 @@
use crate::os_input_output::ClientOsApi;
use crate::InputInstruction;
use std::collections::HashMap;
use terminfo::{capability as cap, Database as TerminfoDatabase};
use termion::input::TermReadEventsAndRaw;
use zellij_utils::channels::SenderWithContext;
use zellij_utils::input::mouse::MouseEvent;
use zellij_utils::termion;
fn keys_to_adjust() -> HashMap<Vec<u8>, Vec<u8>> {
let mut keys_to_adjust = HashMap::new();
if let Ok(terminfo_db) = TerminfoDatabase::from_env() {
// TODO: there might be more adjustments we can do here, but I held off on them because I'm
// not sure they're a thing in these modern times. It should be pretty straightforward to
// implement them if they are...
if let Some(adjusted_home_key) = terminfo_db
.get::<cap::KeyHome>()
.and_then(|k| k.expand().to_vec().ok())
{
keys_to_adjust.insert(vec![27, 91, 72], adjusted_home_key);
}
if let Some(adjusted_end_key) = terminfo_db
.get::<cap::KeyEnd>()
.and_then(|k| k.expand().to_vec().ok())
{
keys_to_adjust.insert(vec![27, 91, 70], adjusted_end_key);
}
}
keys_to_adjust
}
fn bracketed_paste_end_position(stdin_buffer: &[u8]) -> Option<usize> {
let bracketed_paste_end = vec![27, 91, 50, 48, 49, 126]; // \u{1b}[201
let mut bp_position = 0;
@ -34,6 +58,7 @@ pub(crate) fn stdin_loop(
) {
let mut pasting = false;
let bracketed_paste_start = vec![27, 91, 50, 48, 48, 126]; // \u{1b}[200~
let adjusted_keys = keys_to_adjust();
loop {
let mut stdin_buffer = os_input.read_from_stdin();
if pasting
@ -65,6 +90,7 @@ pub(crate) fn stdin_loop(
}
for key_result in stdin_buffer.events_and_raw() {
let (key_event, raw_bytes) = key_result.unwrap();
let raw_bytes = adjusted_keys.get(&raw_bytes).cloned().unwrap_or(raw_bytes);
if let termion::event::Event::Mouse(me) = key_event {
let mouse_event = zellij_utils::input::mouse::MouseEvent::from(me);
if let MouseEvent::Hold(_) = mouse_event {

View file

@ -190,7 +190,7 @@ impl Keybinds {
/// [`InputMode`] and [`Keybinds`].
pub fn key_to_actions(
key: &Key,
input: Vec<u8>,
raw_bytes: Vec<u8>,
mode: &InputMode,
keybinds: &Keybinds,
) -> Vec<Action> {
@ -205,8 +205,10 @@ impl Keybinds {
.unwrap_or_else(|| vec![action])
};
match *mode {
InputMode::Normal | InputMode::Locked => mode_keybind_or_action(Action::Write(input)),
InputMode::RenameTab => mode_keybind_or_action(Action::TabNameInput(input)),
InputMode::Normal | InputMode::Locked => {
mode_keybind_or_action(Action::Write(raw_bytes))
}
InputMode::RenameTab => mode_keybind_or_action(Action::TabNameInput(raw_bytes)),
_ => mode_keybind_or_action(Action::NoOp),
}
}