Skip to content

Instantly share code, notes, and snippets.

@wojukasz
Last active February 7, 2026 10:18
Show Gist options
  • Select an option

  • Save wojukasz/d76ca3162debc66d4227b9dc6049789e to your computer and use it in GitHub Desktop.

Select an option

Save wojukasz/d76ca3162debc66d4227b9dc6049789e to your computer and use it in GitHub Desktop.
⚡ Quick Start: VS Code + Vim keybindings | Works with AntiGravity Cursor | Copy-paste ready config | 5-min setup | Full version: https://github.com/wojukasz/VimCode (50+ keybindings, LazyVim-inspired, multi-editor support)
[
// ╔══════════════════════════════════════════════════════════════════════════════════╗
// ║ VSCODE VIM LAZYVIM KEYBINDINGS ║
// ║ Modifier Key Bindings (Ctrl, Alt, Shift) ║
// ╚══════════════════════════════════════════════════════════════════════════════════╝
//
// This file contains keybindings that use modifier keys (Ctrl, Alt, Shift) and special
// characters that need VSCode's key binding system (not Vim's).
//
// IMPORTANT: DO NOT put space-leader bindings here (<leader>...)
// Those belong in settings.json under vim.normalModeKeyBindingsNonRecursive
//
// FILE ORGANIZATION:
// - Window navigation (Ctrl+h/j/k/l)
// - Buffer navigation (Shift+h/l, [b, ]b)
// - Diagnostic navigation ([d, ]d, [e, ]e)
// - Quickfix navigation ([q, ]q)
// - Git hunk navigation ([h, ]h)
// - Suggestion/autocomplete navigation
// - File explorer navigation
// - Terminal toggle
// - Line movement (Alt+j/k)
//
// SPECIAL KEY CODES:
// - oem_4 = [ (left bracket)
// - oem_6 = ] (right bracket)
// - oem_2 = / (forward slash)
// - oem_1 = ; (semicolon)
//
// For keyboard layout independence, you can use scan codes instead:
// - [BracketLeft] instead of oem_4
// - [BracketRight] instead of oem_6
// - [Slash] instead of oem_2
//
// WHEN CLAUSES:
// The "when" field controls when a binding is active. Common contexts:
// - editorTextFocus: cursor is in an editor
// - vim.active: Vim extension is active
// - vim.mode: current Vim mode (Normal, Insert, Visual)
// - suggestWidgetVisible: autocomplete menu is open
// - inQuickOpen: Quick Open (Ctrl+P) is open
// - terminalFocus: terminal is focused
// - listFocus: a list (explorer, search) has focus
//
// ══════════════════════════════════════════════════════════════════════════════════════
// ┌────────────────────────────────────────────────────────────────────────────────────┐
// │ WINDOW NAVIGATION - Ctrl+h/j/k/l (LazyVim: <C-h/j/k/l>) │
// └────────────────────────────────────────────────────────────────────────────────────┘
//
// Navigate between editor splits using Vim-style hjkl keys with Ctrl modifier.
// These work in Normal mode and are disabled when:
// - Terminal is focused (so Ctrl+h/j/k/l work normally in terminal)
// - Suggestion widget is visible (so Ctrl+j/k navigate suggestions)
// - Quick Open is active (so Ctrl+j/k navigate file list)
//
{
"key": "ctrl+h",
"command": "workbench.action.focusLeftGroup",
"when": "!terminalFocus && vim.active && vim.mode != 'Insert'"
},
{
"key": "ctrl+l",
"command": "workbench.action.focusRightGroup",
"when": "!terminalFocus && vim.active && vim.mode != 'Insert'"
},
{
"key": "ctrl+j",
"command": "workbench.action.focusBelowGroup",
"when": "!terminalFocus && !suggestWidgetVisible && !inQuickOpen && vim.active && vim.mode != 'Insert'"
},
{
"key": "ctrl+k",
"command": "workbench.action.focusAboveGroup",
"when": "!terminalFocus && !suggestWidgetVisible && !inQuickOpen && vim.active && vim.mode != 'Insert'"
},
// ┌────────────────────────────────────────────────────────────────────────────────────┐
// │ WINDOW RESIZING - Ctrl+Arrow Keys (LazyVim: <C-Up/Down/Left/Right>) │
// └────────────────────────────────────────────────────────────────────────────────────┘
//
// Resize editor splits using Ctrl+Arrow keys. Only active in Normal mode to avoid
// interfering with text editing shortcuts (Ctrl+Left/Right normally jump words).
//
{
"key": "ctrl+up",
"command": "workbench.action.increaseViewHeight",
"when": "vim.active && vim.mode == 'Normal'"
},
{
"key": "ctrl+down",
"command": "workbench.action.decreaseViewHeight",
"when": "vim.active && vim.mode == 'Normal'"
},
{
"key": "ctrl+left",
"command": "workbench.action.decreaseViewWidth",
"when": "vim.active && vim.mode == 'Normal'"
},
{
"key": "ctrl+right",
"command": "workbench.action.increaseViewWidth",
"when": "vim.active && vim.mode == 'Normal'"
},
// ┌────────────────────────────────────────────────────────────────────────────────────┐
// │ BUFFER NAVIGATION - Shift+h/l (LazyVim: <S-h>, <S-l>) │
// └────────────────────────────────────────────────────────────────────────────────────┘
//
// Switch between open editor tabs using Shift+H (previous) and Shift+L (next).
// Only active in Normal/Visual modes to avoid conflicts with text selection.
// Alternative: Use [b and ]b (defined below) for the same functionality.
//
{
"key": "shift+h",
"command": "workbench.action.previousEditor",
"when": "vim.active && vim.mode != 'Insert'"
},
{
"key": "shift+l",
"command": "workbench.action.nextEditor",
"when": "vim.active && vim.mode != 'Insert'"
},
// ┌────────────────────────────────────────────────────────────────────────────────────┐
// │ LINE MOVEMENT - Alt+j/k (LazyVim: <A-j>, <A-k>) │
// └────────────────────────────────────────────────────────────────────────────────────┘
//
// Move lines up/down using Alt+J/K. Works in Normal and Visual modes.
// In Visual mode, moves the entire selection.
//
{
"key": "alt+j",
"command": "editor.action.moveLinesDownAction",
"when": "editorTextFocus && !editorReadonly"
},
{
"key": "alt+k",
"command": "editor.action.moveLinesUpAction",
"when": "editorTextFocus && !editorReadonly"
},
// ┌────────────────────────────────────────────────────────────────────────────────────┐
// │ SAVE FILE - Ctrl+s (LazyVim: <C-s>) │
// └────────────────────────────────────────────────────────────────────────────────────┘
//
// Standard save shortcut. Works in all modes.
//
{
"key": "ctrl+s",
"command": "workbench.action.files.save",
"when": "editorTextFocus"
},
// ┌────────────────────────────────────────────────────────────────────────────────────┐
// │ TERMINAL TOGGLE - Ctrl+/ (LazyVim: <C-/>) │
// └────────────────────────────────────────────────────────────────────────────────────┘
//
// Toggle terminal panel visibility using Ctrl+/.
// - If terminal is hidden: opens and focuses it
// - If terminal is visible and focused: closes it
// - If terminal is visible but not focused: focuses it
//
// Note: oem_2 is the / (forward slash) key
//
{
"key": "ctrl+oem_2",
"command": "workbench.action.terminal.toggleTerminal"
},
// Alternative terminal toggle that focuses terminal if not focused
{
"key": "ctrl+oem_2",
"command": "workbench.action.terminal.focus",
"when": "!terminalFocus"
},
// ┌────────────────────────────────────────────────────────────────────────────────────┐
// │ TERMINAL NAVIGATION - Ctrl+; (bidirectional toggle) │
// └────────────────────────────────────────────────────────────────────────────────────┘
//
// Use Ctrl+; to jump between editor and terminal without closing it:
// - When in editor: jumps to terminal (opens if closed)
// - When in terminal: jumps back to editor
//
{
"key": "ctrl+;",
"command": "workbench.action.terminal.focus",
"when": "!terminalFocus"
},
{
"key": "ctrl+;",
"command": "workbench.action.focusActiveEditorGroup",
"when": "terminalFocus"
}
// #TODO: EXPERIMENTAL - TO TEST AND VALIDATE!
// ┌────────────────────────────────────────────────────────────────────────────────────┐
// │ SUGGESTION WIDGET NAVIGATION - Ctrl+j/k when autocomplete is visible │
// └────────────────────────────────────────────────────────────────────────────────────┘
//
// Navigate autocomplete suggestions using Vim-style j/k keys.
// These override the window navigation when suggestion widget is visible.
//
{
"key": "ctrl+j",
"command": "selectNextSuggestion",
"when": "suggestWidgetVisible"
},
{
"key": "ctrl+k",
"command": "selectPrevSuggestion",
"when": "suggestWidgetVisible"
},
{
"key": "ctrl+d",
"command": "selectNextPageSuggestion",
"when": "suggestWidgetVisible"
},
{
"key": "ctrl+u",
"command": "selectPrevPageSuggestion",
"when": "suggestWidgetVisible"
},
// ┌────────────────────────────────────────────────────────────────────────────────────┐
// │ QUICK OPEN NAVIGATION - Ctrl+j/k when file picker is open │
// └────────────────────────────────────────────────────────────────────────────────────┘
//
// Navigate Quick Open (Ctrl+P) file list using Vim-style j/k keys.
//
{
"key": "ctrl+j",
"command": "workbench.action.quickOpenSelectNext",
"when": "inQuickOpen"
},
{
"key": "ctrl+k",
"command": "workbench.action.quickOpenSelectPrevious",
"when": "inQuickOpen"
},
// ┌────────────────────────────────────────────────────────────────────────────────────┐
// │ DIAGNOSTICS NAVIGATION - [d, ]d (all files) and [e, ]e (current file) │
// └────────────────────────────────────────────────────────────────────────────────────┘
//
// LazyVim diagnostic navigation using bracket prefix:
// - [d / ]d = previous/next diagnostic across all files
// - [e / ]e = previous/next diagnostic in current file only
//
// SPECIAL KEY CODES:
// - oem_4 = [ (left bracket)
// - oem_6 = ] (right bracket)
//
// On non-US keyboards, you may need to use scan codes instead:
// - "key": "[BracketLeft] d" instead of "key": "oem_4 d"
//
// Only active in Normal mode to prevent conflicts when typing brackets in Insert mode.
//
{
"key": "oem_4 d", // [d = previous diagnostic (all files)
"command": "editor.action.marker.prevInFiles",
"when": "editorTextFocus && vim.active && vim.mode == 'Normal'"
},
{
"key": "oem_6 d", // ]d = next diagnostic (all files)
"command": "editor.action.marker.nextInFiles",
"when": "editorTextFocus && vim.active && vim.mode == 'Normal'"
},
{
"key": "oem_4 e", // [e = previous diagnostic (current file)
"command": "editor.action.marker.prev",
"when": "editorTextFocus && vim.active && vim.mode == 'Normal'"
},
{
"key": "oem_6 e", // ]e = next diagnostic (current file)
"command": "editor.action.marker.next",
"when": "editorTextFocus && vim.active && vim.mode == 'Normal'"
},
// ┌────────────────────────────────────────────────────────────────────────────────────┐
// │ QUICKFIX/SEARCH RESULTS NAVIGATION - [q, ]q │
// └────────────────────────────────────────────────────────────────────────────────────┘
//
// Navigate search results using bracket prefix.
// Only active when search results exist and in Normal mode.
//
{
"key": "oem_4 q", // [q = previous search result
"command": "search.action.focusPreviousSearchResult",
"when": "hasSearchResult && vim.active && vim.mode == 'Normal'"
},
{
"key": "oem_6 q", // ]q = next search result
"command": "search.action.focusNextSearchResult",
"when": "hasSearchResult && vim.active && vim.mode == 'Normal'"
},
// ┌────────────────────────────────────────────────────────────────────────────────────┐
// │ BUFFER NAVIGATION - [b, ]b (alternate method) │
// └────────────────────────────────────────────────────────────────────────────────────┘
//
// Alternative buffer navigation using bracket prefix (same as Shift+H/L).
// Some users prefer this LazyVim pattern for consistency with other bracket navigation.
//
{
"key": "oem_4 b", // [b = previous buffer/editor
"command": "workbench.action.previousEditor",
"when": "editorTextFocus && vim.active && vim.mode == 'Normal'"
},
{
"key": "oem_6 b", // ]b = next buffer/editor
"command": "workbench.action.nextEditor",
"when": "editorTextFocus && vim.active && vim.mode == 'Normal'"
},
// ┌────────────────────────────────────────────────────────────────────────────────────┐
// │ GIT HUNK NAVIGATION - [h, ]h (requires Git or GitLens) │
// └────────────────────────────────────────────────────────────────────────────────────┘
//
// Navigate between git changes/hunks in the current file.
// Works with native VSCode git or GitLens extension.
//
{
"key": "oem_4 h", // [h = previous git change
"command": "workbench.action.editor.previousChange",
"when": "editorTextFocus && vim.active && vim.mode == 'Normal'"
},
{
"key": "oem_6 h", // ]h = next git change
"command": "workbench.action.editor.nextChange",
"when": "editorTextFocus && vim.active && vim.mode == 'Normal'"
},
// ┌────────────────────────────────────────────────────────────────────────────────────┐
// │ FILE EXPLORER NAVIGATION - Ctrl+h/j/k/l when explorer is focused │
// └────────────────────────────────────────────────────────────────────────────────────┘
//
// Navigate file explorer using Vim keys when it has focus:
// - j/k = down/up
// - h = collapse folder or go to parent
// - l = expand folder or open file
//
// IMPORTANT: These must come AFTER the window navigation bindings above.
// VSCode processes keybindings from bottom to top, so more specific contexts
// (explorerViewletVisible) override more general ones (!terminalFocus).
//
{
"key": "ctrl+j",
"command": "list.focusDown",
"when": "explorerViewletVisible && filesExplorerFocus && !inputFocus"
},
{
"key": "ctrl+k",
"command": "list.focusUp",
"when": "explorerViewletVisible && filesExplorerFocus && !inputFocus"
},
{
"key": "ctrl+h",
"command": "list.collapse",
"when": "explorerViewletVisible && filesExplorerFocus && !inputFocus"
},
{
"key": "ctrl+l",
"command": "list.select",
"when": "explorerViewletVisible && filesExplorerFocus && !inputFocus"
},
// Alternative: Use j/k without Ctrl for explorer navigation (more Vim-like)
// Uncomment these if you prefer plain j/k in the explorer:
// {
// "key": "j",
// "command": "list.focusDown",
// "when": "explorerViewletVisible && filesExplorerFocus && !inputFocus"
// },
// {
// "key": "k",
// "command": "list.focusUp",
// "when": "explorerViewletVisible && filesExplorerFocus && !inputFocus"
// },
// {
// "key": "h",
// "command": "list.collapse",
// "when": "explorerViewletVisible && filesExplorerFocus && !inputFocus"
// },
// {
// "key": "l",
// "command": "list.select",
// "when": "explorerViewletVisible && filesExplorerFocus && !inputFocus"
// },
// ┌────────────────────────────────────────────────────────────────────────────────────┐
// │ SEARCH/PROBLEMS PANEL NAVIGATION - j/k when panel has focus │
// └────────────────────────────────────────────────────────────────────────────────────┘
//
// Navigate lists in search results and problems panel using j/k.
//
{
"key": "j",
"command": "list.focusDown",
"when": "listFocus && !inputFocus"
},
{
"key": "k",
"command": "list.focusUp",
"when": "listFocus && !inputFocus"
},
// Navigate in panels with Ctrl+j/k as alternative
{
"key": "ctrl+j",
"command": "list.focusDown",
"when": "panelFocus && !terminalFocus"
},
{
"key": "ctrl+k",
"command": "list.focusUp",
"when": "panelFocus && !terminalFocus"
},
// ┌────────────────────────────────────────────────────────────────────────────────────┐
// │ FOCUS EDITOR GROUPS - Ctrl+1/2/3 │
// └────────────────────────────────────────────────────────────────────────────────────┘
//
// Quickly jump to specific editor groups/splits.
// Useful when you have multiple splits and want to jump directly to one.
//
{
"key": "ctrl+1",
"command": "workbench.action.focusFirstEditorGroup"
},
{
"key": "ctrl+2",
"command": "workbench.action.focusSecondEditorGroup"
},
{
"key": "ctrl+3",
"command": "workbench.action.focusThirdEditorGroup"
},
{
"key": "ctrl+4",
"command": "workbench.action.focusFourthEditorGroup"
},
{
"key": "ctrl+5",
"command": "workbench.action.focusFifthEditorGroup"
}
// ══════════════════════════════════════════════════════════════════════════════════════
// TROUBLESHOOTING NOTES
// ══════════════════════════════════════════════════════════════════════════════════════
//
// BRACKET KEYS NOT WORKING ([d, ]d, etc.):
//
// 1. UK/Non-US Keyboard Layouts:
// If you're on a non-US keyboard, the oem_4 and oem_6 codes might not work.
// Replace them with scan codes:
// - "key": "[BracketLeft] d" instead of "key": "oem_4 d"
// - "key": "[BracketRight] d" instead of "key": "oem_6 d"
//
// 2. MacOS:
// Brackets might require different key codes. Try:
// - "key": "[BracketLeft] d"
// - "key": "[BracketRight] d"
//
// 3. Testing bracket keys:
// Open VSCode Keyboard Shortcuts UI (Ctrl+K Ctrl+S / Cmd+K Cmd+S)
// Try to record your bracket key to see what VSCode detects it as
//
// CONFLICTS WITH OTHER EXTENSIONS:
//
// If keybindings don't work, check for conflicts:
// 1. Open Keyboard Shortcuts UI (Ctrl+K Ctrl+S / Cmd+K Cmd+S)
// 2. Search for the key combination (e.g., "ctrl+h")
// 3. Look for duplicate bindings from other extensions
// 4. Either disable the conflicting extension or modify your binding
//
// WHEN CLAUSES NOT WORKING:
//
// To debug when clauses:
// 1. Open Command Palette (Ctrl+Shift+P / Cmd+Shift+P)
// 2. Run "Developer: Inspect Context Keys"
// 3. This shows all active context keys for debugging
//
// VALIDATION CHECKLIST:
// □ Ctrl+h/j/k/l navigates between splits
// □ Shift+h/l switches buffers
// □ [d / ]d navigates diagnostics
// □ [b / ]b switches buffers
// □ Ctrl+j/k navigates suggestions when autocomplete is open
// □ Ctrl+j/k navigates file list when Quick Open is active
// □ Alt+j/k moves lines up/down
// □ Ctrl+/ toggles terminal
//
// ══════════════════════════════════════════════════════════════════════════════════════
]
{
// ╔══════════════════════════════════════════════════════════════════════════════════╗
// ║ VSCODE VIM LAZYVIM CONFIGURATION ║
// ║ Complete Settings for LazyVim Alignment ║
// ╚══════════════════════════════════════════════════════════════════════════════════╝
//
// This configuration provides LazyVim-style keybindings in VSCode using the Vim extension.
//
// REQUIRED EXTENSIONS:
// - vscodevim.vim (VSCode Vim) - Core requirement
//
// RECOMMENDED EXTENSIONS:
// - eamodio.gitlens (GitLens) - For git operations like blame, history
// - hoovercj.vscode-settings-cycler (Settings Cycler) - For line number toggling
// - VSpaceCode.whichkey (Which Key) - For keybinding discovery menus
// - usernamehw.errorlens (Error Lens) - Inline diagnostics display
//
// PERFORMANCE OPTIMIZATION:
// The extensions.experimental.affinity setting (at bottom of file) runs Vim extension
// in a separate thread to prevent typing lag. This is CRITICAL for performance.
//
// FILE ORGANIZATION:
// This file contains ALL space-leader keybindings (<leader>...). Standard VSCode keybindings
// that don't use the leader key go in keybindings.json to prevent conflicts.
//
// ══════════════════════════════════════════════════════════════════════════════════════
// ──────────────────────────────────────────────────────────────────────────────────────
// EDITOR SETTINGS - Visual appearance and behaviour
// ──────────────────────────────────────────────────────────────────────────────────────
"editor.lineNumbers": "relative", // Relative line numbers (Vim-style)
"editor.scrollBeyondLastLine": false, // Don't scroll past end of file
"editor.cursorSurroundingLines": 8, // Keep 8 lines above/below cursor (matches LazyVim scrolloff)
"editor.smoothScrolling": true, // Smooth scrolling animations
"editor.bracketPairColorization.enabled": true, // Colour matching brackets
"editor.guides.bracketPairs": true, // Show bracket pair guides
"editor.minimap.renderCharacters": false, // Simplified minimap
"editor.minimap.scale": 2, // Larger minimap scale
"editor.cursorBlinking": "solid", // Solid cursor (Vim-like)
"editor.formatOnSave": false, // Format on save (set to true if desired)
// ──────────────────────────────────────────────────────────────────────────────────────
// VIM EXTENSION CORE SETTINGS - Vim behaviour and plugin emulation
// ──────────────────────────────────────────────────────────────────────────────────────
"vim.leader": "<space>", // Space as leader key (LazyVim standard)
"vim.useSystemClipboard": true, // Use system clipboard for yank/paste
"vim.useCtrlKeys": true, // Enable Vim Ctrl key bindings
"vim.smartRelativeLine": true, // Absolute line numbers in insert mode
// Vim plugin emulations (built into VSCode Vim extension)
"vim.easymotion": true, // Enable EasyMotion (use <leader><leader>w etc)
"vim.sneak": true, // Enable vim-sneak (use s/S for 2-char search)
"vim.surround": true, // Enable vim-surround (ys/ds/cs commands)
"vim.foldfix": true, // Better folding support
// Search settings
"vim.incsearch": true, // Incremental search (show matches as you type)
"vim.hlsearch": true, // Highlight search results
"vim.searchHighlightColor": "rgba(180, 142, 173, 0.5)", // Search highlight colour
// Visual feedback
"vim.highlightedyank.enable": true, // Briefly highlight yanked text
"vim.highlightedyank.duration": 200, // Highlight duration in milliseconds
// ──────────────────────────────────────────────────────────────────────────────────────
// STATUS BAR COLORS - Visual mode indicators (LazyVim-inspired colours)
// ──────────────────────────────────────────────────────────────────────────────────────
"vim.statusBarColorControl": true, // Enable status bar colour changes
"vim.statusBarColors.normal": "#519aba", // Blue for normal mode
"vim.statusBarColors.insert": "#98c379", // Green for insert mode
"vim.statusBarColors.visual": "#c678dd", // Purple for visual mode
"vim.statusBarColors.visualline": "#c678dd", // Purple for visual line mode
"vim.statusBarColors.visualblock": "#c678dd", // Purple for visual block mode
"vim.statusBarColors.replace": "#e06c75", // Red for replace mode
// ──────────────────────────────────────────────────────────────────────────────────────
// HANDLE KEYS - Which keys are processed by Vim vs VSCode
// ──────────────────────────────────────────────────────────────────────────────────────
//
// IMPORTANT: This section determines whether a key combination is handled by the Vim
// extension (true) or passed to VSCode (false). This prevents conflicts between Vim
// commands and VSCode shortcuts.
//
// - true = Vim extension handles the key (e.g., <C-d> for page down in Vim)
// - false = VSCode handles the key (e.g., <C-f> for native find dialogue)
//
"vim.handleKeys": {
"<C-d>": true, // Vim page down (half-page scroll)
"<C-u>": true, // Vim page up (half-page scroll)
"<C-f>": false, // VSCode find (don't override with Vim's full page down)
"<C-b>": false, // VSCode sidebar toggle (don't override with Vim's page up)
"<C-h>": false, // VSCode window navigation (defined in keybindings.json)
"<C-j>": false, // VSCode window navigation (defined in keybindings.json)
"<C-k>": false, // VSCode window navigation (defined in keybindings.json)
"<C-l>": false, // VSCode window navigation (defined in keybindings.json)
"<C-w>": false, // VSCode close tab (don't override Vim's window commands)
"<C-s>": false, // VSCode save file (standard shortcut)
"<C-a>": false, // VSCode select all (standard shortcut)
"<C-c>": false, // VSCode copy (standard shortcut)
"<C-v>": false, // VSCode paste (standard shortcut)
"<C-z>": false // VSCode undo (standard shortcut)
},
// ──────────────────────────────────────────────────────────────────────────────────────
// INSERT MODE KEYBINDINGS - Escape alternatives
// ──────────────────────────────────────────────────────────────────────────────────────
"vim.insertModeKeyBindings": [
{
"before": ["j", "k"], // jk to escape (LazyVim default)
"after": ["<Esc>"]
},
{
"before": ["j", "j"], // jj to escape (alternative)
"after": ["<Esc>"]
}
],
// ──────────────────────────────────────────────────────────────────────────────────────
// NORMAL MODE KEYBINDINGS - Space-leader mappings (LazyVim alignment)
// ──────────────────────────────────────────────────────────────────────────────────────
//
// CRITICAL: All space-leader bindings (<leader>...) MUST be defined here in settings.json,
// NOT in keybindings.json. The Vim extension needs to intercept these before VSCode sees them.
//
// Pattern reference (matches LazyVim):
// <leader>f* = File operations
// <leader>s* = Search operations
// <leader>c* = Code actions (LSP)
// <leader>b* = Buffer management
// <leader>g* = Git operations
// <leader>w* = Window management
// <leader>x* = Diagnostics/Quickfix
// <leader>u* = UI toggles
//
"vim.normalModeKeyBindingsNonRecursive": [
// ┌────────────────────────────────────────────────────────────────────────────────┐
// │ GENERAL UTILITY MAPPINGS │
// └────────────────────────────────────────────────────────────────────────────────┘
{
"before": ["<leader>", "d"], // <leader>d = delete line (dd shortcut)
"after": ["d", "d"]
},
{
"before": ["<Esc>"], // Escape clears search highlight
"commands": [":nohl"]
},
{
"before": ["<leader>", "u", "r"], // <leader>ur = clear search (LazyVim "unredraw")
"commands": [":nohl"]
},
{
"before": ["<C-n>"], // Ctrl+n also clears search highlight
"commands": [":nohl"]
},
{
"before": ["K"], // K = show hover documentation (LSP)
"commands": ["editor.action.showHover"]
},
// ┌────────────────────────────────────────────────────────────────────────────────┐
// │ FILE OPERATIONS - <leader>f* prefix │
// └────────────────────────────────────────────────────────────────────────────────┘
//
// LazyVim file operations pattern for finding, creating, and managing files
//
{
"before": ["<leader>", "<space>"], // <leader><space> = find files (Quick Open)
"commands": ["workbench.action.quickOpen"]
},
{
"before": ["<leader>", ","], // <leader>, = switch buffer (Quick Open Editors)
"commands": ["workbench.action.showAllEditors"]
},
{
"before": ["<leader>", "/"], // <leader>/ = search in files (Live Grep equivalent)
"commands": ["workbench.action.findInFiles"]
},
{
"before": ["<leader>", "f", "f"], // <leader>ff = find files (same as <leader><space>)
"commands": ["workbench.action.quickOpen"]
},
{
"before": ["<leader>", "f", "r"], // <leader>fr = recent files
"commands": ["workbench.action.openRecent"]
},
{
"before": ["<leader>", "f", "n"], // <leader>fn = new file
"commands": ["workbench.action.files.newUntitledFile"]
},
{
"before": ["<leader>", "f", "b"], // <leader>fb = buffers (open editors)
"commands": ["workbench.action.showAllEditors"]
},
{
"before": ["<leader>", "f", "e"], // <leader>fe = file explorer (reveal active file)
"commands": ["workbench.files.action.showActiveFileInExplorer"]
},
{
"before": ["<leader>", "f", "t"], // <leader>ft = toggle terminal
"commands": ["workbench.action.terminal.toggleTerminal"]
},
{
"before": ["<leader>", "e"], // <leader>e = toggle sidebar
"commands": ["workbench.action.toggleSidebarVisibility"]
},
{
"before": ["<leader>", "E"], // <leader>E = focus file explorer
"commands": ["workbench.files.action.focusFilesExplorer"]
},
// ┌────────────────────────────────────────────────────────────────────────────────┐
// │ SEARCH OPERATIONS - <leader>s* prefix │
// └────────────────────────────────────────────────────────────────────────────────┘
//
// LazyVim search operations for finding text, symbols, and configuration
//
{
"before": ["<leader>", "s", "g"], // <leader>sg = grep/search in files
"commands": ["workbench.action.findInFiles"]
},
{
"before": ["<leader>", "s", "w"], // <leader>sw = search word under cursor
"commands": ["workbench.action.findInFiles"]
},
{
"before": ["<leader>", "s", "r"], // <leader>sr = search and replace in files
"commands": ["workbench.action.replaceInFiles"]
},
{
"before": ["<leader>", "s", "s"], // <leader>ss = goto symbol in file
"commands": ["workbench.action.gotoSymbol"]
},
{
"before": ["<leader>", "s", "S"], // <leader>sS = goto symbol in workspace
"commands": ["workbench.action.showAllSymbols"]
},
{
"before": ["<leader>", "s", "k"], // <leader>sk = keymaps (open keyboard shortcuts)
"commands": ["workbench.action.openGlobalKeybindings"]
},
{
"before": ["<leader>", "s", "c"], // <leader>sc = command palette
"commands": ["workbench.action.showCommands"]
},
{
"before": ["<leader>", "s", "h"], // <leader>sh = help (all commands)
"commands": ["workbench.action.showAllCommands"]
},
// ┌────────────────────────────────────────────────────────────────────────────────┐
// │ CODE ACTIONS - <leader>c* prefix (LSP operations) │
// └────────────────────────────────────────────────────────────────────────────────┘
//
// LazyVim code actions for LSP features like formatting, refactoring, diagnostics
//
{
"before": ["<leader>", "c", "a"], // <leader>ca = code action (quick fix)
"commands": ["editor.action.quickFix"]
},
{
"before": ["<leader>", "c", "A"], // <leader>cA = source action
"commands": ["editor.action.sourceAction"]
},
{
"before": ["<leader>", "c", "f"], // <leader>cf = format document
"commands": ["editor.action.formatDocument"]
},
{
"before": ["<leader>", "c", "F"], // <leader>cF = format selection
"commands": ["editor.action.formatSelection"]
},
{
"before": ["<leader>", "c", "r"], // <leader>cr = rename symbol
"commands": ["editor.action.rename"]
},
{
"before": ["<leader>", "c", "d"], // <leader>cd = line diagnostics (hover)
"commands": ["editor.action.showHover"]
},
{
"before": ["<leader>", "c", "l"], // <leader>cl = open problems panel
"commands": ["workbench.action.problems.focus"]
},
{
"before": ["<leader>", "c", "o"], // <leader>co = organise imports
"commands": ["editor.action.organizeImports"]
},
// ┌────────────────────────────────────────────────────────────────────────────────┐
// │ LSP NAVIGATION - g* prefix (goto definitions, references, etc.) │
// └────────────────────────────────────────────────────────────────────────────────┘
//
// Standard Vim LSP navigation bindings (matches LazyVim defaults)
//
{
"before": ["g", "d"], // gd = goto definition
"commands": ["editor.action.revealDefinition"]
},
{
"before": ["g", "D"], // gD = goto declaration
"commands": ["editor.action.revealDeclaration"]
},
{
"before": ["g", "r"], // gr = goto references
"commands": ["editor.action.goToReferences"]
},
{
"before": ["g", "I"], // gI = goto implementation
"commands": ["editor.action.goToImplementation"]
},
{
"before": ["g", "y"], // gy = goto type definition
"commands": ["editor.action.goToTypeDefinition"]
},
{
"before": ["g", "K"], // gK = signature help (parameter hints)
"commands": ["editor.action.triggerParameterHints"]
},
// ┌────────────────────────────────────────────────────────────────────────────────┐
// │ BUFFER MANAGEMENT - <leader>b* prefix │
// └────────────────────────────────────────────────────────────────────────────────┘
//
// LazyVim buffer operations for managing open files/tabs
//
{
"before": ["<leader>", "b", "b"], // <leader>bb = switch buffer (show all editors)
"commands": ["workbench.action.showAllEditors"]
},
{
"before": ["<leader>", "b", "d"], // <leader>bd = delete buffer (close tab)
"commands": ["workbench.action.closeActiveEditor"]
},
{
"before": ["<leader>", "b", "D"], // <leader>bD = delete other buffers
"commands": ["workbench.action.closeOtherEditors"]
},
{
"before": ["<leader>", "b", "o"], // <leader>bo = close other editors (same as bD)
"commands": ["workbench.action.closeOtherEditors"]
},
{
"before": ["<leader>", "b", "p"], // <leader>bp = pin buffer (pin tab)
"commands": ["workbench.action.pinEditor"]
},
{
"before": ["<leader>", "b", "P"], // <leader>bP = unpin buffer
"commands": ["workbench.action.unpinEditor"]
},
{
"before": ["<leader>", "`"], // <leader>` = last buffer (alternate file)
"commands": ["workbench.action.quickOpenPreviousRecentlyUsedEditorInGroup"]
},
{
"before": ["<S-h>"], // Shift+h = previous buffer
"commands": [":bprev"]
},
{
"before": ["<S-l>"], // Shift+l = next buffer
"commands": [":bnext"]
},
// ┌────────────────────────────────────────────────────────────────────────────────┐
// │ GIT OPERATIONS - <leader>g* prefix (requires GitLens extension) │
// └────────────────────────────────────────────────────────────────────────────────┘
//
// LazyVim git operations. Most features require GitLens extension for full functionality.
// Without GitLens, basic git commands (gg, gs, gd) still work with native VSCode git.
//
{
"before": ["<leader>", "g", "g"], // <leader>gg = git status (open source control)
"commands": ["workbench.view.scm"]
},
{
"before": ["<leader>", "g", "s"], // <leader>gs = git status (same as gg)
"commands": ["workbench.view.scm"]
},
{
"before": ["<leader>", "g", "b"], // <leader>gb = git blame toggle (GitLens)
"commands": ["gitlens.toggleFileBlame"]
},
{
"before": ["<leader>", "g", "B"], // <leader>gB = git browse (open on remote - GitLens)
"commands": ["gitlens.openFileOnRemote"]
},
{
"before": ["<leader>", "g", "d"], // <leader>gd = git diff (show changes)
"commands": ["git.openChange"]
},
{
"before": ["<leader>", "g", "l"], // <leader>gl = git log (file history - GitLens)
"commands": ["gitlens.showQuickFileHistory"]
},
{
"before": ["<leader>", "g", "L"], // <leader>gL = git log (branch history - GitLens)
"commands": ["gitlens.showQuickRepoHistory"]
},
{
"before": ["<leader>", "g", "c"], // <leader>gc = git commits (show commit details - GitLens)
"commands": ["gitlens.showQuickCommitDetails"]
},
// ┌────────────────────────────────────────────────────────────────────────────────┐
// │ WINDOW MANAGEMENT - <leader>w* and <leader>-/| prefix │
// └────────────────────────────────────────────────────────────────────────────────┘
//
// LazyVim window/split operations
//
{
"before": ["<leader>", "w", "d"], // <leader>wd = close window (close split/editor)
"commands": ["workbench.action.closeActiveEditor"]
},
{
"before": ["<leader>", "w", "w"], // <leader>ww = switch window (focus other group)
"commands": ["workbench.action.focusNextGroup"]
},
{
"before": ["<leader>", "w", "m"], // <leader>wm = maximise window (toggle editor width)
"commands": ["workbench.action.toggleEditorWidths"]
},
{
"before": ["<leader>", "-"], // <leader>- = split window below
"commands": ["workbench.action.splitEditorDown"]
},
{
"before": ["<leader>", "|"], // <leader>| = split window right
"commands": ["workbench.action.splitEditorRight"]
},
// ┌────────────────────────────────────────────────────────────────────────────────┐
// │ DIAGNOSTICS/QUICKFIX - <leader>x* prefix and [ ] navigation │
// └────────────────────────────────────────────────────────────────────────────────┘
//
// LazyVim diagnostics and error navigation. Bracket prefix mappings ([d, ]d) are
// defined in keybindings.json because they use special key codes (oem_4, oem_6).
//
{
"before": ["<leader>", "x", "x"], // <leader>xx = diagnostics list (problems panel)
"commands": ["workbench.action.problems.focus"]
},
{
"before": ["<leader>", "x", "X"], // <leader>xX = workspace diagnostics
"commands": ["workbench.actions.view.problems"]
},
{
"before": ["<leader>", "x", "l"], // <leader>xl = location list (same as xx)
"commands": ["workbench.action.problems.focus"]
},
// Note: [d, ]d, [e, ]e navigation defined in keybindings.json
// ┌────────────────────────────────────────────────────────────────────────────────┐
// │ UI TOGGLES - <leader>u* prefix │
// └────────────────────────────────────────────────────────────────────────────────┘
//
// LazyVim UI toggle operations. Line number toggling requires Settings Cycler extension.
// Install: hoovercj.vscode-settings-cycler
// Configure settings.cycle in this file (see bottom section).
//
{
"before": ["<leader>", "u", "w"], // <leader>uw = toggle word wrap
"commands": ["editor.action.toggleWordWrap"]
},
{
"before": ["<leader>", "u", "z"], // <leader>uz = toggle zen mode
"commands": ["workbench.action.toggleZenMode"]
},
{
"before": ["<leader>", "u", "r"], // <leader>ur = redraw/clear search
"commands": [":nohl"]
},
// Requires Settings Cycler extension - uncomment after installing:
// {
// "before": ["<leader>", "u", "l"], // <leader>ul = toggle line numbers
// "commands": ["settings.cycle.lineNumbers"]
// },
// {
// "before": ["<leader>", "u", "L"], // <leader>uL = toggle relative numbers
// "commands": ["settings.cycle.relativeLineNumbers"]
// },
// ┌────────────────────────────────────────────────────────────────────────────────┐
// │ QUIT - <leader>q* prefix │
// └────────────────────────────────────────────────────────────────────────────────┘
{
"before": ["<leader>", "q", "q"], // <leader>qq = quit VSCode
"commands": ["workbench.action.closeWindow"]
},
{
"before": ["<leader>", "q", "a"], // <leader>qa = quit all windows
"commands": ["workbench.action.quit"]
}
],
// ──────────────────────────────────────────────────────────────────────────────────────
// VISUAL MODE KEYBINDINGS - Selection operations
// ──────────────────────────────────────────────────────────────────────────────────────
//
// Visual mode enhancements for better selection handling and LazyVim parity
//
"vim.visualModeKeyBindings": [
{
"before": ["<"], // < = indent left and reselect
"after": ["<", "g", "v"] // The 'gv' reselects the previous visual selection
},
{
"before": [">"], // > = indent right and reselect
"after": [">", "g", "v"]
},
{
"before": ["<leader>", "/"], // <leader>/ = search selected text
"commands": ["workbench.action.findInFiles"]
},
{
"before": ["<leader>", "c", "a"], // <leader>ca = code action on selection
"commands": ["editor.action.quickFix"]
},
{
"before": ["<leader>", "c", "f"], // <leader>cf = format selection
"commands": ["editor.action.formatSelection"]
},
{
"before": ["g", "c"], // gc = comment toggle
"commands": ["editor.action.commentLine"]
}
],
// ──────────────────────────────────────────────────────────────────────────────────────
// SETTINGS CYCLER CONFIGURATION (requires hoovercj.vscode-settings-cycler extension)
// ──────────────────────────────────────────────────────────────────────────────────────
//
// This provides LazyVim-style line number toggling with <leader>ul and <leader>uL.
// Install the extension, then uncomment the keybindings above in the UI TOGGLES section.
//
// "settings.cycle": [
// {
// "id": "lineNumbers",
// "values": [
// { "editor.lineNumbers": "on" }, // Absolute line numbers
// { "editor.lineNumbers": "relative" }, // Relative line numbers
// { "editor.lineNumbers": "off" } // No line numbers
// ]
// },
// {
// "id": "relativeLineNumbers",
// "values": [
// { "editor.lineNumbers": "relative" }, // Toggle between relative
// { "editor.lineNumbers": "on" } // and absolute only
// ]
// }
// ],
// ──────────────────────────────────────────────────────────────────────────────────────
// PERFORMANCE OPTIMISATION - CRITICAL for responsive typing
// ──────────────────────────────────────────────────────────────────────────────────────
//
// This runs the Vim extension in a dedicated thread to prevent typing lag and cursor
// delays. This is ESSENTIAL for a good Vim experience in VSCode.
//
"extensions.experimental.affinity": {
"vscodevim.vim": 1
}
// ──────────────────────────────────────────────────────────────────────────────────────
// ADDITIONAL NOTES AND TROUBLESHOOTING
// ──────────────────────────────────────────────────────────────────────────────────────
//
// MACOS USERS: Enable key repeat for hjkl navigation
// Run in terminal: defaults write com.microsoft.VSCode ApplePressAndHoldEnabled -bool false
// Then restart VSCode.
//
// COMMON ISSUES:
//
// 1. Leader key not working:
// - Ensure "vim.leader": "<space>" is set
// - Verify bindings are in settings.json, NOT keybindings.json
// - Check no other extension is capturing space key
//
// 2. Typing lag or cursor delay:
// - Ensure extensions.experimental.affinity is set (see above)
// - Disable unused extensions
// - Check CPU usage in Task Manager
//
// 3. GitLens commands not working:
// - Install GitLens extension: eamodio.gitlens
// - Some commands are only available in git repositories
//
// 4. Bracket navigation ([d, ]d) not working:
// - These are defined in keybindings.json
// - Check your keybindings.json file is configured correctly
//
// 5. Line number toggle not working:
// - Install Settings Cycler: hoovercj.vscode-settings-cycler
// - Uncomment the settings.cycle section above
// - Uncomment the <leader>ul keybindings in UI TOGGLES section
//
// VALIDATION CHECKLIST:
// □ Space key triggers leader (doesn't move cursor)
// □ <leader>ff opens file picker
// □ <leader>/ searches in files
// □ gd navigates to definition
// □ K shows hover
// □ <leader>ca shows code actions
// □ Shift+H/L switches buffers
// □ No typing lag or cursor delays
//
// ══════════════════════════════════════════════════════════════════════════════════════
}

Changelog

[Migration Notice] - 2026-01

This gist is now synced with VimCode Repository 🚀

What Changed

  • Gist = Quick Start version of VimCode (copy-paste ready)
  • Repository = Full version with 50+ keybindings, docs, multi-editor support
  • Synced configurations - gist matches repo's core config
  • Easy upgrade path - start here, upgrade to full repo when ready

Why Upgrade to VimCode Repository?

  • 50+ keybindings vs ~20 in this gist
  • LazyVim conventions - complete implementation
  • Multi-editor support - VS Code, Cursor, Windsurf
  • Comprehensive docs - SETUP.md, KEYBINDINGS.md, TROUBLESHOOTING.md, TIPS_AND_TRICKS.md
  • Active community - Issues, Discussions, regular updates
  • Better organization - Logical file structure and documentation

Migration Path

  1. ✅ Use this gist for quick 5-minute setup
  2. 📖 Read VimCode docs
  3. ⭐ Star the repository
  4. 🔧 Upgrade to full config when you want more features

[2.0.0] - 2026-01-17 (Synced with VimCode v2.0.0)

This version syncs with VimCode Repository v2.0.0

Added

  • Enhanced Git integration
    • Pull command: <leader>gp
    • Push command: <leader>gP
    • File history: <leader>gh
  • New navigation shortcuts
    • Method boundaries: [m, ]m
    • Error navigation: [d, ]d
    • Definition jumping: ctrl+], ctrl+t
  • Split management
    • Resize shortcuts: alt+h, alt+l
    • Maximize toggle: ctrl+w m
    • Equal sizing: <C-w>=
  • Code folding commands
    • Fold: <leader>z
    • Unfold: <leader>Z
  • Tab navigation
    • Previous/Next: alt+[, alt+]
  • Workspace management
    • Close workspace: ctrl+shift+w
    • Copy file path: ctrl+k p
  • Enhanced panel navigation
    • Consistent ctrl+j/k in all panels
    • Improved terminal focus controls

Changed

  • Standardized sidebar toggling to use <leader>e
  • Improved comments and documentation
  • Reorganized keybindings into logical groups
  • Synced with VimCode repository structure

Fixed

  • Removed redundant keybindings
  • Standardized leader key usage
  • Improved context awareness for shortcuts

👉 For full changelog and latest updates, see VimCode CHANGELOG.md


[1.0.0] - 2025-01-22 (Gist-only release)

Added

  • Enhanced Git integration
    • Pull command: <leader>g p
    • Push command: <leader>g P
    • File history: <leader>g h
  • New navigation shortcuts
    • Method boundaries: [m, ]m
    • Error navigation: [d, ]d
    • Definition jumping: ctrl+], ctrl+t
  • Split management
    • Resize shortcuts: alt+h, alt+l
    • Maximize toggle: ctrl+w m
    • Equal sizing: <C-w>=
  • Code folding commands
    • Fold: <leader>z
    • Unfold: <leader>Z
  • Tab navigation
    • Previous/Next: alt+[, alt+]
  • Workspace management
    • Close workspace: ctrl+shift+w
    • Copy file path: ctrl+k p
  • Enhanced panel navigation
    • Consistent ctrl+j/k in all panels
    • Improved terminal focus controls

Changed

  • Standardized sidebar toggling to use <leader>e
  • Improved comments and documentation
  • Reorganized keybindings into logical groups

Fixed

  • Removed redundant keybindings
  • Standardized leader key usage
  • Improved context awareness for shortcuts

[0.1.0] - Initial Release

Added

  • Basic Vim keybindings
  • File explorer integration
  • Terminal shortcuts
  • Basic Git commands
  • Split navigation

Maintenance Notes

Gist Update Schedule:

  • This gist is updated when VimCode repository has major releases
  • For latest features and bug fixes, use the VimCode repository
  • Gist focuses on core, stable features for quick setup

Want to Contribute?

VS Code + Vim Keybindings - Quick Start ⚡

🚀 This gist is synced with VimCode v2.0.0 - same configs, streamlined docs!

💡 Want more? The VimCode repository adds comprehensive documentation, troubleshooting guides, tips & tricks, and multi-editor support (Cursor, Windsurf).

Star VimCode on GitHub | 📖 Full Docs | 🔧 Advanced Setup


About This Gist

This is a copy-paste ready Vim configuration for VS Code featuring:

Same configs as VimCode repository - keybindings.json and settings.json are identical
50+ LazyVim-inspired keybindings - Organized by prefix (<leader>f*, <leader>s*, etc.)
Full LSP integration - Code navigation, formatting, refactoring
Git operations - Powered by GitLens
5-minute setup - Copy, paste, reload, done!

Gist vs Repository - What's the Difference?

Feature This Gist VimCode Repository
Config files ✅ Same (synced) ✅ Same
Keybindings ✅ 50+ (identical) ✅ 50+ (identical)
Setup guide ⚡ Quick (5-min) 📚 Comprehensive
Documentation 📄 This README 📖 5 detailed guides
Troubleshooting ❌ Link to repo ✅ Full guide
Tips & tricks ❌ Link to repo ✅ Power user workflows
Multi-editor 💻 VS Code only 💻 VS Code + Cursor + Windsurf
Community ✅ Issues, Discussions, PRs
Updates 📅 Major releases 🔄 Active development

TL;DR: Same powerful configs, choose based on how much documentation you want!


5-Minute Setup

1. Install Required Extensions

# Essential (required)
code --install-extension vscodevim.vim
 
# Recommended (for full functionality)
code --install-extension eamodio.gitlens
code --install-extension ryuta46.multi-command

2. Copy Configuration Files

Copy settings.json and keybindings.json from this gist to your VS Code user directory:

macOS:

~/.config/Code/User/settings.json
~/.config/Code/User/keybindings.json

Linux:

~/.config/Code/User/settings.json
~/.config/Code/User/keybindings.json

Windows:

%APPDATA%\Code\User\settings.json
%APPDATA%\Code\User\keybindings.json

💡 Tip: If you already have custom configs, consider backing them up first!

3. Reload VS Code

Press Cmd/Ctrl + Shift + P → Type "Reload Window" → Enter

Done! 🎉 Try pressing <space> (leader key) to see available commands.


Essential Keybindings

Leader key: <space>

🗂️ File Operations

Keybinding Action
<leader>ff Find files
<leader>fg Find in files (grep)
<leader>fr Recent files
<leader>fb Find buffers
<leader>w Save file
<leader>q Close file

🔍 Search Operations

Keybinding Action
<leader>sg Search with grep
<leader>sw Search word under cursor
<leader>/ Search in current file

⚙️ Code Actions

Keybinding Action
gd Go to definition
gr Find references
<leader>ca Code actions
<leader>rn Rename symbol
<leader>cf Format code

🌳 Git Operations

Keybinding Action
<leader>gg Open Git panel
<leader>gb Git blame
<leader>gd Git diff
<leader>gp Git pull
<leader>gP Git push

🪟 Window Management

Keybinding Action
Ctrl+h/j/k/l Navigate splits
<leader>wv Vertical split
<leader>ws Horizontal split
<leader>wc Close window
<leader>wm Maximize toggle

🎯 UI Toggles

Keybinding Action
<leader>e Toggle file explorer
<leader>uf Toggle format on save
<leader>ul Toggle line numbers

👉 Complete reference: VimCode Keybindings Guide (all 50+ shortcuts with categories)


Quick Troubleshooting

Problem: Keybindings Don't Work

Solution:

  1. Verify VSCodeVim extension is installed: code --list-extensions | grep vim
  2. Check extension is enabled: Extensions panel → VSCodeVim → Make sure it's not disabled
  3. Reload VS Code: Cmd/Ctrl + Shift + P → "Reload Window"

Still not working? See the full troubleshooting guide

Problem: Conflicts with Existing Keybindings

Solution:

  1. Open Keyboard Shortcuts: Cmd/Ctrl + K, Cmd/Ctrl + S
  2. Search for the conflicting keybinding
  3. Right-click conflicting entry → "Remove Keybinding"

Need help resolving conflicts? Check the keybinding conflicts guide

Problem: Some Features Missing

Possible causes:

  • GitLens extension not installed (for Git features)
  • Multi-command extension not installed (for complex commands)

Solution: Install recommended extensions (see Setup step 1 above)


Files in This Gist

File Purpose Synced with Repo?
README.md This file - setup guide ✅ Optimized for quick start
settings.json VS Code settings + Vim config ✅ Identical to repo
keybindings.json All 50+ keyboard shortcuts ✅ Identical to repo
CHANGELOG.md Version history ✅ Summarized from repo

Why Upgrade to VimCode Repository?

You're Happy with This Gist If:

  • ✅ 5-minute setup is all you need
  • ✅ Configs are working great
  • ✅ You don't need troubleshooting help
  • ✅ You only use VS Code (not Cursor/Windsurf)

Upgrade to VimCode Repository If:

  • 📚 You want comprehensive documentation (SETUP.md, KEYBINDINGS.md, etc.)
  • 🐛 You need troubleshooting help (common issues, solutions)
  • 💡 You want tips & tricks (power user workflows, best practices)
  • 🎯 You use Cursor or Windsurf (multi-editor configurations)
  • 👥 You want community support (issues, discussions)
  • 🔄 You want latest updates (active development)
  • 🤝 You want to contribute (PRs welcome!)

Next Steps

1. Try It Out (5 min)

  • Open a file and try <leader>ff to find files
  • Navigate splits with Ctrl+h/j/k/l
  • Try code actions with <leader>ca
  • Use Git blame with <leader>gb

2. Learn More (15 min)

3. Get Involved (optional)


Related Resources

VimCode Documentation

Getting Help

External Resources


Sync Status

Last synced with VimCode: v2.0.0 (2026-01-17)

What this means:

  • ✅ Configs in this gist match VimCode repository v2.0.0
  • ✅ You have all 50+ keybindings from the repo
  • ✅ Future major releases will be synced here
  • 📅 This gist updates every major release (v3.0.0, v4.0.0, etc.)

Want bleeding edge? Use the VimCode repository directly!


Contributing

Found a bug? Want to suggest an improvement?

  1. 🐛 Report bugs
  2. 💡 Request features
  3. ⌨️ Report keybinding conflicts
  4. 🤝 Submit pull requests

All contributions go through the VimCode repository!


License

MIT License - Free to use and modify

See LICENSE in the VimCode repository.


Keep in Touch


⭐ If you find this useful, please star VimCode on GitHub!

🚀 Ready for the full experience? Visit VimCode Repository for comprehensive docs, troubleshooting, community support, and multi-editor configurations!

@odezzshuuk
Copy link

  // ┌────────────────────────────────────────────────────────────────────────────────────┐
  // │ BUFFER NAVIGATION - Shift+h/l (LazyVim: <S-h>, <S-l>)                              │
  // └────────────────────────────────────────────────────────────────────────────────────┘
  //
  // Switch between open editor tabs using Shift+H (previous) and Shift+L (next).
  // Only active in Normal/Visual modes to avoid conflicts with text selection.
  // Alternative: Use [b and ]b (defined below) for the same functionality.
  //
  {
    "key": "shift+h",
    "command": "workbench.action.previousEditor",
    "when": "vim.active && vim.mode != 'Insert' && editorFocus"
  },
  {
    "key": "shift+l",
    "command": "workbench.action.nextEditor",
    "when": "vim.active && vim.mode != 'Insert' && editorFocus"
  },

I add editorFocus to buffer navigation when-expression to avoid tab switch when typing "L", "H" in copilot chat.

@wojukasz
Copy link
Author

Brilliant @odezzshuuk , I encountered that last week just didn't got around to fixing it, thanks will try it out coming week and update accordingly.

@shanksxz
Copy link

shanksxz commented Feb 1, 2026

can't i navigate btw file explorer and the file with ctrl h,l

@wojukasz
Copy link
Author

wojukasz commented Feb 6, 2026

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment