diff --git a/crates/gpui/src/platform/keystroke.rs b/crates/gpui/src/platform/keystroke.rs index fa408165a6..d48c9358c4 100644 --- a/crates/gpui/src/platform/keystroke.rs +++ b/crates/gpui/src/platform/keystroke.rs @@ -109,6 +109,17 @@ impl Keystroke { }) } + /// Returns true if this keystroke left + /// the ime system in an incomplete state. + pub fn is_ime_in_progress(&self) -> bool { + self.ime_key.is_none() + && (is_printable_key(&self.key) || self.key.is_empty()) + && !(self.modifiers.platform + || self.modifiers.control + || self.modifiers.function + || self.modifiers.alt) + } + /// Returns a new keystroke with the ime_key filled. /// This is used for dispatch_keystroke where we want users to /// be able to simulate typing "space", etc. @@ -123,9 +134,7 @@ impl Keystroke { "space" => Some(" ".into()), "tab" => Some("\t".into()), "enter" => Some("\n".into()), - "up" | "down" | "left" | "right" | "pageup" | "pagedown" | "home" | "end" - | "delete" | "escape" | "backspace" | "f1" | "f2" | "f3" | "f4" | "f5" | "f6" - | "f7" | "f8" | "f9" | "f10" | "f11" | "f12" => None, + key if !is_printable_key(key) => None, key => { if self.modifiers.shift { Some(key.to_uppercase()) @@ -139,6 +148,15 @@ impl Keystroke { } } +fn is_printable_key(key: &str) -> bool { + match key { + "up" | "down" | "left" | "right" | "pageup" | "pagedown" | "home" | "end" | "delete" + | "escape" | "backspace" | "f1" | "f2" | "f3" | "f4" | "f5" | "f6" | "f7" | "f8" | "f9" + | "f10" | "f11" | "f12" => false, + _ => true, + } +} + impl std::fmt::Display for Keystroke { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { if self.modifiers.control { diff --git a/crates/vim/src/vim.rs b/crates/vim/src/vim.rs index 4f5ca7b558..a027059ea3 100644 --- a/crates/vim/src/vim.rs +++ b/crates/vim/src/vim.rs @@ -187,7 +187,7 @@ fn observe_keystrokes(keystroke_event: &KeystrokeEvent, cx: &mut WindowContext) if action.name().starts_with("vim::") { return; } - } else if cx.has_pending_keystrokes() { + } else if cx.has_pending_keystrokes() || keystroke_event.keystroke.is_ime_in_progress() { return; }