You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
VimCode stacks three layers of keybindings on top of each other. Understanding this helps debug any binding that doesn't behave as expected.
Layer 3 — which-key (VSpaceCode.whichkey)
Trigger: ~ in Normal/Visual mode → whichkey.show
Owns: the popup menu tree (whichkey.bindings in settings.json)
Fallback: if which-key is not installed, ~ is a no-op and
the Layer 2 vim bindings handle everything directly
NOTE: <space> would be the LazyVim-matching trigger but conflicts
with vim.leader = "<space>" — the leader intercepts <space>
before which-key can fire. ~ is used as the reliable workaround.
Layer 2 — Custom LazyVim mappings
Leader: settings.json → vim.normalModeKeyBindingsNonRecursive
(first match wins; ~ → whichkey.show is entry #1)
Modifiers: keybindings.json — Ctrl/Alt/Shift bindings
(last definition wins for equal when-clause specificity;
user keybindings.json always beats VSCodeVim's handlers)
Escape: vim.handleKeys — explicitly releases certain Ctrl keys
back to VS Code (e.g. <C-f>, <C-w>, <C-s>)
Layer 1 — VSCodeVim defaults (vscodevim.vim)
Core Vim: h j k l, w b e, gg G, / ? * #, etc.
Ctrl keys intercepted by default (vim.useCtrlKeys=true):
C-d C-u (half-page scroll — kept in vim.handleKeys)
C-o C-i (jump list — kept)
C-r (redo — kept)
C-n C-p (autocomplete in Insert — kept)
C-f C-b C-h C-j C-k C-l C-w C-s C-a C-c C-v C-z
(all released to VS Code via vim.handleKeys: false)
Plugins: EasyMotion (<leader><leader>*) — re-exposed as <leader>j*
Sneak (s/S forward/backward, ; next, , prev)
Surround (ys / ds / cs)
Key resolution rule: if a binding isn't firing, check whether a higher-priority layer is consuming it first. User keybindings.json always beats VSCodeVim's type handler for the same key+when combination.
Note: Git operations marked "GitLens" require the GitLens extension.
Window Management — <leader>w*
Keybinding
Action
Notes
<leader>wd
Close window/split
Close editor group
<leader>ww
Switch window
Focus next group
<leader>wm
Maximize window
Toggle maximize
<leader>-
Split below
Horizontal split
<leader>|
Split right
Vertical split
Ctrl+h
Focus left split
Window navigation
Ctrl+j
Focus below split
Window navigation
Ctrl+k
Focus above split
Window navigation
Ctrl+l
Focus right split
Window navigation
Ctrl+←→↑↓
Resize splits
Adjust split size
Ctrl+1/2/3
Focus editor group
Direct group focus
Diagnostics — <leader>x* and []
Keybinding
Action
Notes
<leader>xx
Open problems panel
Show all diagnostics
<leader>xX
Workspace diagnostics
All files
[d
Previous diagnostic
All files
]d
Next diagnostic
All files
[e
Previous error
Current file only
]e
Next error
Current file only
[q
Previous search result
Search navigation
]q
Next search result
Search navigation
UI Toggles — <leader>u*
Keybinding
Action
Extension
<leader>uw
Toggle word wrap
Native
<leader>uz
Toggle zen mode
Native
<leader>ur
Clear search highlight
Native
<leader>ul
Toggle line numbers
Settings Cycler
<leader>uL
Toggle relative numbers
Settings Cycler
Note: Line number toggles require the Settings Cycler extension.
By Context
LSP Navigation — g*
Keybinding
Action
Notes
gd
Go to definition
Jump to source
gD
Go to declaration
Jump to header/interface
gr
Go to references
Show all uses
gI
Go to implementation
Jump to impl
gy
Go to type definition
Type source
gK
Signature help
Function params
K
Show hover
Docs and type info
Ctrl+o
Navigate back
After jumping
Ctrl+i
Navigate forward
Redo navigation
Insert Mode
Keybinding
Action
Notes
jk
Exit to Normal mode
Alternative to Esc
jj
Exit to Normal mode
Alternative to Esc
Ctrl+n
Next suggestion
Autocomplete (vim default)
Ctrl+p
Previous suggestion
Autocomplete (vim default)
Ctrl+j
Next suggestion
Autocomplete (when widget visible)
Ctrl+k
Previous suggestion
Autocomplete (when widget visible)
Ctrl+s
Save file
Standard VS Code
Note:Ctrl+d/u for paging through suggestions is not available — vim.handleKeys keeps those keys for half-page scrolling and they cannot be conditionally released. Use Ctrl+n/p as a reliable fallback.
Visual Mode
Keybinding
Action
Notes
<
Indent left & reselect
Stay in Visual
>
Indent right & reselect
Stay in Visual
gc
Toggle comment
Comment lines
<leader>a
Select all occurrences
Multi-cursor
<leader>ss
Sort lines (ascending)
Line sorting
<leader>u
Transform to UPPERCASE
Text transform
<leader>l
Transform to lowercase
Text transform
Explorer Navigation
Keybinding
Action
Context
j
Down
File explorer
k
Up
File explorer
h
Collapse folder
File explorer
l
Expand folder
File explorer
Enter
Open file
File explorer
Ctrl+Enter
Rename
File explorer
Ctrl+Shift+1
Open in left split
File explorer
Ctrl+Shift+2
Open in right split
File explorer
Terminal Operations
Keybinding
Action
Notes
Ctrl+/
Toggle terminal
Show/hide
<leader>ft
Toggle terminal
Alternative
Ctrl+;
Focus terminal
Switch focus
Ctrl+Shift+;
Maximize terminal
Toggle max
Vim Plugins
EasyMotion
Fast cursor movement to visible text. Use <leader>j* — the <leader>j group in which-key:
Keybinding
Action
<leader>jw
Jump to word (forward)
<leader>jb
Jump to word (backward)
<leader>js{char}
Jump to character
<leader>jj
Jump to line (down)
<leader>jk
Jump to line (up)
The native <leader><leader>* form still works when which-key is not installed. When which-key is active, use <leader>j* instead — ~ now triggers the which-key menu, so <space> remains clean as the leader key.
Sneak
Two-character search for quick navigation.
Keybinding
Action
s{char}{char}
Sneak forward
S{char}{char}
Sneak backward
;
Next occurrence
,
Previous occurrence
Note: The which-key menu also has , bound to "Switch Buffer" (<space>,). These do not conflict — Sneak's , fires when you press , directly in Normal mode; which-key's , only fires when the which-key menu is already open (i.e. after pressing <space>). They are entirely separate key sequences.