-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Remapping keys
For some background on how VS Code handles key remapping, please see this page.
TODO
Please see this page for details.
Custom remappings are defined on a per-mode basis.
"vim.insertModeKeyBindings"
/"vim.normalModeKeyBindings"
/"vim.visualModeKeyBindings"
/"vim.operatorPendingModeKeyBindings"
- Keybinding overrides to use for insert, normal, operatorPending and visual modes.
- Keybinding overrides can include
"before"
,"after"
,"commands"
, and"silent"
. - Bind
jj
to<Esc>
in insert mode:
"vim.insertModeKeyBindings": [
{
"before": ["j", "j"],
"after": ["<Esc>"]
}
]
- Bind
£
to goto previous whole word under cursor:
"vim.normalModeKeyBindings": [
{
"before": ["£"],
"after": ["#"]
}
]
- Bind
:
to show the command palette, and don't show the message on the status bar:
"vim.normalModeKeyBindings": [
{
"before": [":"],
"commands": [
"workbench.action.showCommands",
],
"silent": true
}
]
- Bind
<leader>m
to add a bookmark and<leader>b
to open the list of all bookmarks (using the Bookmarks extension):
"vim.normalModeKeyBindings": [
{
"before": ["<leader>", "m"],
"commands": [
"bookmarks.toggle"
]
},
{
"before": ["<leader>", "b"],
"commands": [
"bookmarks.list"
]
}
]
- Bind
ctrl+n
to turn off search highlighting and<leader>w
to save the current file:
"vim.normalModeKeyBindings": [
{
"before":["<C-n>"],
"commands": [
":nohl",
]
},
{
"before": ["leader", "w"],
"commands": [
"workbench.action.files.save",
]
}
]
- Bind
{
tow
in operator pending mode makesy{
andd{
work likeyw
anddw
respectively:
"vim.operatorPendingModeKeyBindings": [
{
"before": ["{"],
"after": ["w"]
}
]
- Bind
L
to$
andH
to^
in operator pending mode makesyL
anddH
work likey$
andd^
respectively:
"vim.operatorPendingModeKeyBindings": [
{
"before": ["L"],
"after": ["$"]
},
{
"before": ["H"],
"after": ["^"]
}
]
- Bind
>
and<
in visual mode to indent/outdent lines (repeatable):
"vim.visualModeKeyBindings": [
{
"before": [
">"
],
"commands": [
"editor.action.indentLines"
]
},
{
"before": [
"<"
],
"commands": [
"editor.action.outdentLines"
]
},
]
- Bind
<leader>vim
to clone this repository to the selected location:
"vim.visualModeKeyBindings": [
{
"before": [
"<leader>", "v", "i", "m"
],
"commands": [
{
"command": "git.clone",
"args": [ "https://github.com/VSCodeVim/Vim.git" ]
}
]
}
]
"vim.insertModeKeyBindingsNonRecursive"
/"normalModeKeyBindingsNonRecursive"
/"visualModeKeyBindingsNonRecursive"
/"operatorPendingModeKeyBindingsNonRecursive"
- Non-recursive keybinding overrides to use for insert, normal, and visual modes
-
Example: Exchange the meaning of two keys like
j
tok
andk
toj
to exchange the cursor up and down commands. Notice that if you attempted this binding normally, thej
would be replaced withk
and thek
would be replaced withj
, on and on forever. When this happens 'maxmapdepth' times (default 1000) the error message 'E223 Recursive Mapping' will be thrown. Stop this recursive expansion using the NonRecursive variation of the keybindings:
"vim.normalModeKeyBindingsNonRecursive": [
{
"before": ["j"],
"after": ["k"]
},
{
"before": ["k"],
"after": ["j"]
}
]
- Bind
(
to 'i(' in operator pending mode makes 'y(' and 'c(' work like 'yi(' and 'ci(' respectively:
"vim.operatorPendingModeKeyBindingsNonRecursive": [
{
"before": ["("],
"after": ["i("]
}
]
- Bind
p
in visual mode to paste without overriding the current register:
"vim.visualModeKeyBindingsNonRecursive": [
{
"before": [
"p",
],
"after": [
"p",
"g",
"v",
"y"
]
}
],
-
Adjust the extension's logging level to 'debug' and open the Output window:
- Run
Developer: Set Log Level
from the command palette. - Select
Vim
, thenDebug
- Run
Developer: Reload window
- In the bottom panel, open the
Output
tab and selectVim
from the dropdown selection.
- Run
-
Are your configurations correct?
As each remapped configuration is loaded, it is logged to the Vim Output panel. Do you see any errors?
debug: Remapper: normalModeKeyBindingsNonRecursive. before=0. after=^. debug: Remapper: insertModeKeyBindings. before=j,j. after=<Esc>. error: Remapper: insertModeKeyBindings. Invalid configuration. Missing 'after' key or 'commands'. before=j,k.
Misconfigured configurations are ignored.
-
Does the extension handle the keys you are trying to remap?
VSCodeVim explicitly instructs VS Code which key events we care about through the package.json. If the key you are trying to remap is a key in which vim/vscodevim generally does not handle, then it's most likely that this extension does not receive those key events from VS Code. In the Vim Output panel, you should see:
debug: ModeHandler: handling key=A. debug: ModeHandler: handling key=l. debug: ModeHandler: handling key=<BS>. debug: ModeHandler: handling key=<C-a>.
As you press the key that you are trying to remap, do you see it outputted here? If not, it means we don't subscribe to those key events. It is still possible to remap those keys by using VSCode's keybindings.json (see next section: Remapping more complex key combinations).
It is highly recommended to remap keys using vim commands like "vim.normalModeKeyBindings"
(see here). But sometimes the usual remapping commands are not enough as they do not support every key combinations possible (for example Alt+key
or Ctrl+Shift+key
). In this case it is possible to create new keybindings inside keybindings.json. To do so: open up keybindings.json in VSCode using CTRL+SHIFT+P
and select Open keyboard shortcuts (JSON)
.
You can then add a new entry to the keybindings like so:
{
"key": "YOUR_KEY_COMBINATION",
"command": "vim.remap",
"when": "inputFocus && vim.mode == 'VIM_MODE_YOU_WANT_TO_REBIND'",
"args": {
"after": ["YOUR_VIM_ACTION"]
}
}
For example, to rebind ctrl+shift+y
to VSCodeVim's yy
(yank line) in normal mode, add this to your keybindings.json:
{
"key": "ctrl+shift+y",
"command": "vim.remap",
"when": "inputFocus && vim.mode == 'Normal'",
"args": {
"after": ["y", "y"]
}
}
If keybindings.json is empty the first time you open it, make sure to add opening [
and closing ]
square brackets to the file as the keybindings should be inside a JSON Array.