Change summary
crates/gpui/src/platform/keystroke.rs | 29 +++++++++++++++++++++++++++++
crates/gpui/src/window.rs | 14 ++------------
crates/vim/src/test.rs | 12 ++++++++++++
3 files changed, 43 insertions(+), 12 deletions(-)
Detailed changes
@@ -108,6 +108,35 @@ impl Keystroke {
ime_key,
})
}
+
+ /// 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.
+ pub fn with_simulated_ime(mut self) -> Self {
+ if self.ime_key.is_none()
+ && !self.modifiers.command
+ && !self.modifiers.control
+ && !self.modifiers.function
+ && !self.modifiers.alt
+ {
+ self.ime_key = match self.key.as_str() {
+ "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 self.modifiers.shift {
+ Some(key.to_uppercase())
+ } else {
+ Some(key.into())
+ }
+ }
+ }
+ }
+ self
+ }
}
impl std::fmt::Display for Keystroke {
@@ -1101,18 +1101,8 @@ impl<'a> WindowContext<'a> {
/// Dispatch a given keystroke as though the user had typed it.
/// You can create a keystroke with Keystroke::parse("").
- pub fn dispatch_keystroke(&mut self, mut keystroke: Keystroke) -> bool {
- if keystroke.ime_key.is_none()
- && !keystroke.modifiers.command
- && !keystroke.modifiers.control
- && !keystroke.modifiers.function
- {
- keystroke.ime_key = Some(if keystroke.modifiers.shift {
- keystroke.key.to_uppercase().clone()
- } else {
- keystroke.key.clone()
- })
- }
+ pub fn dispatch_keystroke(&mut self, keystroke: Keystroke) -> bool {
+ let keystroke = keystroke.with_simulated_ime();
if self.dispatch_event(PlatformInput::KeyDown(KeyDownEvent {
keystroke: keystroke.clone(),
is_held: false,
@@ -950,4 +950,16 @@ async fn test_remap(cx: &mut gpui::TestAppContext) {
cx.set_state("ˇ1234\n56789", Mode::Normal);
cx.simulate_keystrokes(["g", "u"]);
cx.assert_state("1234 567ˇ89", Mode::Normal);
+
+ // test leaving command
+ cx.update(|cx| {
+ cx.bind_keys([KeyBinding::new(
+ "g t",
+ workspace::SendKeystrokes("i space escape".to_string()),
+ None,
+ )])
+ });
+ cx.set_state("12ˇ34", Mode::Normal);
+ cx.simulate_keystrokes(["g", "t"]);
+ cx.assert_state("12ˇ 34", Mode::Normal);
}