From b061178606a36edfaaab36b13b708992407daebc Mon Sep 17 00:00:00 2001 From: Johannes Altmanninger Date: Mon, 14 Apr 2025 23:51:34 +0200 Subject: [PATCH] Reduce parse_codepoint responsibilities, fixing alt in single-byte locale? This also changes the single-byte locale code path to treat keyboard input like "\x1ba" as alt-a instead of "escape,a". I can't off-hand reproduce a problem with "LC_ALL=C fish_key_reader", I guess we always use a UTF-8 locale if available? --- src/input_common.rs | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/src/input_common.rs b/src/input_common.rs index 5d9b954df..a0dce0cd0 100644 --- a/src/input_common.rs +++ b/src/input_common.rs @@ -874,19 +874,23 @@ fn try_readch(&mut self, blocking: bool) -> Option { } match self.parse_codepoint( &mut state, - &mut key, &mut seq, - &buffer, - i, + &buffer[..i + 1], &mut consumed, - &mut have_escape_prefix, ) { - ControlFlow::Continue(codepoint_complete) => { - if codepoint_complete && i + 1 == buffer.len() { + ControlFlow::Continue(/*codepoint_complete=*/ false) => (), + ControlFlow::Continue(/*codepoint_complete=*/ true) => { + if have_escape_prefix && i != 0 { + have_escape_prefix = false; + let c = seq.as_char_slice().last().unwrap(); + key = Some(KeyEvent::from(alt(*c))); + } + if i + 1 == buffer.len() { break true; } } ControlFlow::Break(()) => { + self.push_front(CharEvent::from_check_exit()); break false; } } @@ -1001,15 +1005,12 @@ fn parse_escape_sequence( fn parse_codepoint( &mut self, state: &mut mbstate_t, - out_key: &mut Option, out_seq: &mut WString, buffer: &[u8], - i: usize, consumed: &mut usize, - have_escape_prefix: &mut bool, ) -> ControlFlow<(), bool> { let mut res: char = '\0'; - let read_byte = buffer[i]; + let read_byte = *buffer.last().unwrap(); if crate::libc::MB_CUR_MAX() == 1 { // single-byte locale, all values are legal // FIXME: this looks wrong, this falsely assumes that @@ -1031,7 +1032,6 @@ fn parse_codepoint( -1 => { FLOG!(reader, "Illegal input"); *consumed += 1; - self.push_front(CharEvent::from_check_exit()); return ControlFlow::Break(()); } -2 => { @@ -1043,16 +1043,12 @@ fn parse_codepoint( if let Some(res) = char::from_u32(codepoint) { // Sequence complete. if !fish_reserved_codepoint(res) { - if *have_escape_prefix && i != 0 { - *have_escape_prefix = false; - *out_key = Some(KeyEvent::from(alt(res))); - } *consumed += 1; out_seq.push(res); return ControlFlow::Continue(true); } } - for &b in &buffer[*consumed..i] { + for &b in &buffer[*consumed..] { out_seq.push(encode_byte_to_char(b)); *consumed += 1; }