← back

VSCode keybindings I can't live without

Before using VSCode I used to be a VIM user for more than 10 years. One of the things VIM does to you is after learning it properly, any other editor feels like driving a car with the parking brake applied.

So the natural step for me after getting VSCode up and running was to find proper VIM emulation layer. Thankfully I found decent one.

After a few days of using VSCode I started to notice more and more small things that a seasoned VIM user would consider muscle memory but were missing in VSCode.

The rest of this post is a summary of issues I managed to find and fix by either keybinding or a custom extension. Enjoy and I hope you’ll find something useful!

Panel

With the following keybindings I can simply press cmd + j to switch focus between editor group and panel. cmd + shift + j on the other hand toggles the panel visibility. There’s a lot more!

jsonc
[
// remove keybinding for native console (annoyed me too much)
{
"key": "shift+cmd+c",
"command": "-workbench.action.terminal.openNativeConsole",
"when": "!terminalFocus"
},
// switch focus from editor to panel
{
"key": "cmd+j",
"command": "workbench.action.focusPanel",
"when": "!panelFocus"
},
// switch focus from panel to editor
{
"key": "cmd+j",
"command": "workbench.action.focusActiveEditorGroup",
"when": "panelFocus"
},
// switch focus from maximized panel to editor (closes panel)
{
"key": "cmd+j",
"command": "workbench.action.closePanel",
"when": "panelVisible && panelMaximized"
},
// toggle panel visibility
{
"key": "cmd+shift+j",
"command": "workbench.action.togglePanel"
},
// maximize panel
{
"key": "cmd+w m",
"command": "workbench.action.toggleMaximizedPanel",
"when": "panelFocus"
},
// move panel to bottom/right
{
"key": "cmd+w shift+l",
"command": "extension.multiCommand.execute",
"args": {
"sequence": [
"workbench.action.positionPanelRight",
"workbench.action.focusPanel"
]
},
"when": "panelFocus"
},
{
"key": "cmd+w shift+j",
"command": "extension.multiCommand.execute",
"args": {
"sequence": [
"workbench.action.positionPanelBottom",
"workbench.action.focusPanel"
]
},
"when": "panelFocus"
},
// switch to next panel view (you need to be focused on the panel)
{
"key": "cmd+shift+]",
"command": "workbench.action.nextPanelView",
"when": "panelFocus"
},
// switch to previous panel view (you need to be focused on the panel)
{
"key": "cmd+shift+[",
"command": "workbench.action.previousPanelView",
"when": "panelFocus"
}
]
jsonc
[
// remove keybinding for native console (annoyed me too much)
{
"key": "shift+cmd+c",
"command": "-workbench.action.terminal.openNativeConsole",
"when": "!terminalFocus"
},
// switch focus from editor to panel
{
"key": "cmd+j",
"command": "workbench.action.focusPanel",
"when": "!panelFocus"
},
// switch focus from panel to editor
{
"key": "cmd+j",
"command": "workbench.action.focusActiveEditorGroup",
"when": "panelFocus"
},
// switch focus from maximized panel to editor (closes panel)
{
"key": "cmd+j",
"command": "workbench.action.closePanel",
"when": "panelVisible && panelMaximized"
},
// toggle panel visibility
{
"key": "cmd+shift+j",
"command": "workbench.action.togglePanel"
},
// maximize panel
{
"key": "cmd+w m",
"command": "workbench.action.toggleMaximizedPanel",
"when": "panelFocus"
},
// move panel to bottom/right
{
"key": "cmd+w shift+l",
"command": "extension.multiCommand.execute",
"args": {
"sequence": [
"workbench.action.positionPanelRight",
"workbench.action.focusPanel"
]
},
"when": "panelFocus"
},
{
"key": "cmd+w shift+j",
"command": "extension.multiCommand.execute",
"args": {
"sequence": [
"workbench.action.positionPanelBottom",
"workbench.action.focusPanel"
]
},
"when": "panelFocus"
},
// switch to next panel view (you need to be focused on the panel)
{
"key": "cmd+shift+]",
"command": "workbench.action.nextPanelView",
"when": "panelFocus"
},
// switch to previous panel view (you need to be focused on the panel)
{
"key": "cmd+shift+[",
"command": "workbench.action.previousPanelView",
"when": "panelFocus"
}
]

Terminal inside the panel

Once you have the panel opened and the focus is on the “Terminal” use the following keybindings to manage terminal sessions:

jsonc
[
// switch between terminals
{
"key": "cmd+]",
"command": "workbench.action.terminal.focusNext",
"when": "terminalFocus && terminalHasBeenCreated && !terminalEditorFocus || terminalFocus && terminalProcessSupported && !terminalEditorFocus"
},
{
"key": "shift+cmd+]",
"command": "-workbench.action.terminal.focusNext",
"when": "terminalFocus && terminalHasBeenCreated && !terminalEditorFocus || terminalFocus && terminalProcessSupported && !terminalEditorFocus"
},
{
"key": "cmd+[",
"command": "workbench.action.terminal.focusPrevious",
"when": "terminalFocus && terminalHasBeenCreated && !terminalEditorFocus || terminalFocus && terminalProcessSupported && !terminalEditorFocus"
},
{
"key": "shift+cmd+[",
"command": "-workbench.action.terminal.focusPrevious",
"when": "terminalFocus && terminalHasBeenCreated && !terminalEditorFocus || terminalFocus && terminalProcessSupported && !terminalEditorFocus"
},
// create new terminal window
{
"key": "cmd+n",
"command": "workbench.action.terminal.new",
"when": "terminalFocus && terminalProcessSupported"
},
{
"key": "ctrl+shift+`",
"command": "-workbench.action.terminal.new",
"when": "terminalProcessSupported || terminalWebExtensionContributedProfile"
},
// kill active terminal
{
"key": "cmd+w cmd+w",
"command": "workbench.action.terminal.killEditor",
"when": "terminalEditorFocus && terminalFocus && terminalHasBeenCreated && resourceScheme == 'vscode-terminal' || terminalEditorFocus && terminalFocus && terminalProcessSupported && resourceScheme == 'vscode-terminal'"
},
{
"key": "cmd+w cmd+w",
"command": "workbench.action.terminal.kill",
"when": "terminalFocus && terminalHasBeenCreated && !terminalEditorFocus || terminalFocus && terminalProcessSupported && !terminalEditorFocus"
},
// focus next/prev terminal pane
{
"key": "cmd+w cmd+l",
"command": "workbench.action.terminal.focusNextPane",
"when": "terminalFocus && terminalHasBeenCreated || terminalFocus && terminalProcessSupported"
},
{
"key": "cmd+w cmd+j",
"command": "workbench.action.terminal.focusNextPane",
"when": "terminalFocus && terminalHasBeenCreated || terminalFocus && terminalProcessSupported"
},
{
"key": "cmd+w cmd+h",
"command": "workbench.action.terminal.focusPreviousPane",
"when": "terminalFocus && terminalHasBeenCreated || terminalFocus && terminalProcessSupported"
},
{
"key": "cmd+w cmd+k",
"command": "workbench.action.terminal.focusPreviousPane",
"when": "terminalFocus && terminalHasBeenCreated || terminalFocus && terminalProcessSupported"
},
// scroll to next/prev command
{
"key": "cmd+k cmd+j",
"command": "workbench.action.terminal.scrollToNextCommand",
"when": "terminalFocus && terminalHasBeenCreated && !accessibilityModeEnabled || terminalFocus && terminalProcessSupported && !accessibilityModeEnabled"
},
{
"key": "cmd+k cmd+k",
"command": "workbench.action.terminal.scrollToPreviousCommand",
"when": "terminalFocus && terminalHasBeenCreated && !accessibilityModeEnabled || terminalFocus && terminalProcessSupported && !accessibilityModeEnabled"
}
]
jsonc
[
// switch between terminals
{
"key": "cmd+]",
"command": "workbench.action.terminal.focusNext",
"when": "terminalFocus && terminalHasBeenCreated && !terminalEditorFocus || terminalFocus && terminalProcessSupported && !terminalEditorFocus"
},
{
"key": "shift+cmd+]",
"command": "-workbench.action.terminal.focusNext",
"when": "terminalFocus && terminalHasBeenCreated && !terminalEditorFocus || terminalFocus && terminalProcessSupported && !terminalEditorFocus"
},
{
"key": "cmd+[",
"command": "workbench.action.terminal.focusPrevious",
"when": "terminalFocus && terminalHasBeenCreated && !terminalEditorFocus || terminalFocus && terminalProcessSupported && !terminalEditorFocus"
},
{
"key": "shift+cmd+[",
"command": "-workbench.action.terminal.focusPrevious",
"when": "terminalFocus && terminalHasBeenCreated && !terminalEditorFocus || terminalFocus && terminalProcessSupported && !terminalEditorFocus"
},
// create new terminal window
{
"key": "cmd+n",
"command": "workbench.action.terminal.new",
"when": "terminalFocus && terminalProcessSupported"
},
{
"key": "ctrl+shift+`",
"command": "-workbench.action.terminal.new",
"when": "terminalProcessSupported || terminalWebExtensionContributedProfile"
},
// kill active terminal
{
"key": "cmd+w cmd+w",
"command": "workbench.action.terminal.killEditor",
"when": "terminalEditorFocus && terminalFocus && terminalHasBeenCreated && resourceScheme == 'vscode-terminal' || terminalEditorFocus && terminalFocus && terminalProcessSupported && resourceScheme == 'vscode-terminal'"
},
{
"key": "cmd+w cmd+w",
"command": "workbench.action.terminal.kill",
"when": "terminalFocus && terminalHasBeenCreated && !terminalEditorFocus || terminalFocus && terminalProcessSupported && !terminalEditorFocus"
},
// focus next/prev terminal pane
{
"key": "cmd+w cmd+l",
"command": "workbench.action.terminal.focusNextPane",
"when": "terminalFocus && terminalHasBeenCreated || terminalFocus && terminalProcessSupported"
},
{
"key": "cmd+w cmd+j",
"command": "workbench.action.terminal.focusNextPane",
"when": "terminalFocus && terminalHasBeenCreated || terminalFocus && terminalProcessSupported"
},
{
"key": "cmd+w cmd+h",
"command": "workbench.action.terminal.focusPreviousPane",
"when": "terminalFocus && terminalHasBeenCreated || terminalFocus && terminalProcessSupported"
},
{
"key": "cmd+w cmd+k",
"command": "workbench.action.terminal.focusPreviousPane",
"when": "terminalFocus && terminalHasBeenCreated || terminalFocus && terminalProcessSupported"
},
// scroll to next/prev command
{
"key": "cmd+k cmd+j",
"command": "workbench.action.terminal.scrollToNextCommand",
"when": "terminalFocus && terminalHasBeenCreated && !accessibilityModeEnabled || terminalFocus && terminalProcessSupported && !accessibilityModeEnabled"
},
{
"key": "cmd+k cmd+k",
"command": "workbench.action.terminal.scrollToPreviousCommand",
"when": "terminalFocus && terminalHasBeenCreated && !accessibilityModeEnabled || terminalFocus && terminalProcessSupported && !accessibilityModeEnabled"
}
]

Unimpaired

The following keybindings are inspired by a great VIM plugin, unimpaired.vim and I use them a lot!

jsonc
[
// search results
{
"key": "[ f",
"command": "search.action.focusPreviousSearchResult",
"when": "editorFocus && vim.mode == 'Normal' && !terminalFocus"
},
{
"key": "] f",
"command": "search.action.focusNextSearchResult",
"when": "editorFocus && vim.mode == 'Normal' && !terminalFocus"
},
// problems/warnings
{
"key": "[ e",
"command": "editor.action.marker.prev",
"when": "editorFocus && vim.mode == 'Normal' && !terminalFocus"
},
{
"key": "] e",
"command": "editor.action.marker.next",
"when": "editorFocus && vim.mode == 'Normal' && !terminalFocus"
},
// scm changes
{
"key": "[ d",
"command": "workbench.action.editor.previousChange",
"when": "editorFocus && vim.mode == 'Normal' && !terminalFocus"
},
{
"key": "] d",
"command": "workbench.action.editor.nextChange",
"when": "editorFocus && vim.mode == 'Normal' && !terminalFocus"
},
{
"key": "[ d",
"command": "workbench.action.compareEditor.previousChange",
"when": "textCompareEditorVisible && vim.mode == 'Normal' && !terminalFocus"
},
{
"key": "] d",
"command": "workbench.action.compareEditor.nextChange",
"when": "textCompareEditorVisible && vim.mode == 'Normal' && !terminalFocus"
},
// selections under cursor
{
"key": "[ s",
"command": "editor.action.wordHighlight.prev",
"when": "editorFocus && hasWordHighlights && vim.mode == 'Normal' && !terminalFocus",
},
{
"key": "] s",
"command": "editor.action.wordHighlight.next",
"when": "editorFocus && hasWordHighlights && vim.mode == 'Normal' && !terminalFocus",
}
]
jsonc
[
// search results
{
"key": "[ f",
"command": "search.action.focusPreviousSearchResult",
"when": "editorFocus && vim.mode == 'Normal' && !terminalFocus"
},
{
"key": "] f",
"command": "search.action.focusNextSearchResult",
"when": "editorFocus && vim.mode == 'Normal' && !terminalFocus"
},
// problems/warnings
{
"key": "[ e",
"command": "editor.action.marker.prev",
"when": "editorFocus && vim.mode == 'Normal' && !terminalFocus"
},
{
"key": "] e",
"command": "editor.action.marker.next",
"when": "editorFocus && vim.mode == 'Normal' && !terminalFocus"
},
// scm changes
{
"key": "[ d",
"command": "workbench.action.editor.previousChange",
"when": "editorFocus && vim.mode == 'Normal' && !terminalFocus"
},
{
"key": "] d",
"command": "workbench.action.editor.nextChange",
"when": "editorFocus && vim.mode == 'Normal' && !terminalFocus"
},
{
"key": "[ d",
"command": "workbench.action.compareEditor.previousChange",
"when": "textCompareEditorVisible && vim.mode == 'Normal' && !terminalFocus"
},
{
"key": "] d",
"command": "workbench.action.compareEditor.nextChange",
"when": "textCompareEditorVisible && vim.mode == 'Normal' && !terminalFocus"
},
// selections under cursor
{
"key": "[ s",
"command": "editor.action.wordHighlight.prev",
"when": "editorFocus && hasWordHighlights && vim.mode == 'Normal' && !terminalFocus",
},
{
"key": "] s",
"command": "editor.action.wordHighlight.next",
"when": "editorFocus && hasWordHighlights && vim.mode == 'Normal' && !terminalFocus",
}
]

Explorer

Just single one here but heavily used by me nonetheless:

jsonc
[
// collapse all
{
"key": "cmd+k cmd+0",
"command": "workbench.files.action.collapseExplorerFolders",
"when": "explorerViewletFocus"
}
]
jsonc
[
// collapse all
{
"key": "cmd+k cmd+0",
"command": "workbench.files.action.collapseExplorerFolders",
"when": "explorerViewletFocus"
}
]
jsonc
[
// similarly to native VSCode fold collapse/expand bindings
// the following collapse & expand search results when global
// search view is focused
{
"key": "cmd+k cmd+0",
"command": "search.action.collapseSearchResults",
"when": "focusedView == 'workbench.view.search'"
},
{
"key": "cmd+k cmd+j",
"command": "search.action.expandSearchResults",
"when": "focusedView == 'workbench.view.search'"
},
// change focus from search view to editor group
{
"key": "shift+cmd+f",
"command": "workbench.action.focusActiveEditorGroup",
"when": "searchViewletFocus && searchInputBoxFocus"
},
// change focus back from editor group to global search view
// preserving list focus if any (this one really annoyed me)
{
"key": "shift+cmd+f",
"command": "workbench.action.focusSideBar",
"when": "searchViewletVisible && !searchViewletFocus"
},
// especially proud of this one: switch focus from
// search input to result list, yay!
{
"key": "cmd+/",
"command": "search.action.focusSearchList",
"when": "searchViewletFocus && !listHasSelectionOrFocus"
},
// and back from list to input!
{
"key": "cmd+/",
"command": "workbench.action.findInFiles",
"when": "searchViewletFocus && listHasSelectionOrFocus && !replaceActive"
},
{
"key": "cmd+/",
"command": "workbench.action.replaceInFiles",
"when": "searchViewletFocus && listHasSelectionOrFocus && replaceActive"
},
// toggle tree/list view
{
"key": "cmd+k t",
"command": "search.action.viewAsList",
"when": "searchViewletFocus && inTreeView"
},
{
"key": "cmd+k t",
"command": "search.action.viewAsTree",
"when": "searchViewletFocus && !inTreeView"
},
// toggle match case
{
"key": "cmd+k c",
"command": "toggleSearchCaseSensitive",
"when": "searchViewletFocus && searchInputBoxFocus"
},
// toggle whole word
{
"key": "cmd+k w",
"command": "toggleSearchWholeWord",
"when": "searchViewletFocus && searchInputBoxFocus"
},
// toggle regex
{
"key": "cmd+k r",
"command": "toggleSearchRegex",
"when": "searchViewletFocus && searchInputBoxFocus"
},
]
jsonc
[
// similarly to native VSCode fold collapse/expand bindings
// the following collapse & expand search results when global
// search view is focused
{
"key": "cmd+k cmd+0",
"command": "search.action.collapseSearchResults",
"when": "focusedView == 'workbench.view.search'"
},
{
"key": "cmd+k cmd+j",
"command": "search.action.expandSearchResults",
"when": "focusedView == 'workbench.view.search'"
},
// change focus from search view to editor group
{
"key": "shift+cmd+f",
"command": "workbench.action.focusActiveEditorGroup",
"when": "searchViewletFocus && searchInputBoxFocus"
},
// change focus back from editor group to global search view
// preserving list focus if any (this one really annoyed me)
{
"key": "shift+cmd+f",
"command": "workbench.action.focusSideBar",
"when": "searchViewletVisible && !searchViewletFocus"
},
// especially proud of this one: switch focus from
// search input to result list, yay!
{
"key": "cmd+/",
"command": "search.action.focusSearchList",
"when": "searchViewletFocus && !listHasSelectionOrFocus"
},
// and back from list to input!
{
"key": "cmd+/",
"command": "workbench.action.findInFiles",
"when": "searchViewletFocus && listHasSelectionOrFocus && !replaceActive"
},
{
"key": "cmd+/",
"command": "workbench.action.replaceInFiles",
"when": "searchViewletFocus && listHasSelectionOrFocus && replaceActive"
},
// toggle tree/list view
{
"key": "cmd+k t",
"command": "search.action.viewAsList",
"when": "searchViewletFocus && inTreeView"
},
{
"key": "cmd+k t",
"command": "search.action.viewAsTree",
"when": "searchViewletFocus && !inTreeView"
},
// toggle match case
{
"key": "cmd+k c",
"command": "toggleSearchCaseSensitive",
"when": "searchViewletFocus && searchInputBoxFocus"
},
// toggle whole word
{
"key": "cmd+k w",
"command": "toggleSearchWholeWord",
"when": "searchViewletFocus && searchInputBoxFocus"
},
// toggle regex
{
"key": "cmd+k r",
"command": "toggleSearchRegex",
"when": "searchViewletFocus && searchInputBoxFocus"
},
]

Editor groups

Now the following key bindings are all about managing editor groups:

jsonc
[
// close all editors
{
"key": "cmd+e w",
"command": "workbench.action.closeEditorsInGroup"
},
{
"key": "cmd+k w",
"command": "-workbench.action.closeEditorsInGroup"
},
// close all unsaved editors
{
"key": "cmd+e u",
"command": "workbench.action.closeUnmodifiedEditors",
},
// close other editors in group
{
"key": "cmd+e o",
"command": "workbench.action.closeOtherEditors",
},
// close to the left/right
{
"key": "cmd+e l",
"command": "workbench.action.closeEditorsToTheRight",
},
{
"key": "cmd+e h",
"command": "workbench.action.closeEditorsToTheLeft",
},
// move editor to other group
{
"key": "cmd+e shift+k",
"command": "workbench.action.moveEditorToAboveGroup",
},
{
"key": "cmd+e shift+j",
"command": "workbench.action.moveEditorToBelowGroup",
},
{
"key": "cmd+e shift+l",
"command": "workbench.action.moveEditorToRightGroup",
},
{
"key": "cmd+e shift+h",
"command": "workbench.action.moveEditorToLeftGroup",
},
// toggle maximize
{
"key": "cmd+w m",
"command": "workbench.action.toggleEditorWidths",
},
// hide all panels & views
{
"key": "cmd+w cmd+m",
"command": "extension.multiCommand.execute",
"args": {
"sequence": [
"workbench.action.closePanel",
"workbench.action.closeSidebar",
"workbench.action.closeAuxiliaryBar"
]
}
},
// navigate between views
{
"key": "cmd+w cmd+l",
"command": "workbench.action.navigateRight"
},
{
"key": "cmd+w cmd+h",
"command": "workbench.action.navigateLeft"
},
{
"key": "cmd+w cmd+k",
"command": "workbench.action.navigateUp"
},
{
"key": "cmd+w cmd+j",
"command": "workbench.action.navigateDown"
},
// rebind 'cmd+w' to 'cmd+w cmd+w' chord
{
"key": "cmd+w cmd+w",
"command": "workbench.action.closeWindow",
"when": "!editorIsOpen && !multipleEditorGroups && textInputFocus"
},
{
"key": "cmd+w",
"command": "-workbench.action.closeWindow",
"when": "!editorIsOpen && !multipleEditorGroups"
},
{
"key": "cmd+w cmd+w",
"command": "workbench.action.closeActiveEditor"
},
{
"key": "cmd+w",
"command": "-workbench.action.closeActiveEditor"
},
{
"key": "cmd+w cmd+w",
"command": "workbench.action.closeGroup",
"when": "activeEditorGroupEmpty && multipleEditorGroups"
},
{
"key": "cmd+w",
"command": "-workbench.action.closeGroup",
"when": "activeEditorGroupEmpty && multipleEditorGroups"
},
// move editor groups
{
"key": "cmd+w shift+l",
"command": "workbench.action.moveActiveEditorGroupRight",
},
{
"key": "cmd+w shift+h",
"command": "workbench.action.moveActiveEditorGroupLeft",
},
{
"key": "cmd+w shift+j",
"command": "workbench.action.moveActiveEditorGroupDown",
},
{
"key": "cmd+w shift+k",
"command": "workbench.action.moveActiveEditorGroupUp",
},
// split editor group
{
"key": "cmd+w shift+cmd+h",
"command": "workbench.action.splitEditorLeft",
},
{
"key": "cmd+w shift+cmd+l",
"command": "workbench.action.splitEditorRight",
},
{
"key": "cmd+w shift+cmd+j",
"command": "workbench.action.splitEditorDown",
},
{
"key": "cmd+w shift+cmd+k",
"command": "workbench.action.splitEditorUp",
},
// switch tabs only within active editor group
{
"key": "shift+cmd+]",
"command": "workbench.action.nextEditorInGroup"
},
{
"key": "cmd+k alt+cmd+right",
"command": "-workbench.action.nextEditorInGroup"
},
{
"key": "shift+cmd+[",
"command": "workbench.action.previousEditorInGroup"
},
{
"key": "cmd+k alt+cmd+left",
"command": "-workbench.action.previousEditorInGroup"
}
]
jsonc
[
// close all editors
{
"key": "cmd+e w",
"command": "workbench.action.closeEditorsInGroup"
},
{
"key": "cmd+k w",
"command": "-workbench.action.closeEditorsInGroup"
},
// close all unsaved editors
{
"key": "cmd+e u",
"command": "workbench.action.closeUnmodifiedEditors",
},
// close other editors in group
{
"key": "cmd+e o",
"command": "workbench.action.closeOtherEditors",
},
// close to the left/right
{
"key": "cmd+e l",
"command": "workbench.action.closeEditorsToTheRight",
},
{
"key": "cmd+e h",
"command": "workbench.action.closeEditorsToTheLeft",
},
// move editor to other group
{
"key": "cmd+e shift+k",
"command": "workbench.action.moveEditorToAboveGroup",
},
{
"key": "cmd+e shift+j",
"command": "workbench.action.moveEditorToBelowGroup",
},
{
"key": "cmd+e shift+l",
"command": "workbench.action.moveEditorToRightGroup",
},
{
"key": "cmd+e shift+h",
"command": "workbench.action.moveEditorToLeftGroup",
},
// toggle maximize
{
"key": "cmd+w m",
"command": "workbench.action.toggleEditorWidths",
},
// hide all panels & views
{
"key": "cmd+w cmd+m",
"command": "extension.multiCommand.execute",
"args": {
"sequence": [
"workbench.action.closePanel",
"workbench.action.closeSidebar",
"workbench.action.closeAuxiliaryBar"
]
}
},
// navigate between views
{
"key": "cmd+w cmd+l",
"command": "workbench.action.navigateRight"
},
{
"key": "cmd+w cmd+h",
"command": "workbench.action.navigateLeft"
},
{
"key": "cmd+w cmd+k",
"command": "workbench.action.navigateUp"
},
{
"key": "cmd+w cmd+j",
"command": "workbench.action.navigateDown"
},
// rebind 'cmd+w' to 'cmd+w cmd+w' chord
{
"key": "cmd+w cmd+w",
"command": "workbench.action.closeWindow",
"when": "!editorIsOpen && !multipleEditorGroups && textInputFocus"
},
{
"key": "cmd+w",
"command": "-workbench.action.closeWindow",
"when": "!editorIsOpen && !multipleEditorGroups"
},
{
"key": "cmd+w cmd+w",
"command": "workbench.action.closeActiveEditor"
},
{
"key": "cmd+w",
"command": "-workbench.action.closeActiveEditor"
},
{
"key": "cmd+w cmd+w",
"command": "workbench.action.closeGroup",
"when": "activeEditorGroupEmpty && multipleEditorGroups"
},
{
"key": "cmd+w",
"command": "-workbench.action.closeGroup",
"when": "activeEditorGroupEmpty && multipleEditorGroups"
},
// move editor groups
{
"key": "cmd+w shift+l",
"command": "workbench.action.moveActiveEditorGroupRight",
},
{
"key": "cmd+w shift+h",
"command": "workbench.action.moveActiveEditorGroupLeft",
},
{
"key": "cmd+w shift+j",
"command": "workbench.action.moveActiveEditorGroupDown",
},
{
"key": "cmd+w shift+k",
"command": "workbench.action.moveActiveEditorGroupUp",
},
// split editor group
{
"key": "cmd+w shift+cmd+h",
"command": "workbench.action.splitEditorLeft",
},
{
"key": "cmd+w shift+cmd+l",
"command": "workbench.action.splitEditorRight",
},
{
"key": "cmd+w shift+cmd+j",
"command": "workbench.action.splitEditorDown",
},
{
"key": "cmd+w shift+cmd+k",
"command": "workbench.action.splitEditorUp",
},
// switch tabs only within active editor group
{
"key": "shift+cmd+]",
"command": "workbench.action.nextEditorInGroup"
},
{
"key": "cmd+k alt+cmd+right",
"command": "-workbench.action.nextEditorInGroup"
},
{
"key": "shift+cmd+[",
"command": "workbench.action.previousEditorInGroup"
},
{
"key": "cmd+k alt+cmd+left",
"command": "-workbench.action.previousEditorInGroup"
}
]

Folding

Default VSCode cmd+k cmd+{n} set of folding keybindings have this strange behaviour that once you press i.e cmd+k cmd+1 to fold on level 1 and then want to switch to level 2 by pressing cmd+k cmd+2 it doesn’t work and you need to first expand all by typing cmd+k cmd+j and then set the selected level of folding.

To fix this I installed another extension called multiCommand that allows to execute multiple commands in one keybinding. By leveraging this, I remapped all the default keybindings to first unfold and then perform the desired fold.

jsonc
// make 'Cmd+K Cmd+{n}' set 'n' folding level
{
"key": "cmd+k cmd+1",
"command": "extension.multiCommand.execute",
"args": {
"sequence": ["editor.unfoldAll", "editor.foldLevel1"]
},
"when": "editorTextFocus && foldingEnabled"
},
{
"key": "cmd+k cmd+2",
"command": "extension.multiCommand.execute",
"args": {
"sequence": ["editor.unfoldAll", "editor.foldLevel2"]
},
"when": "editorTextFocus && foldingEnabled"
},
{
"key": "cmd+k cmd+3",
"command": "extension.multiCommand.execute",
"args": {
"sequence": ["editor.unfoldAll", "editor.foldLevel3"]
},
"when": "editorTextFocus && foldingEnabled"
},
{
"key": "cmd+k cmd+4",
"command": "extension.multiCommand.execute",
"args": {
"sequence": ["editor.unfoldAll", "editor.foldLevel4"]
},
"when": "editorTextFocus && foldingEnabled"
},
{
"key": "cmd+k cmd+5",
"command": "extension.multiCommand.execute",
"args": {
"sequence": ["editor.unfoldAll", "editor.foldLevel5"]
},
"when": "editorTextFocus && foldingEnabled"
},
{
"key": "cmd+k cmd+6",
"command": "extension.multiCommand.execute",
"args": {
"sequence": ["editor.unfoldAll", "editor.foldLevel6"]
},
"when": "editorTextFocus && foldingEnabled"
},
{
"key": "cmd+k cmd+7",
"command": "extension.multiCommand.execute",
"args": {
"sequence": ["editor.unfoldAll", "editor.foldLevel7"]
},
"when": "editorTextFocus && foldingEnabled"
}
]
jsonc
// make 'Cmd+K Cmd+{n}' set 'n' folding level
{
"key": "cmd+k cmd+1",
"command": "extension.multiCommand.execute",
"args": {
"sequence": ["editor.unfoldAll", "editor.foldLevel1"]
},
"when": "editorTextFocus && foldingEnabled"
},
{
"key": "cmd+k cmd+2",
"command": "extension.multiCommand.execute",
"args": {
"sequence": ["editor.unfoldAll", "editor.foldLevel2"]
},
"when": "editorTextFocus && foldingEnabled"
},
{
"key": "cmd+k cmd+3",
"command": "extension.multiCommand.execute",
"args": {
"sequence": ["editor.unfoldAll", "editor.foldLevel3"]
},
"when": "editorTextFocus && foldingEnabled"
},
{
"key": "cmd+k cmd+4",
"command": "extension.multiCommand.execute",
"args": {
"sequence": ["editor.unfoldAll", "editor.foldLevel4"]
},
"when": "editorTextFocus && foldingEnabled"
},
{
"key": "cmd+k cmd+5",
"command": "extension.multiCommand.execute",
"args": {
"sequence": ["editor.unfoldAll", "editor.foldLevel5"]
},
"when": "editorTextFocus && foldingEnabled"
},
{
"key": "cmd+k cmd+6",
"command": "extension.multiCommand.execute",
"args": {
"sequence": ["editor.unfoldAll", "editor.foldLevel6"]
},
"when": "editorTextFocus && foldingEnabled"
},
{
"key": "cmd+k cmd+7",
"command": "extension.multiCommand.execute",
"args": {
"sequence": ["editor.unfoldAll", "editor.foldLevel7"]
},
"when": "editorTextFocus && foldingEnabled"
}
]

Miscellaneous

All the rest keybindings I can’t live without but doesn’t fit into other categories:

jsonc
[
// trigger source action
{
"key": "cmd+shift+.",
"command": "editor.action.sourceAction",
"when": "editorTextFocus && !editorReadOnly"
},
// toggle secondary sidebar
{
"key": "shift+cmd+a",
"command": "workbench.action.toggleAuxiliaryBar"
},
// set indentation for a file
{
"key": "cmd+k cmd+m",
"command": "changeEditorIndentation3",
"when": "editorTextFocus"
},
// close find widget when focused
{
"key": "cmd+f",
"command": "closeFindWidget",
"when": "editorFocus && findWidgetVisible && findInputFocussed && !isComposing"
},
// open keybindings.json
{
"key": "cmd+k s",
"command": "workbench.action.openGlobalKeybindingsFile"
},
// open settings.json
{
"key": "shift+cmd+,",
"command": "workbench.action.openSettingsJson"
},
// rebind quit to 'cmd+k q' (cmd+q was to easy to type for me)
{
"key": "cmd+k q",
"command": "workbench.action.quit"
},
{
"key": "cmd+q",
"command": "-workbench.action.quit"
},
// vim half page up/down
{
"key": "shift+j",
"command": "extension.vim_ctrl+d",
"when": "editorTextFocus && vim.active && vim.use<C-d> && !inDebugRepl && vim.mode == 'Normal'"
},
{
"key": "shift+k",
"command": "extension.vim_ctrl+u",
"when": "editorTextFocus && vim.active && vim.use<C-u> && !inDebugRepl && vim.mode == 'Normal'"
}
]
jsonc
[
// trigger source action
{
"key": "cmd+shift+.",
"command": "editor.action.sourceAction",
"when": "editorTextFocus && !editorReadOnly"
},
// toggle secondary sidebar
{
"key": "shift+cmd+a",
"command": "workbench.action.toggleAuxiliaryBar"
},
// set indentation for a file
{
"key": "cmd+k cmd+m",
"command": "changeEditorIndentation3",
"when": "editorTextFocus"
},
// close find widget when focused
{
"key": "cmd+f",
"command": "closeFindWidget",
"when": "editorFocus && findWidgetVisible && findInputFocussed && !isComposing"
},
// open keybindings.json
{
"key": "cmd+k s",
"command": "workbench.action.openGlobalKeybindingsFile"
},
// open settings.json
{
"key": "shift+cmd+,",
"command": "workbench.action.openSettingsJson"
},
// rebind quit to 'cmd+k q' (cmd+q was to easy to type for me)
{
"key": "cmd+k q",
"command": "workbench.action.quit"
},
{
"key": "cmd+q",
"command": "-workbench.action.quit"
},
// vim half page up/down
{
"key": "shift+j",
"command": "extension.vim_ctrl+d",
"when": "editorTextFocus && vim.active && vim.use<C-d> && !inDebugRepl && vim.mode == 'Normal'"
},
{
"key": "shift+k",
"command": "extension.vim_ctrl+u",
"when": "editorTextFocus && vim.active && vim.use<C-u> && !inDebugRepl && vim.mode == 'Normal'"
}
]

Summary

Hope you enjoyed and got inspired to make your editor truly yours!