From 47bb56efe649c3fe699da7f79735df8955cf4602 Mon Sep 17 00:00:00 2001 From: Johannes Altmanninger Date: Mon, 15 Apr 2024 08:13:48 +0200 Subject: [PATCH] Allow mapping new-style sequences that start with escape On Konsole with function my-bindings bind --preset --erase escape bind escape,i 'echo escape i' end set fish_key_bindings my-bindings the "escape,i" binding doesn't trigger. This is because of our special handling of the escape key prefix. Other multi-key bindings like "bind j,k" wait indefinitely for the second character. But not "escape,i"; that one has historically had a low timeout (fish_escape_delay_ms). The motivation is probably that we have a "escape" binding as well that shouldn't wait indefinitely. We can distinguish between the case of raw escape sequence binding like "\e123" and a binding that talks about the actual escape key like "escape,i". For the latter we don't need the special treatment of having a low timeout, so make it fall back to "fish_sequence_key_delay_ms" which waits indefinitely by default. --- src/input.rs | 23 +++++++++++++++++------ src/input_common.rs | 9 +++++++-- 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/src/input.rs b/src/input.rs index 31262d705..8793f13d3 100644 --- a/src/input.rs +++ b/src/input.rs @@ -653,15 +653,26 @@ fn next_is_char(&mut self, style: &KeyNameStyle, key: Key, escaped: bool) -> boo // Grab a new event if we have exhausted what we have already peeked. // Use either readch or readch_timed, per our param. if self.idx == self.peeked.len() { - let Some(newevt) = (if escaped { + let newevt = if escaped { FLOG!(reader, "reading timed escape"); - self.event_queue.readch_timed_esc() + match self.event_queue.readch_timed_esc(style) { + Ok(evt) => evt, + Err(timed_out) => { + if timed_out { + self.had_timeout = true; + } + return false; + } + } } else { FLOG!(reader, "readch timed sequence key"); - self.event_queue.readch_timed_sequence_key() - }) else { - self.had_timeout = true; - return false; + match self.event_queue.readch_timed_sequence_key() { + Some(evt) => evt, + None => { + self.had_timeout = true; + return false; + } + } }; FLOG!(reader, format!("adding peeked {:?}", newevt)); self.peeked.push(newevt); diff --git a/src/input_common.rs b/src/input_common.rs index 28dc6a39d..465bf8301 100644 --- a/src/input_common.rs +++ b/src/input_common.rs @@ -7,6 +7,7 @@ use crate::env::{EnvStack, Environment}; use crate::fd_readable_set::FdReadableSet; use crate::flog::FLOG; +use crate::input::KeyNameStyle; use crate::key::{ self, alt, canonicalize_control_char, canonicalize_keyed_control_char, function_key, shift, Key, Modifiers, @@ -993,12 +994,16 @@ fn parse_ss3(&mut self, buffer: &mut Vec) -> Option { Some(key) } - fn readch_timed_esc(&mut self) -> Option { + fn readch_timed_esc(&mut self, style: &KeyNameStyle) -> Result { let wait_ms = WAIT_ON_ESCAPE_MS.load(Ordering::Relaxed); if wait_ms == 0 { - return None; + if *style == KeyNameStyle::Plain { + return self.readch_timed_sequence_key().ok_or(true); + } + return Err(false); // Not timed out } self.readch_timed(WAIT_ON_ESCAPE_MS.load(Ordering::Relaxed)) + .ok_or(true) // Timed out } fn readch_timed_sequence_key(&mut self) -> Option {