Allow binding of CTRL+ALT+<c>, CTRL+ALT+SHIFT+<c>, and <c> (#580)

Combinations like `Ctrl+Alt+a` could not be mapped previously, since
some non-us keyboard layouts use those combinations for sending
characters like `@`.

Now, first check if there a binding was defined using that combination,
else interpret as raw characters. This should not affect those special
keyboard layouts, since they would be sending `Ctrl+Alt+<special char>`,
rather than what would be on the US layout.

E.g.
- Map `Ctrl+Alt+a` to an action
- `Ctrl+Alt+a` on (some) german keyboards would send `@`
- A german layout pressing those keys would send a key combination of `Ctrl+Alt+@`,
  so they are unaffected by this change (they would have to specifically
  map `Ctrl+Alt+@`)
- For any layout actually sending `Ctrl+Alt+a`, they get the mapped action

This also allows the user to bind a keybinding without modifiers.

This affects emacs mode and vi insert mode (vi normal mode
already allows such keybindings).
This commit is contained in:
TrMen 2023-05-05 12:38:28 +02:00 committed by GitHub
parent 97f754425a
commit 7f54706cab
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 42 additions and 34 deletions

View File

@ -127,24 +127,28 @@ impl EditMode for Emacs {
_ => c.to_ascii_lowercase(),
};
if modifier == KeyModifiers::NONE
|| modifier == KeyModifiers::SHIFT
|| modifier == KeyModifiers::CONTROL | KeyModifiers::ALT
|| modifier
== KeyModifiers::CONTROL | KeyModifiers::ALT | KeyModifiers::SHIFT
{
ReedlineEvent::Edit(vec![EditCommand::InsertChar(
if modifier == KeyModifiers::SHIFT {
c.to_ascii_uppercase()
self.keybindings
.find_binding(modifier, KeyCode::Char(c))
.unwrap_or_else(|| {
if modifier == KeyModifiers::NONE
|| modifier == KeyModifiers::SHIFT
|| modifier == KeyModifiers::CONTROL | KeyModifiers::ALT
|| modifier
== KeyModifiers::CONTROL
| KeyModifiers::ALT
| KeyModifiers::SHIFT
{
ReedlineEvent::Edit(vec![EditCommand::InsertChar(
if modifier == KeyModifiers::SHIFT {
c.to_ascii_uppercase()
} else {
c
},
)])
} else {
c
},
)])
} else {
self.keybindings
.find_binding(modifier, KeyCode::Char(c))
.unwrap_or(ReedlineEvent::None)
}
ReedlineEvent::None
}
})
}
_ => self
.keybindings

View File

@ -111,24 +111,28 @@ impl EditMode for Vi {
_ => c.to_ascii_lowercase(),
};
if modifier == KeyModifiers::NONE
|| modifier == KeyModifiers::SHIFT
|| modifier == KeyModifiers::CONTROL | KeyModifiers::ALT
|| modifier
== KeyModifiers::CONTROL | KeyModifiers::ALT | KeyModifiers::SHIFT
{
ReedlineEvent::Edit(vec![EditCommand::InsertChar(
if modifier == KeyModifiers::SHIFT {
c.to_ascii_uppercase()
self.insert_keybindings
.find_binding(modifier, KeyCode::Char(c))
.unwrap_or_else(|| {
if modifier == KeyModifiers::NONE
|| modifier == KeyModifiers::SHIFT
|| modifier == KeyModifiers::CONTROL | KeyModifiers::ALT
|| modifier
== KeyModifiers::CONTROL
| KeyModifiers::ALT
| KeyModifiers::SHIFT
{
ReedlineEvent::Edit(vec![EditCommand::InsertChar(
if modifier == KeyModifiers::SHIFT {
c.to_ascii_uppercase()
} else {
c
},
)])
} else {
c
},
)])
} else {
self.insert_keybindings
.find_binding(modifier, KeyCode::Char(c))
.unwrap_or(ReedlineEvent::None)
}
ReedlineEvent::None
}
})
}
(_, KeyModifiers::NONE, KeyCode::Esc) => {
self.cache.clear();