Fix ci" on a brazillian keyboard (#13185)

Conrad Irwin created

Fixes: #12523

Release Notes:

- vim: Fix ci" on keyboards where typing a " requires the IME (#12523)

Change summary

crates/gpui/src/platform/keystroke.rs | 24 +++++++++++++++++++++---
crates/vim/src/vim.rs                 |  2 +-
2 files changed, 22 insertions(+), 4 deletions(-)

Detailed changes

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 {

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;
     }