mirror of
https://github.com/helix-editor/helix.git
synced 2024-12-18 14:01:55 +04:00
Support bindings with the Super (Cmd/Win/Meta) modifier (#6592)
Terminals which support the enhanced keyboard protocol send events for keys pressed with the Super modifier (Windows/Linux key or the Command key). The only changes that are needed to support this in Helix are: * Mapping the modifier from crossterm's KeyModifiers to Helix's KeyModifiers. * Representing and parsing the modifier from the KeyEvent text representation. * Documenting the ability to remap it. When writing keybindings, use 'Meta-', 'Cmd-' or 'Win-' which are all synonymous. For example: [keys.normal] Cmd-s = ":write" will trigger for the Windows or Linux keys and the Command key plus 's'.
This commit is contained in:
parent
fc9968bd4b
commit
271c32f2e6
@ -72,8 +72,22 @@ # create a new minor mode bound to `+`
|
||||
|
||||
## Special keys and modifiers
|
||||
|
||||
Ctrl, Shift and Alt modifiers are encoded respectively with the prefixes
|
||||
`C-`, `S-` and `A-`. Special keys are encoded as follows:
|
||||
Ctrl, Shift and Alt modifiers are encoded respectively with the prefixes `C-`, `S-` and `A-`.
|
||||
|
||||
The [Super key](https://en.wikipedia.org/wiki/Super_key_(keyboard_button)) - the Windows/Linux
|
||||
key or the Command key on Mac keyboards - is also supported when using a terminal emulator that
|
||||
supports the [enhanced keyboard protocol](https://github.com/helix-editor/helix/wiki/Terminal-Support#enhanced-keyboard-protocol).
|
||||
The super key is encoded with prefixes `Meta-`, `Cmd-` or `Win-`. These are all synonyms for the
|
||||
super modifier - binding a key with a `Win-` modifier will mean it can be used with the
|
||||
Windows/Linux key or the Command key.
|
||||
|
||||
```toml
|
||||
[keys.normal]
|
||||
C-s = ":write" # Ctrl and 's' to write
|
||||
Cmd-s = ":write" # Cmd or Win or Meta and 's' to write
|
||||
```
|
||||
|
||||
Special keys are encoded as follows:
|
||||
|
||||
| Key name | Representation |
|
||||
| --- | --- |
|
||||
|
@ -162,7 +162,12 @@ pub(crate) mod keys {
|
||||
impl fmt::Display for KeyEvent {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.write_fmt(format_args!(
|
||||
"{}{}{}",
|
||||
"{}{}{}{}",
|
||||
if self.modifiers.contains(KeyModifiers::SUPER) {
|
||||
"Meta-"
|
||||
} else {
|
||||
""
|
||||
},
|
||||
if self.modifiers.contains(KeyModifiers::SHIFT) {
|
||||
"S-"
|
||||
} else {
|
||||
@ -312,6 +317,10 @@ fn width(&self) -> usize {
|
||||
if self.modifiers.contains(KeyModifiers::CONTROL) {
|
||||
width += 2;
|
||||
}
|
||||
if self.modifiers.contains(KeyModifiers::SUPER) {
|
||||
// "-Meta"
|
||||
width += 5;
|
||||
}
|
||||
width
|
||||
}
|
||||
|
||||
@ -413,6 +422,7 @@ fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
"S" => KeyModifiers::SHIFT,
|
||||
"A" => KeyModifiers::ALT,
|
||||
"C" => KeyModifiers::CONTROL,
|
||||
"Meta" | "Cmd" | "Win" => KeyModifiers::SUPER,
|
||||
_ => return Err(anyhow!("Invalid key modifier '{}-'", token)),
|
||||
};
|
||||
|
||||
@ -733,6 +743,28 @@ fn parsing_modified_keys() {
|
||||
modifiers: KeyModifiers::NONE
|
||||
}
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
str::parse::<KeyEvent>("Meta-c").unwrap(),
|
||||
KeyEvent {
|
||||
code: KeyCode::Char('c'),
|
||||
modifiers: KeyModifiers::SUPER
|
||||
}
|
||||
);
|
||||
assert_eq!(
|
||||
str::parse::<KeyEvent>("Win-s").unwrap(),
|
||||
KeyEvent {
|
||||
code: KeyCode::Char('s'),
|
||||
modifiers: KeyModifiers::SUPER
|
||||
}
|
||||
);
|
||||
assert_eq!(
|
||||
str::parse::<KeyEvent>("Cmd-d").unwrap(),
|
||||
KeyEvent {
|
||||
code: KeyCode::Char('d'),
|
||||
modifiers: KeyModifiers::SUPER
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -7,6 +7,7 @@ pub struct KeyModifiers: u8 {
|
||||
const SHIFT = 0b0000_0001;
|
||||
const CONTROL = 0b0000_0010;
|
||||
const ALT = 0b0000_0100;
|
||||
const SUPER = 0b0000_1000;
|
||||
const NONE = 0b0000_0000;
|
||||
}
|
||||
}
|
||||
@ -27,6 +28,9 @@ fn from(key_modifiers: KeyModifiers) -> Self {
|
||||
if key_modifiers.contains(KeyModifiers::ALT) {
|
||||
result.insert(CKeyModifiers::ALT);
|
||||
}
|
||||
if key_modifiers.contains(KeyModifiers::SUPER) {
|
||||
result.insert(CKeyModifiers::SUPER);
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
@ -48,6 +52,9 @@ fn from(val: crossterm::event::KeyModifiers) -> Self {
|
||||
if val.contains(CKeyModifiers::ALT) {
|
||||
result.insert(KeyModifiers::ALT);
|
||||
}
|
||||
if val.contains(CKeyModifiers::SUPER) {
|
||||
result.insert(KeyModifiers::SUPER);
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user