I'm a VS Code user that uses the vscodevim extension. When also using GitHub Copilot Next Edit Suggestion (NES) feature, it requires the usage of Tab and ESC which conflict with VIM.
How can a remap the NES keys, as Tab in Normal mode does not register and ESC in Insert mode exits Insert mode?
Take a look this github discussion and suggestion: https://github.com/VSCodeVim/Vim/issues/9459#issuecomment-2648156285
The code is below. The key points how it works:
Carefully layering rules for the Escape
key using when
clauses. VS Code evaluates these rules from bottom to top in your keybindings.json
, but the most specific matching when
clause usually takes precedence. The -
prefix on a command removes or disables a default or previously defined keybinding for that specific when
context.
1st Rule: It disables (-
) the default behavior of Escape
provided by the VSCodeVim extension (extension.vim_escape
) whenever the editor has focus, Vim mode is active, and you're not in the debug console. This effectively says, "Don't let Vim handle Escape by default; we're going to define custom rules."
2nd Rule: This rule re-enables the standard Vim Escape command (extension.vim_escape
) but only under very specific conditions. * Conditions: It triggers only when Vim is active, and you're in Insert mode (or not in a notebook editor), and importantly, none of the potentially conflicting UI elements are visible
3rd Rule: This rule specifically targets the Copilot inline suggestion conflict. It triggers only when Vim is in Insert mode AND an inline suggestion is visible (inlineEditIsVisible
).
4th Rule: Similar to the previous rule, but targets the standard suggestion widget. Triggers only when Vim is in Insert mode AND the suggestion widget is visible (suggestWidgetVisible
)
5th Rule: This disables (-
) the default VS Code behavior where Escape
simply closes the suggestion widget (hideSuggestWidget
) when it's visible and you have text input focus. This is done because rules #4 and #6 provide more specific, Vim-aware handling.
6th Rule: This re-enables the hideSuggestWidget
command for Escape
, but only when the suggestion widget is visible AND Vim mode is NOT active (!vim.active
).
// Place your key bindings in this file to override the defaults
[
{
"key": "escape",
"command": "-extension.vim_escape",
"when": "editorTextFocus && vim.active && !inDebugRepl"
},
{
"key": "escape",
"command": "extension.vim_escape",
"when": "editorTextFocus && vim.active && !inDebugRepl && !testing.isPeekVisible && !testing.isInPeek && (vim.mode == 'Insert' || !notebookEditorFocused) && !inlineEditIsVisible && !suggestWidgetVisible && !findWidgetVisible && !dirtyDiffVisible"
},
{
"key": "escape",
"command": "runCommands",
"when": "vim.mode == 'Insert' && inlineEditIsVisible",
"args": {
"commands": [
"editor.action.inlineSuggest.hide",
"extension.vim_escape"
]
}
},
{
"key": "escape",
"command": "runCommands",
"when": "vim.mode == 'Insert' && suggestWidgetVisible",
"args": {
"commands": [
"hideSuggestWidget",
"extension.vim_escape"
]
}
},
{
"key": "escape",
"command": "-hideSuggestWidget",
"when": "suggestWidgetVisible && textInputFocus"
},
{
"key": "escape",
"command": "hideSuggestWidget",
"when": "suggestWidgetVisible && textInputFocus && !vim.active"
},
{
// Remove VSCodeVim's handling of tab to enable default handling of tab
// e.g. for inline suggestions.
"key": "tab",
"command": "-extension.vim_tab",
},
]