Make workspace::SendKeystrokes not use layout key equivalents (#47061)
Closes #46509 Release Notes: - Fixed: `workspace::SendKeystrokes` would not allow remapping keys in different keyboard layouts --------- Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
This commit is contained in:
1 parent
cb84a955ed
commit
a74abd34f1
2 files changed
+120
-1
No files matched your search
@@ -2540,6 +2540,125 @@ async fn test_deactivate(cx: &mut gpui::TestAppContext) {
|
||||
});
|
||||
}
|
||||
|
||||
// workspace::SendKeystrokes should pass literal keystrokes without triggering vim motions.
|
||||
// When sending `" _ x`, the `_` should select the blackhole register, not trigger
|
||||
// vim::StartOfLineDownward.
|
||||
#[gpui::test]
|
||||
async fn test_send_keystrokes_underscore_is_literal_46509(cx: &mut gpui::TestAppContext) {
|
||||
let mut cx = VimTestContext::new(cx, true).await;
|
||||
|
||||
// Bind a key to send `" _ x` which should:
|
||||
// `"` - start register selection
|
||||
// `_` - select blackhole register (NOT vim::StartOfLineDownward)
|
||||
// `x` - delete character into blackhole register
|
||||
cx.update(|_, cx| {
|
||||
cx.bind_keys([KeyBinding::new(
|
||||
"g x",
|
||||
workspace::SendKeystrokes("\" _ x".to_string()),
|
||||
Some("VimControl"),
|
||||
)])
|
||||
});
|
||||
|
||||
cx.set_state("helˇlo", Mode::Normal);
|
||||
|
||||
cx.simulate_keystrokes("g x");
|
||||
cx.run_until_parked();
|
||||
|
||||
cx.assert_state("helˇo", Mode::Normal);
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
async fn test_send_keystrokes_no_key_equivalent_mapping_46509(cx: &mut gpui::TestAppContext) {
|
||||
use collections::HashMap;
|
||||
use gpui::{KeybindingKeystroke, Keystroke, PlatformKeyboardMapper};
|
||||
|
||||
// create a mock Danish keyboard mapper
|
||||
// on Danish keyboards, the macOS key equivalents mapping includes: '{' -> 'Æ' and '}' -> 'Ø'
|
||||
// this means the `{` character is produced by the key labeled `Æ` (with shift modifier)
|
||||
struct DanishKeyboardMapper;
|
||||
impl PlatformKeyboardMapper for DanishKeyboardMapper {
|
||||
fn map_key_equivalent(
|
||||
&self,
|
||||
mut keystroke: Keystroke,
|
||||
use_key_equivalents: bool,
|
||||
) -> KeybindingKeystroke {
|
||||
if use_key_equivalents {
|
||||
if keystroke.key == "{" {
|
||||
keystroke.key = "Æ".to_string();
|
||||
}
|
||||
if keystroke.key == "}" {
|
||||
keystroke.key = "Ø".to_string();
|
||||
}
|
||||
}
|
||||
KeybindingKeystroke::from_keystroke(keystroke)
|
||||
}
|
||||
|
||||
fn get_key_equivalents(&self) -> Option<&HashMap<char, char>> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
let mapper = DanishKeyboardMapper;
|
||||
|
||||
let keystroke_brace = Keystroke::parse("{").unwrap();
|
||||
let mapped_with_bug = mapper.map_key_equivalent(keystroke_brace.clone(), true);
|
||||
assert_eq!(
|
||||
mapped_with_bug.key(),
|
||||
"Æ",
|
||||
"BUG: With use_key_equivalents=true, {{ is mapped to Æ on Danish keyboard"
|
||||
);
|
||||
|
||||
// Fixed behavior, where the literal `{` character is preserved
|
||||
let mapped_fixed = mapper.map_key_equivalent(keystroke_brace.clone(), false);
|
||||
assert_eq!(
|
||||
mapped_fixed.key(),
|
||||
"{",
|
||||
"FIX: With use_key_equivalents=false, {{ stays as {{"
|
||||
);
|
||||
|
||||
// Same applies to }
|
||||
let keystroke_close = Keystroke::parse("}").unwrap();
|
||||
let mapped_close_bug = mapper.map_key_equivalent(keystroke_close.clone(), true);
|
||||
assert_eq!(mapped_close_bug.key(), "Ø");
|
||||
let mapped_close_fixed = mapper.map_key_equivalent(keystroke_close.clone(), false);
|
||||
assert_eq!(mapped_close_fixed.key(), "}");
|
||||
|
||||
let mut cx = VimTestContext::new(cx, true).await;
|
||||
|
||||
cx.update(|_, cx| {
|
||||
cx.bind_keys([KeyBinding::new(
|
||||
"g p",
|
||||
workspace::SendKeystrokes("{".to_string()),
|
||||
Some("vim_mode == normal"),
|
||||
)])
|
||||
});
|
||||
|
||||
cx.set_state(
|
||||
indoc! {"
|
||||
first paragraph
|
||||
|
||||
second paragraphˇ
|
||||
|
||||
third paragraph
|
||||
"},
|
||||
Mode::Normal,
|
||||
);
|
||||
|
||||
cx.simulate_keystrokes("g p");
|
||||
cx.run_until_parked();
|
||||
|
||||
cx.assert_state(
|
||||
indoc! {"
|
||||
first paragraph
|
||||
ˇ
|
||||
second paragraph
|
||||
|
||||
third paragraph
|
||||
"},
|
||||
Mode::Normal,
|
||||
);
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
async fn test_project_search_opens_in_normal_mode(cx: &mut gpui::TestAppContext) {
|
||||
VimTestContext::init(cx);
|
||||
|
||||
@@ -2722,7 +2722,7 @@ impl Workspace {
|
||||
.flat_map(|k| Keystroke::parse(k).log_err())
|
||||
.map(|k| {
|
||||
cx.keyboard_mapper()
|
||||
.map_key_equivalent(k, true)
|
||||
.map_key_equivalent(k, false)
|
||||
.inner()
|
||||
.clone()
|
||||
})
|
||||
|
||||
Reference in new issue
Block a user