Cheatsheet

VS Code shortcuts grouped by what you are doing

Windows and Linux keys in the first column, macOS in the second, grouped by task rather than by menu. Multi-cursor and the command palette are worth more than every other shortcut on this page combined, so they come first. The settings section at the end is the other half of the speed story: a dozen lines of JSON that remove more friction than any keybinding.

Command palette and navigation

If you learn one shortcut, learn the palette. Every command in the editor is in there, including the ones that have no keybinding, and it shows you the binding for the ones that do.

Windows and Linux macOS What it does
Ctrl+Shift+P Cmd+Shift+P Command palette. Fuzzy search every command the editor and its extensions expose.
Ctrl+P Cmd+P Quick open by filename. Fuzzy matches path segments, so "sr/co/bu" finds the file.
Ctrl+P then @ Cmd+P then @ Jump to a symbol in the current file. Add a colon to group by kind.
Ctrl+T Cmd+T Symbol search across the whole workspace, not just the open file.
Ctrl+G Ctrl+G Go to line number. Same as typing a colon in quick open.
F12 F12 Go to definition. Ctrl+Click does the same with the mouse.
Alt+F12 Opt+F12 Peek definition inline without leaving the file you are reading.
Shift+F12 Shift+F12 Find all references to the symbol under the cursor.
Ctrl+F12 Cmd+F12 Go to implementation. The one that matters in an interface-heavy codebase.
Alt+Left Ctrl+- Navigate back through your cursor history. The undo button for jumping around.
Alt+Right Ctrl+Shift+- Navigate forward again.
Ctrl+Tab Ctrl+Tab Cycle open editors in most-recently-used order. Hold to pick from the list.
Ctrl+B Cmd+B Toggle the sidebar. Instantly reclaims 300px on a laptop.
Ctrl+\ Cmd+\ Split the editor. Ctrl+1, Ctrl+2, Ctrl+3 then focus each group.
Ctrl+W Cmd+W Close the current editor tab.
Ctrl+Shift+T Cmd+Shift+T Reopen the editor you just closed by accident.
Ctrl+K Z Cmd+K Z Zen mode. Everything disappears except the code. Escape twice to leave.
Ctrl+Shift+E Cmd+Shift+E Focus the file explorer. Press it again to focus back on the editor.
Ctrl+, Cmd+, Open settings. Ctrl+K Ctrl+S opens the keyboard shortcut editor instead.

Gotcha: quick open is not just a file picker. Prefix your query with @ for symbols, # for workspace symbols, : for a line number, > for commands, and ? to see the whole list.

Multi-cursor and selection

This is the group that replaces a regex find-and-replace most of the time, and it is far less risky because you can see every edit as you make it.

Windows and Linux macOS What it does
Ctrl+D Cmd+D Select the word, then press again to add the next occurrence as a new cursor.
Ctrl+K Ctrl+D Cmd+K Cmd+D Skip this occurrence and move the selection to the next one.
Ctrl+Shift+L Cmd+Shift+L Select every occurrence in the file at once. The rename-without-a-language-server move.
Ctrl+F2 Cmd+F2 Same thing for the word under the cursor, without selecting it first.
Ctrl+Alt+Up Cmd+Opt+Up Add a cursor on the line above. Down arrow for below.
Alt+Click Opt+Click Drop a cursor anywhere. Works as many times as you like.
Shift+Alt+drag Shift+Opt+drag Column selection. Editing a block of aligned text becomes one edit.
Ctrl+Shift+Alt+Arrow Shift+Opt+Cmd+Arrow Column selection from the keyboard, no mouse required.
Shift+Alt+Right Ctrl+Shift+Cmd+Right Expand selection outward by syntax: word, then expression, then block.
Shift+Alt+Left Ctrl+Shift+Cmd+Left Shrink the selection back one syntax level.
Ctrl+L Cmd+L Select the whole line, then press again for the next line.
Ctrl+U Cmd+U Undo the last cursor operation. The escape hatch when Ctrl+D goes one too far.
Escape Escape Collapse every cursor back to one.

Gotcha: with several cursors active, Home, End, and the word-jump keys all move independently on each line. That is what makes multi-cursor useful on lines of different lengths, and what makes a stray arrow key so confusing.

Editing and refactoring

Windows and Linux macOS What it does
Alt+Up / Alt+Down Opt+Up / Opt+Down Move the current line or selection up and down. Auto-reindents as it goes.
Shift+Alt+Up / Down Shift+Opt+Up / Down Duplicate the line or selection above or below.
Ctrl+Shift+K Cmd+Shift+K Delete the whole line, no selection required.
Ctrl+Enter Cmd+Enter Open a new line below, wherever the cursor sits on the current line.
Ctrl+Shift+Enter Cmd+Shift+Enter Open a new line above.
Ctrl+/ Cmd+/ Toggle a line comment. Works on a multi-line selection too.
Shift+Alt+A Shift+Opt+A Toggle a block comment around the selection.
F2 F2 Rename a symbol everywhere in the project, using the language server rather than text matching.
Ctrl+. Cmd+. Quick fix and code actions: add the import, fix the lint error, extract to a function.
Ctrl+Shift+R Ctrl+Shift+R Refactor menu only: extract method, extract variable, move to a new file.
Shift+Alt+F Shift+Opt+F Format the document with the configured formatter.
Ctrl+K Ctrl+F Cmd+K Cmd+F Format only the selection. Useful in a file you do not want to churn.
Ctrl+] / Ctrl+[ Cmd+] / Cmd+[ Indent and outdent the current line or selection.
Ctrl+Space Ctrl+Space Force the suggestion widget open, even mid-word.
Ctrl+Shift+Space Cmd+Shift+Space Show parameter hints for the call you are inside.
Ctrl+K Ctrl+I Cmd+K Cmd+I Show the hover tooltip at the keyboard cursor: type, docs, and signature.
Ctrl+K Ctrl+0 Cmd+K Cmd+0 Fold every region. Ctrl+K Ctrl+J unfolds everything again.
Ctrl+Shift+[ / ] Cmd+Opt+[ / ] Fold and unfold the region under the cursor only.
Alt+Z Opt+Z Toggle word wrap for this editor only.
Ctrl+K Ctrl+X Cmd+K Cmd+X Trim trailing whitespace across the file.

Gotcha: F2 rename and Ctrl+Shift+L look similar and are not. Rename understands scope, so a local variable named id is renamed only in its own function. Select-all-occurrences is pure text and will happily rewrite a string literal.

Search and replace

Windows and Linux macOS What it does
Ctrl+F Cmd+F Find in the current file. Selecting text first seeds the query.
Ctrl+H Cmd+Opt+F Replace in the current file.
Ctrl+Shift+F Cmd+Shift+F Search every file in the workspace, with include and exclude globs.
Ctrl+Shift+H Cmd+Shift+H Replace across every file. Always preview the diff before you accept it.
F3 / Shift+F3 Cmd+G / Cmd+Shift+G Next and previous match without reopening the find box.
Alt+Enter Opt+Enter In the find box: turn every match into a cursor. The bridge to multi-cursor.
Alt+R Cmd+Opt+R Toggle regex mode. Capture groups replace as $1, $2, and so on.
Alt+C Cmd+Opt+C Toggle case sensitivity.
Alt+W Cmd+Opt+W Toggle whole-word matching.
Ctrl+Alt+Enter Cmd+Opt+Enter Replace all matches in the current file.

Gotcha: workspace search honors .gitignore by default, so a hit inside dist/ or node_modules/ will not appear until you toggle the gear icon. That saves you most of the time and confuses you the rest.

Integrated terminal

Windows and Linux macOS What it does
Ctrl+` Ctrl+` Show or hide the terminal panel, keeping focus where you left it.
Ctrl+Shift+` Ctrl+Shift+` Create a new terminal instance rather than reusing the last one.
Ctrl+Shift+5 Cmd+\ Split the terminal so a dev server and a test watcher sit side by side.
Ctrl+Shift+P then "Terminal: Rename" Cmd+Shift+P Name each terminal so five open shells stay distinguishable.
Ctrl+Shift+P then "Terminal: Select Default Profile" Cmd+Shift+P Switch between PowerShell, Command Prompt, WSL, or a login shell.
Ctrl+Shift+M Cmd+Shift+M Jump to the Problems panel, where build and lint output is grouped by file.
Ctrl+Shift+U Cmd+Shift+U Open the Output panel, where extensions and language servers log.

Debugging

The function keys here are the same across every language extension, which is most of the reason to debug in the editor instead of a browser panel.

Windows and Linux macOS What it does
F5 F5 Start debugging, or continue when already paused.
Ctrl+F5 Ctrl+F5 Run without attaching the debugger. Faster when you only want the output.
Shift+F5 Shift+F5 Stop the session.
Ctrl+Shift+F5 Cmd+Shift+F5 Restart the session with the same configuration.
F9 F9 Toggle a breakpoint on the current line.
F10 F10 Step over: run the call and stop on the next line.
F11 F11 Step into the function being called.
Shift+F11 Shift+F11 Step out to the caller.
Ctrl+Shift+D Cmd+Shift+D Open the Run and Debug view to pick a launch configuration.
Ctrl+Shift+Y Cmd+Shift+Y Toggle the Debug Console, which is a live REPL in the paused scope.
Right-click the gutter Right-click the gutter Conditional breakpoint, hit count, or a logpoint that prints without stopping.

Gotcha: a logpoint is the underrated one. It prints an expression to the Debug Console every time the line runs and never pauses execution, which means you can instrument a running app without editing a single file or leaving a stray console statement in a commit.

Source control and diffs

Windows and Linux macOS What it does
Ctrl+Shift+G Ctrl+Shift+G Open the Source Control view with the staged and unstaged lists.
Ctrl+Enter Cmd+Enter Commit from the message box without touching the mouse.
Alt+F5 Opt+F5 Jump to the next change in a diff view. Shift+Alt+F5 goes back.
Ctrl+Shift+P then "Git: Stage Selected Ranges" Cmd+Shift+P The editor equivalent of git add -p: stage only the lines you selected.
Ctrl+Shift+P then "Git: Checkout to" Cmd+Shift+P Switch or create a branch with fuzzy search over every ref.
Ctrl+Shift+P then "Open Changes" Cmd+Shift+P Side-by-side diff of the open file against HEAD.
Ctrl+Shift+P then "Timeline" Cmd+Shift+P Per-file history combining git commits with local file saves.

The commands behind these are the same ones on the Git cheatsheet, which is worth having open the first time a merge conflict shows up in the diff editor.

Settings worth changing

Open the JSON directly with Ctrl+Shift+P then "Preferences: Open User Settings (JSON)". These are the entries that change how the editor feels rather than how it looks.

{
  // Formatting and lint on save - removes an entire class of review comment
  "editor.formatOnSave": true,
  "editor.defaultFormatter": "esbenp.prettier-vscode",
  "editor.codeActionsOnSave": { "source.fixAll.eslint": "explicit" },
  "files.trimTrailingWhitespace": true,
  "files.insertFinalNewline": true,

  // Saving and tabs
  "files.autoSave": "onFocusChange",
  "workbench.editor.enablePreview": false,  // stop tabs replacing each other
  "explorer.confirmDragAndDrop": false,

  // Reading long files
  "editor.stickyScroll.enabled": true,      // keeps the enclosing scope pinned
  "editor.minimap.enabled": false,          // reclaims real estate on a laptop
  "editor.rulers": [100],
  "editor.cursorSurroundingLines": 8,       // never edit on the last visible line

  // Editing quality of life
  "editor.linkedEditing": true,             // rename an HTML tag pair together
  "editor.suggestSelection": "first",
  "editor.wordWrap": "on",
  "editor.tabSize": 2,

  // Search and explorer noise
  "search.exclude": { "**/dist": true, "**/coverage": true, "**/.next": true },
  "explorer.fileNesting.enabled": true,     // collapse lock files under package.json

  // Git
  "git.autofetch": true,
  "git.confirmSync": false,
  "diffEditor.ignoreTrimWhitespace": false,

  // Terminal
  "terminal.integrated.defaultProfile.windows": "PowerShell",
  "terminal.integrated.scrollback": 10000
}

Gotcha: anything that changes formatting belongs in a checked-in .vscode/settings.json rather than your user settings, so every contributor produces identical diffs. User settings are for how you like to work; workspace settings are for how the repo works.

What carries over to Cursor and other forks

Cursor is a fork of VS Code, so every shortcut on this page works there unchanged. So do your settings.json, your keybindings.json, your themes, and your snippets - Cursor offers to import all of them on first run. Windsurf, Trae, and the other editor forks are in the same position. If you learn these bindings you keep them across every fork in the category.

What differs is the AI layer bolted on top, and those bindings are new rather than remapped. In Cursor, Ctrl+K is an inline edit on the current selection, Ctrl+L opens the chat panel against the file, and Ctrl+I opens the agent. None of those collide with the stock bindings above except Ctrl+K, which stock VS Code uses as a chord prefix - so Ctrl+K Ctrl+D and friends still behave, but a bare Ctrl+K does something different.

The larger practical difference is the extension marketplace. Forks cannot use Microsoft's marketplace and pull from Open VSX instead, so a handful of Microsoft-published extensions are unavailable or shipped as a fork-specific replacement. Check the two or three extensions you genuinely depend on before you migrate a team.

A full breakdown of that editor lives on the Cursor guide, and Claude Code vs Cursor covers the terminal-first alternative if you would rather keep stock VS Code and add the AI beside it.

Keep going

Print your own reference with Ctrl+K Ctrl+S, which opens the keyboard shortcut editor showing every binding currently in effect including the ones your extensions added. It is the only truly authoritative list for your install.

Official documentation is at code.visualstudio.com. For what to run in the terminal panel, see the npm, pnpm, and bun mapping, and the rest of the quick references are in the cheatsheet index.