From a720a765b4c85a867a2a807ac649efc2cd69ac1f Mon Sep 17 00:00:00 2001 From: Christian Duerr Date: Tue, 15 Oct 2024 14:06:59 +0000 Subject: [PATCH] Add IME support to inline search This changes the behavior of inline search from only accepting direct key inputs, to also accepting IME and paste. The additional characters are still being discarded, matching the existing behavior. This also fixes an issue where inline search wouldn't work for characters requiring modifiers, since the modifier press was interpreted as the search target instead. Closes #8208. --- CHANGELOG.md | 1 + alacritty/src/display/mod.rs | 7 +++++-- alacritty/src/event.rs | 19 +++++++++++++++++++ alacritty/src/input/keyboard.rs | 15 +++++---------- alacritty/src/input/mod.rs | 1 + 5 files changed, 31 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 15063ca9..d14aa188 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -50,6 +50,7 @@ Notable changes to the `alacritty_terminal` crate are documented in its - Alacritty not being properly activated with startup notify - Invalid URL highlights after terminal scrolling - Hollow block cursor not spanning multiple chars being edited inside the IME preview +- Vi inline search only working for direct key input without modifiers ## 0.13.2 diff --git a/alacritty/src/display/mod.rs b/alacritty/src/display/mod.rs index a8501da6..d0044f8b 100644 --- a/alacritty/src/display/mod.rs +++ b/alacritty/src/display/mod.rs @@ -884,8 +884,11 @@ impl Display { }, None => { let num_lines = self.size_info.screen_lines(); - term::point_to_viewport(display_offset, cursor_point) - .filter(|point| point.line < num_lines) + match vi_cursor_viewport_point { + None => term::point_to_viewport(display_offset, cursor_point) + .filter(|point| point.line < num_lines), + point => point, + } }, }; diff --git a/alacritty/src/event.rs b/alacritty/src/event.rs index 46e9433c..23575e21 100644 --- a/alacritty/src/event.rs +++ b/alacritty/src/event.rs @@ -1218,6 +1218,8 @@ impl<'a, N: Notify + 'a, T: EventListener> input::ActionContext for ActionCon for c in text.chars() { self.search_input(c); } + } else if self.inline_search_state.char_pending { + self.inline_search_input(text); } else if bracketed && self.terminal().mode().contains(TermMode::BRACKETED_PASTE) { self.on_terminal_input_start(); @@ -1291,6 +1293,7 @@ impl<'a, N: Notify + 'a, T: EventListener> input::ActionContext for ActionCon self.inline_search_state.stop_short = stop_short; self.inline_search_state.direction = direction; self.inline_search_state.char_pending = true; + self.inline_search_state.character = None; } /// Jump to the next matching character in the line. @@ -1305,6 +1308,22 @@ impl<'a, N: Notify + 'a, T: EventListener> input::ActionContext for ActionCon self.inline_search(direction); } + /// Process input during inline search. + fn inline_search_input(&mut self, text: &str) { + // Ignore input with empty text, like modifier keys. + let c = match text.chars().next() { + Some(c) => c, + None => return, + }; + + self.inline_search_state.char_pending = false; + self.inline_search_state.character = Some(c); + self.window().set_ime_allowed(false); + + // Immediately move to the captured character. + self.inline_search_next(); + } + fn message(&self) -> Option<&Message> { self.message_buffer.message() } diff --git a/alacritty/src/input/keyboard.rs b/alacritty/src/input/keyboard.rs index 4bc3ffee..14755594 100644 --- a/alacritty/src/input/keyboard.rs +++ b/alacritty/src/input/keyboard.rs @@ -1,5 +1,4 @@ use std::borrow::Cow; -use std::mem; use winit::event::{ElementState, KeyEvent}; #[cfg(target_os = "macos")] @@ -29,6 +28,9 @@ impl> Processor { let mods = self.ctx.modifiers().state(); if key.state == ElementState::Released { + if self.ctx.inline_search_state().char_pending { + self.ctx.window().set_ime_allowed(true); + } self.key_release(key, mode, mods); return; } @@ -45,15 +47,8 @@ impl> Processor { // First key after inline search is captured. let inline_state = self.ctx.inline_search_state(); - if mem::take(&mut inline_state.char_pending) { - if let Some(c) = text.chars().next() { - inline_state.character = Some(c); - - // Immediately move to the captured character. - self.ctx.inline_search_next(); - } - - // Ignore all other characters in `text`. + if inline_state.char_pending { + self.ctx.inline_search_input(text); return; } diff --git a/alacritty/src/input/mod.rs b/alacritty/src/input/mod.rs index c10777f2..bbd8673f 100644 --- a/alacritty/src/input/mod.rs +++ b/alacritty/src/input/mod.rs @@ -127,6 +127,7 @@ pub trait ActionContext { fn inline_search_state(&mut self) -> &mut InlineSearchState; fn start_inline_search(&mut self, _direction: Direction, _stop_short: bool) {} fn inline_search_next(&mut self) {} + fn inline_search_input(&mut self, _text: &str) {} fn inline_search_previous(&mut self) {} fn hint_input(&mut self, _character: char) {} fn trigger_hint(&mut self, _hint: &HintMatch) {}