Visual Studio Code Keyboard Shortcuts
VS Code was built by a team with a strong command-palette philosophy, so nearly every feature in the editor — not just the obvious text-editing actions — has a keyboard path, discoverable through Ctrl+Shift+P if you forget the dedicated binding. This makes VS Code unusually friendly to keyboard-only workflows compared to older editors where some features are genuinely mouse-only. The categories below split around how developers actually move through a coding session: getting around a file and a multi-file project quickly, editing code with multi-cursor and selection tricks that are arguably VS Code's signature feature, managing the integrated terminal and split panes that most developers leave open all day, and the debugging shortcuts that matter once you're past writing code and into figuring out why it's broken. Windows and Linux share nearly identical bindings since VS Code treats them as one platform family in its keymap, while Mac swaps Ctrl for Cmd in most but not quite all cases — a few terminal-related and OS-reserved combinations diverge in ways worth knowing before you assume a binding just isn't working.
Navigation
| Action | Windows | Mac | Description |
|---|---|---|---|
| Quick Open a file by name | Ctrl+P | Cmd+P | Opens a fuzzy-search file finder — type a partial filename or even just scattered letters in order, and VS Code ranks matching files across the entire open workspace, regardless of folder depth. |
| Open Command Palette | Ctrl+Shift+P | Cmd+Shift+P | Opens a searchable list of every command VS Code and its installed extensions expose, the single best way to discover a feature's name or shortcut when you don't remember the dedicated binding. |
| Go to Symbol in file | Ctrl+Shift+O | Cmd+Shift+O | Pulls up every function, class, and variable declaration the current file contains as a searchable list, so you can jump directly to whichever definition you need instead of scrolling past unrelated code to find it. |
| Go to Definition | F12 | F12 | Jumps to where the symbol under the cursor is actually defined, even across files, relying on the active language server for accurate results. |
| Navigate back | Alt+Left | Ctrl+- | Returns the cursor to its previous location in the navigation history, the natural companion to Go to Definition for jumping into a function and then immediately back to where you were reading. |
| Go to line number | Ctrl+G | Cmd+G | Prompts for a line number (and optionally a column after a colon, like 42:10) and jumps the cursor straight there, which stacks with VS Code's Ctrl+G-then-type-relative-offset trick using +10 or -5 to move relative to the current position instead of typing an absolute line. |
| Cycle through open editor tabs | Ctrl+Tab | Cmd+Tab (or Ctrl+Tab) | Opens a quick picker for cycling through recently used open tabs, similar in spirit to a browser's tab-cycling shortcut, useful for bouncing between a small number of files you're actively working across without needing to search for them by name. |
Multi Cursor Editing
| Action | Windows | Mac | Description |
|---|---|---|---|
| Select the current line | Ctrl+L | Cmd+L | Selects the entire line the cursor is on, extending to additional lines if pressed repeatedly — a fast way to grab a whole line for deletion or duplication without using Home/Shift+End. |
| Add cursor on the line below/above | Ctrl+Alt+Down / Ctrl+Alt+Up | Cmd+Option+Down / Cmd+Option+Up | Plants an additional cursor directly one line up or down from wherever you are now, matching the same column — so one typed edit lands identically down a whole vertical stack of lines instead of repeating it manually each time. |
| Add selection to next match | Ctrl+D | Cmd+D | Highlights the word sitting under the cursor first, then each further press hunts down and adds the next matching occurrence to a growing multi-selection — VS Code's go-to move for touching up a handful of variable instances that F2's formal Rename Symbol refactor either can't see or would apply too broadly. |
| Duplicate line down | Shift+Alt+Down | Shift+Option+Down | Copies the current line (or full selection spanning multiple lines) and inserts the copy directly below, without needing to select, copy, and paste manually. |
| Move line up/down | Alt+Up / Alt+Down | Option+Up / Option+Down | Physically relocates the current line (or selected block) one position up or down, automatically adjusting surrounding indentation-sensitive code correctly in most languages. |
| Toggle line comment | Ctrl+/ | Cmd+/ | Flips the comment state on the current line or whatever's selected, picking the right comment marker automatically based on the file's detected language rather than requiring you to remember whether it's // or # or something else entirely. |
| Select all occurrences of current selection | Ctrl+Shift+L | Cmd+Shift+L | Jumps straight to selecting every matching instance in the file at once, skipping the incremental Ctrl+D approach entirely for cases where you already know every occurrence needs the exact same edit. |
| Column (box) selection | Shift+Alt+drag | Shift+Option+drag | Draws a rectangular box selection spanning multiple lines at the same column range, rather than a normal line-based text selection, useful for editing a vertically aligned block of text like a column of values in an ASCII table or aligned code. |
Terminal Panes
| Action | Windows | Mac | Description |
|---|---|---|---|
| Toggle integrated terminal | Ctrl+` | Cmd+` | Shows or hides the integrated terminal panel without leaving the editor, preserving whatever shell session and command history was already running there. |
| Split editor | Ctrl+\ | Cmd+\ | Opens a second editor pane beside the current one, letting you view and edit two files (or two parts of the same file) side by side. |
| Focus next editor group | Ctrl+K Ctrl+Right (or Ctrl+2) | Cmd+K Cmd+Right (or Cmd+2) | Moves keyboard focus to the next split editor group, the fast way to switch between side-by-side panes without clicking into the other pane with the mouse. |
| Create a new terminal instance | Ctrl+Shift+` | Cmd+Shift+` | Opens an additional terminal tab alongside any existing ones, useful for running a dev server in one terminal while keeping a second free for git commands or one-off scripts. |
| Toggle sidebar visibility | Ctrl+B | Cmd+B | Collapses or restores the file explorer sidebar entirely, handing that reclaimed width back to the editor pane — worth doing on a cramped laptop screen or anytime the file tree is just visual clutter while you focus on one file. |
| Kill/close active terminal | Trash icon, or Ctrl+Shift+`` then close | Trash icon | Terminates the active terminal tab's shell process entirely, distinct from just hiding the panel with Ctrl+backtick, which leaves the underlying process running in the background. |
| Clear terminal output | Ctrl+K (terminal focused) | Cmd+K | Clears the visible scrollback in the active terminal, similar to a shell's own clear command, giving you a clean view without needing to scroll past a long previous command's output. |
| Maximize/restore the panel | Ctrl+J (toggles panel visibility) | Cmd+J | Toggles the visibility of the bottom panel area (which hosts the terminal, output, and problems tabs), giving quick access to full editor space when the panel isn't currently needed. |
Debugging
| Action | Windows | Mac | Description |
|---|---|---|---|
| Toggle breakpoint | F9 | F9 | Toggles a red-dot breakpoint marker in the gutter next to the current line; because VS Code's debugging runs through the Debug Adapter Protocol, the exact pause behavior depends on which debug adapter extension is active for the language, though the gutter marker and toggle key stay consistent across all of them. |
| Start debugging / continue | F5 | F5 | Starts a new debug session if none is running, or resumes execution from a paused breakpoint if a session is already active — the same key serves both purposes depending on current state. |
| Step over | F10 | F10 | Executes the current line and moves to the next one without diving into any function calls on that line, the default move when you trust the function being called and just want to keep moving through your own code. |
| Step into | F11 | F11 | Follows execution down into whatever function the current line calls, rather than skipping past it, so you can trace its internal behavior one line at a time. |
| Step out | Shift+F11 | Shift+F11 | Resumes execution until the current function returns, popping back up to whatever called it, the natural next step after using Step Into to confirm a function works correctly and wanting to return to the calling context without stepping through every remaining line individually. |
| Stop debugging session | Shift+F5 | Shift+F5 | Kills the active debug session outright rather than just pausing it, terminating the debugged process and dropping the editor back to its ordinary undebugged state. |
Frequently Asked Questions
Why does Ctrl+P sometimes open a different file picker than I expect?
You've likely triggered Ctrl+Shift+P (Command Palette) by mistake instead of Ctrl+P (Quick Open) — one searches file names across the workspace, the other searches command names, and typing a filename into the wrong one just returns nothing useful since it isn't matching against paths at all. Double-check whether Shift snuck into the combo before assuming something's broken.
Why doesn't F12 jump anywhere for some symbols?
Go to Definition relies on the active language server understanding your code well enough to resolve the symbol, which depends on having the right language extension installed and the project correctly configured (a valid tsconfig.json for TypeScript, a properly set up Python interpreter, etc.). If the language server hasn't fully indexed the project yet, or the symbol comes from a dynamically loaded or untyped source, F12 can fail silently or jump to a generic declaration instead of the real implementation.
What's the difference between Ctrl+D and selecting all occurrences with Find?
Ctrl+D selects the next occurrence one at a time, each press adding one more match to your multi-cursor selection, so you can skip individual matches you don't want to change by pressing Ctrl+D again to skip past them rather than including them. Find and Replace's 'Select All Occurrences' button (or Ctrl+Shift+L) instead selects every match in the file simultaneously in one action, which is faster when you genuinely want to edit all of them but offers no way to selectively skip a particular occurrence first.
Why does F5 sometimes do nothing or show an error instead of starting debugging?
VS Code's debugger needs a launch configuration (in .vscode/launch.json) appropriate for your project type — without one, F5 may prompt you to select an environment or simply fail to find a valid entry point. For some project types (a plain script with no debug config set up at all), you may need to manually create or select a configuration once before F5 starts working as expected on subsequent presses.
Why did my terminal shortcut conflict with my OS?
Ctrl+` is VS Code's default terminal toggle, but on some Linux window managers or with certain keyboard layouts, the backtick key combination can be intercepted by the OS or a window manager binding before VS Code receives it. If the shortcut seems unresponsive only in your terminal context, check your OS-level keyboard shortcut settings for a conflicting global binding on the same key combination.