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.
This commit is contained in:
Johannes Altmanninger 2024-04-15 08:13:48 +02:00
parent a37629f869
commit 47bb56efe6
2 changed files with 24 additions and 8 deletions

View File

@ -653,15 +653,26 @@ impl EventQueuePeeker<'_> {
// 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);

View File

@ -7,6 +7,7 @@ use crate::common::{
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 @@ pub trait InputEventQueuer {
Some(key)
}
fn readch_timed_esc(&mut self) -> Option<CharEvent> {
fn readch_timed_esc(&mut self, style: &KeyNameStyle) -> Result<CharEvent, bool> {
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<CharEvent> {