Last active
January 9, 2026 07:53
-
Star
(142)
You must be signed in to star a gist -
Fork
(25)
You must be signed in to fork a gist
-
-
Save nikolovlazar/1174876ab2769c52ac9fc1534c557d70 to your computer and use it in GitHub Desktop.
VSCode key bindings to navigate like Neovim
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| [ | |
| // Navigation | |
| { | |
| "key": "ctrl-h", | |
| "command": "workbench.action.navigateLeft" | |
| }, | |
| { | |
| "key": "ctrl-l", | |
| "command": "workbench.action.navigateRight" | |
| }, | |
| { | |
| "key": "ctrl-k", | |
| "command": "workbench.action.navigateUp" | |
| }, | |
| { | |
| "key": "ctrl-j", | |
| "command": "workbench.action.navigateDown" | |
| }, | |
| { | |
| "key": "space ,", | |
| "command": "workbench.action.showAllEditors", | |
| "when": "vim.mode == 'Normal' && (editorTextFocus || !inputFocus)" | |
| }, | |
| { | |
| "key": "space e", | |
| "command": "runCommands", | |
| "args": { | |
| "commands": [ | |
| "workbench.action.toggleSidebarVisibility", | |
| "workbench.files.action.focusFilesExplorer" | |
| ] | |
| }, | |
| "when": "vim.mode == 'Normal' && (editorTextFocus || !inputFocus) && !sideBarFocus" | |
| }, | |
| { | |
| "key": "space e", | |
| "command": "runCommands", | |
| "args": { | |
| "commands": [ | |
| "workbench.action.toggleSidebarVisibility", | |
| "workbench.action.focusActiveEditorGroup" | |
| ] | |
| }, | |
| "when": "sideBarFocus && !inputFocus" | |
| }, | |
| { | |
| "key": "space e", | |
| "when": "vim.mode == 'Normal' && editorTextFocus && foldersViewVisible", | |
| "command": "workbench.action.toggleSidebarVisibility" | |
| }, | |
| { | |
| "key": "s h", | |
| "command": "workbench.action.splitEditor", | |
| "when": "vim.mode == 'Normal' && (editorTextFocus || !inputFocus)" | |
| }, | |
| { | |
| "key": "s v", | |
| "command": "workbench.action.splitEditorDown", | |
| "when": "vim.mode == 'Normal' && (editorTextFocus || !inputFocus)" | |
| }, | |
| // Coding | |
| { | |
| "key": "space c a", | |
| "command": "editor.action.codeAction", | |
| "when": "vim.mode == 'Normal' && editorTextFocus" | |
| }, | |
| { | |
| "key": "shift-k", | |
| "command": "editor.action.moveLinesUpAction", | |
| "when": "vim.mode == 'VisualLine' && editorTextFocus" | |
| }, | |
| { | |
| "key": "shift-j", | |
| "command": "editor.action.moveLinesDownAction", | |
| "when": "vim.mode == 'VisualLine' && editorTextFocus" | |
| }, | |
| { | |
| "key": "shift-k", | |
| "command": "editor.action.showHover", | |
| "when": "vim.mode == 'Normal' && editorTextFocus" | |
| }, | |
| { | |
| "key": "space c r", | |
| "command": "editor.action.rename", | |
| "when": "vim.mode == 'Normal' && editorTextFocus" | |
| }, | |
| { | |
| "key": "space c s", | |
| "command": "workbench.action.gotoSymbol", | |
| "when": "vim.mode == 'Normal' && editorTextFocus" | |
| }, | |
| { | |
| "key": "space b d", | |
| "command": "workbench.action.closeActiveEditor", | |
| "when": "(vim.mode == 'Normal' && editorTextFocus) || !inputFocus" | |
| }, | |
| { | |
| "key": "space b o", | |
| "command": "workbench.action.closeOtherEditors", | |
| "when": "(vim.mode == 'Normal' && editorTextFocus) || !inputFocus" | |
| }, | |
| { | |
| "key": "space space", | |
| "command": "workbench.action.quickOpen", | |
| "when": "vim.mode == 'Normal' && (editorTextFocus || !inputFocus)" | |
| }, | |
| { | |
| "key": "space g d", | |
| "command": "editor.action.revealDefinition", | |
| "when": "vim.mode == 'Normal' && editorTextFocus" | |
| }, | |
| { | |
| "key": "space g r", | |
| "command": "editor.action.goToReferences", | |
| "when": "vim.mode == 'Normal' && editorTextFocus" | |
| }, | |
| { | |
| "key": "space g i", | |
| "command": "editor.action.goToImplementation", | |
| "when": "vim.mode == 'Normal' && editorTextFocus" | |
| }, | |
| { | |
| "key": "space s g", | |
| "command": "workbench.action.findInFiles", | |
| "when": "vim.mode == 'Normal' && (editorTextFocus || !inputFocus)" | |
| }, | |
| { | |
| "key": "space g g", | |
| "command": "runCommands", | |
| "when": "vim.mode == 'Normal' && (editorTextFocus || !inputFocus)", | |
| "args": { | |
| "commands": ["workbench.view.scm", "workbench.scm.focus"] | |
| } | |
| }, | |
| { | |
| "key": "ctrl-n", | |
| "command": "editor.action.addSelectionToNextFindMatch", | |
| "when": "(vim.mode == 'Normal' || vim.mode == 'Visual') && (editorTextFocus || !inputFocus)" | |
| }, | |
| // File Explorer | |
| { | |
| "key": "r", | |
| "command": "renameFile", | |
| "when": "filesExplorerFocus && foldersViewVisible && !explorerResourceIsRoot && !explorerResourceReadonly && !inputFocus" | |
| }, | |
| { | |
| "key": "c", | |
| "command": "filesExplorer.copy", | |
| "when": "filesExplorerFocus && foldersViewVisible && !explorerResourceIsRoot && !explorerResourceReadonly && !inputFocus" | |
| }, | |
| { | |
| "key": "p", | |
| "command": "filesExplorer.paste", | |
| "when": "filesExplorerFocus && foldersViewVisible && !explorerResourceIsRoot && !explorerResourceReadonly && !inputFocus" | |
| }, | |
| { | |
| "key": "x", | |
| "command": "filesExplorer.cut", | |
| "when": "filesExplorerFocus && foldersViewVisible && !explorerResourceIsRoot && !explorerResourceReadonly && !inputFocus" | |
| }, | |
| { | |
| "key": "d", | |
| "command": "deleteFile", | |
| "when": "filesExplorerFocus && foldersViewVisible && !explorerResourceIsRoot && !explorerResourceReadonly && !inputFocus" | |
| }, | |
| { | |
| "key": "a", | |
| "command": "explorer.newFile", | |
| "when": "filesExplorerFocus && foldersViewVisible && !explorerResourceIsRoot && !explorerResourceReadonly && !inputFocus" | |
| }, | |
| { | |
| "key": "s", | |
| "command": "explorer.openToSide", | |
| "when": "filesExplorerFocus && foldersViewVisible && !explorerResourceIsRoot && !explorerResourceReadonly && !inputFocus" | |
| }, | |
| { | |
| "key": "shift-s", | |
| "command": "runCommands", | |
| "when": "filesExplorerFocus && foldersViewVisible && !explorerResourceIsRoot && !explorerResourceReadonly && !inputFocus", | |
| "args": { | |
| "commands": [ | |
| "workbench.action.splitEditorDown", | |
| "explorer.openAndPassFocus", | |
| "workbench.action.closeOtherEditors" | |
| ] | |
| } | |
| }, | |
| { | |
| "key": "enter", | |
| "command": "explorer.openAndPassFocus", | |
| "when": "filesExplorerFocus && foldersViewVisible && !explorerResourceIsRoot && !explorerResourceIsFolder && !inputFocus" | |
| }, | |
| { | |
| "key": "enter", | |
| "command": "list.toggleExpand", | |
| "when": "filesExplorerFocus && foldersViewVisible && !explorerResourceIsRoot && explorerResourceIsFolder && !inputFocus" | |
| }, | |
| // Debug | |
| { | |
| "key": "space d a", | |
| "command": "workbench.action.debug.selectandstart", | |
| "when": "vim.mode == 'Normal' && (editorTextFocus || !inputFocus) && debuggersAvailable" | |
| }, | |
| { | |
| "key": "space d t", | |
| "command": "workbench.action.debug.stop", | |
| "when": "vim.mode == 'Normal' && editorTextFocus && inDebugMode && !focusedSessionIsAttached" | |
| }, | |
| { | |
| "key": "space d o", | |
| "command": "workbench.action.debug.stepOver", | |
| "when": "vim.mode == 'Normal' && (editorTextFocus || !inputFocus) && inDebugMode && debugState == 'stopped'" | |
| }, | |
| { | |
| "key": "space d b", | |
| "command": "editor.debug.action.toggleBreakpoint", | |
| "when": "vim.mode == 'Normal' && editorTextFocus" | |
| }, | |
| { | |
| "key": "space d e", | |
| "command": "editor.debug.action.showDebugHover", | |
| "when": "vim.mode == 'Normal' && editorTextFocus && inDebugMode && debugState == 'stopped'" | |
| }, | |
| { | |
| "key": "space d c", | |
| "command": "workbench.action.debug.continue", | |
| "when": "vim.mode == 'Normal' && (editorTextFocus || !inputFocus) && inDebugMode && debugState == 'stopped'" | |
| } | |
| ] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
The reason why
ggdoes not work to go to the top of the file is that VS Code seems to handle the keybindings.json before vim.normalModeKeyBindings (settings.json).I.e. if you have a keybinding sequence that starts with
gyou break all VIM sequences that start withg. Similarily a command likect(change to next whitespace) also (currently) does not work as VS Code knows there is a keybinding sequence that starts with a space, starts listening and the space never reaches VIM.This is the big drawback of configuring it the keybindgs.json way!
I fixed this by moving all commands that start with a
gover to the settings.json and only having sequences that start with space in the keybindings.json. That's still not perfect (cidoes not register, keybings split over two files, etc.) but works for me. Here is the relevant part of the settings.json if anyone wants to use it: