mirror of
https://github.com/helix-editor/helix.git
synced 2024-11-22 01:16:18 +04:00
Support bindings with the Super (Cmd/Win/Meta) modifier
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
fc97ecc3e3
commit
9c108b5486
@ -50,8 +50,22 @@ # create a new minor mode bound to `+`
|
|||||||
|
|
||||||
## Special keys and modifiers
|
## Special keys and modifiers
|
||||||
|
|
||||||
Ctrl, Shift and Alt modifiers are encoded respectively with the prefixes
|
Ctrl, Shift and Alt modifiers are encoded respectively with the prefixes `C-`, `S-` and `A-`.
|
||||||
`C-`, `S-` and `A-`. Special keys are encoded as follows:
|
|
||||||
|
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 |
|
| Key name | Representation |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
|
@ -162,7 +162,12 @@ pub(crate) mod keys {
|
|||||||
impl fmt::Display for KeyEvent {
|
impl fmt::Display for KeyEvent {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
f.write_fmt(format_args!(
|
f.write_fmt(format_args!(
|
||||||
"{}{}{}",
|
"{}{}{}{}",
|
||||||
|
if self.modifiers.contains(KeyModifiers::SUPER) {
|
||||||
|
"Meta-"
|
||||||
|
} else {
|
||||||
|
""
|
||||||
|
},
|
||||||
if self.modifiers.contains(KeyModifiers::SHIFT) {
|
if self.modifiers.contains(KeyModifiers::SHIFT) {
|
||||||
"S-"
|
"S-"
|
||||||
} else {
|
} else {
|
||||||
@ -312,6 +317,10 @@ fn width(&self) -> usize {
|
|||||||
if self.modifiers.contains(KeyModifiers::CONTROL) {
|
if self.modifiers.contains(KeyModifiers::CONTROL) {
|
||||||
width += 2;
|
width += 2;
|
||||||
}
|
}
|
||||||
|
if self.modifiers.contains(KeyModifiers::SUPER) {
|
||||||
|
// "-Meta"
|
||||||
|
width += 5;
|
||||||
|
}
|
||||||
width
|
width
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -396,6 +405,7 @@ fn from_str(s: &str) -> Result<Self, Self::Err> {
|
|||||||
"S" => KeyModifiers::SHIFT,
|
"S" => KeyModifiers::SHIFT,
|
||||||
"A" => KeyModifiers::ALT,
|
"A" => KeyModifiers::ALT,
|
||||||
"C" => KeyModifiers::CONTROL,
|
"C" => KeyModifiers::CONTROL,
|
||||||
|
"Meta" | "Cmd" | "Win" => KeyModifiers::SUPER,
|
||||||
_ => return Err(anyhow!("Invalid key modifier '{}-'", token)),
|
_ => return Err(anyhow!("Invalid key modifier '{}-'", token)),
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -709,6 +719,28 @@ fn parsing_modified_keys() {
|
|||||||
modifiers: KeyModifiers::NONE
|
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]
|
#[test]
|
||||||
|
@ -7,6 +7,7 @@ pub struct KeyModifiers: u8 {
|
|||||||
const SHIFT = 0b0000_0001;
|
const SHIFT = 0b0000_0001;
|
||||||
const CONTROL = 0b0000_0010;
|
const CONTROL = 0b0000_0010;
|
||||||
const ALT = 0b0000_0100;
|
const ALT = 0b0000_0100;
|
||||||
|
const SUPER = 0b0000_1000;
|
||||||
const NONE = 0b0000_0000;
|
const NONE = 0b0000_0000;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -27,6 +28,9 @@ fn from(key_modifiers: KeyModifiers) -> Self {
|
|||||||
if key_modifiers.contains(KeyModifiers::ALT) {
|
if key_modifiers.contains(KeyModifiers::ALT) {
|
||||||
result.insert(CKeyModifiers::ALT);
|
result.insert(CKeyModifiers::ALT);
|
||||||
}
|
}
|
||||||
|
if key_modifiers.contains(KeyModifiers::SUPER) {
|
||||||
|
result.insert(CKeyModifiers::SUPER);
|
||||||
|
}
|
||||||
|
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
@ -48,6 +52,9 @@ fn from(val: crossterm::event::KeyModifiers) -> Self {
|
|||||||
if val.contains(CKeyModifiers::ALT) {
|
if val.contains(CKeyModifiers::ALT) {
|
||||||
result.insert(KeyModifiers::ALT);
|
result.insert(KeyModifiers::ALT);
|
||||||
}
|
}
|
||||||
|
if val.contains(CKeyModifiers::SUPER) {
|
||||||
|
result.insert(KeyModifiers::SUPER);
|
||||||
|
}
|
||||||
|
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user