oni
oni copied to clipboard
Is there a way to map Command to Control?
It'd be great if there was a way to map Command to Control. This would be outside of the Neovim instance, in Electron. Not sure if Electron supports it. Neovim would see it as if we pressed Control, and would not know about this setting.
In iTerm, there's an option to map Command to Control, and Bash will see Control when we're actually pressing Command.
Is this possible?
In macOS, I have Caplock Key mapps to Command, which works great with iTerm (as Control). Would be great to have this in Oni!
We actually have an API (internal) to support this - we can register KeyResolvers
which are a function that take the KeyboardEvent
and return a string
. They live here today:
https://github.com/onivim/oni/blob/115196c8958521abfd1fcf8e885cc28e03560b2b/browser/src/Input/Keyboard/Resolvers.ts#L11
They take KeyboardEvent
s along with the results of previous resolutions, and output a vim-style string, like <M-v>
.
I could see implementing this by adding additional resolvers, along with a config options. For example, we could have a configuration setting input.mapCommandToControl
, and a resolver like mapCommandToControl
, which would be pass-through if that setting is false
, but would otherwise map stuff like <M-v>
to <C-v>
. We could implement a similar resolver/configuration setting for caps-lock too.
If I can get Oni ti run manually, I'd like to give this a shot. Let me try to get up an running...
Alright, got it running (but it's still not ideal). Any pointers on how I might implement this? Where would I start implementing it? In the user config file on activate?
The user config would be a fine place to try this out, but I could see bringing this in as core functionality too (gated by a config, like tmux
).
In theory, something like this should work in config.js
:
oni.input.resolvers.addResolver((evt, key) => {
console.log(key)
switch (key) {
case "j":
return "k"
case "k":
return "j"
default:
return key
}
})
(Of course, you'd want to have actually logic to map control to meta instead of that simplistic switch case 😄 ). Hope that gives an idea. Otherwise, if you wanted to implement it with our other built-in mappings, you can check out the resolvers we include: https://github.com/onivim/oni/blob/115196c8958521abfd1fcf8e885cc28e03560b2b/browser/src/Input/Keyboard/Resolvers.ts#L11
About to try when I get home. By the way, I'm interested in command, not meta, swapping it with control. Or, is meta and command the same?
Are resolvers recursive, or non-recursive? Or both and configurable?
I don't have an actual Apple keyboard to test, but I believe the command
key on Apple maps to meta
.
There isn't a concept of recursion with the input resolvers, as they are run prior to any mappings / bindings being involved (which is where recursion would matter). They're really for taking keyboard events and mapping them to the Vim keyboard input string. They are chained and order does matter (addResolver
adds to the end of the list and gives priority).
Hope that helps - there's a bit more info here too: https://github.com/onivim/oni/wiki/Input-Management-Architecture#resolution
I've been looking into this, and it doesn't feel right to have to define bindings manually in the config.js
.
I've done it that way:
const CUSTOM_KEYBINDINGS = {
'<a-bs>': '<c-w>',
'<m-bs>': '<c-u>',
};
const activate = oni => {
oni.input.resolvers.addResolver((event, key) => {
return CUSTOM_KEYBINDINGS[key] || key;
});
}
IMO, this is useful enough to justify adding a config key and handling this natively (if it isn't already the case). Plus, I don't think it's the user business to create a resolver for such a simple usecase
I can imagine something like that:
// config.js
module.exports = {
"input.keybindings": {
"<a-bs>": "<c-w>",
"<m-bs>": "<c-u>",
},
};
It is better to have command mapped to <D-
, like in vimR.
I suggest using karabiner elements
for Mac.