VSCode


  • Description: VS Code daily reference — install, command palette, editor shortcuts, multi-cursor, IntelliSense, refactoring, extensions, settings, tasks/launch, integrated terminal, remote development
  • My Notion Note ID: K2B-1-4
  • Created: 2020-06-01
  • Updated: 2026-05-15
  • License: Reuse is very welcome. Please credit Yu Zhang and link back to the original on yuzhang.io

Table of Contents


1. Overview

Three pieces, packaged together:

  • Electron shell — cross-platform UI.
  • Monaco editor — text surface.
  • LSP — language intelligence.

VS Code shipped LSP first with polished default UI + curated marketplace. Same protocol now reused by Neovim, Helix, Emacs lsp-mode, etc.

Source vs binary:

  • github.com/microsoft/vscode — MIT. Build → unbranded Code-OSS.
  • Default product.json → no marketplace, no telemetry, no proprietary extensions.
  • MS binary at code.visualstudio.com — same code + MS-patched product.json (telemetry, official marketplace, C/C++ debugger, Remote-SSH, Pylance, Live Share) under proprietary EULA.
  • Distros shipping code-oss (Arch's code, etc.) patch product.json → Open VSX.
  • VSCodium — community rebuild, telemetry off, Open VSX preconfigured.
Distribution Source Marketplace (as shipped) Telemetry Proprietary extensions
VS Code MS binary marketplace.visualstudio.com yes yes (Remote-SSH, etc.)
Code-OSS (upstream build) repo build none (empty product.json) no no
Code-OSS (Arch code) distro pkg Open VSX (distro patch) no no
VSCodium community Open VSX no no
Cursor / Windsurf fork Open VSX (mostly) varies AI features

LSP impact — one server per language (rust-analyzer, clangd, gopls, pyright) → every LSP-aware editor gets completion, diagnostics, hover, go-to-def, rename for free. Pre-LSP: every editor had its own incompatible plugin API.


2. Install and the code CLI

Ubuntu / Debian — Microsoft apt repo:

sudo apt install wget gpg
wget -qO- https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > microsoft.gpg
sudo install -D -o root -g root -m 644 microsoft.gpg /etc/apt/keyrings/packages.microsoft.gpg
echo "deb [arch=amd64,arm64,armhf signed-by=/etc/apt/keyrings/packages.microsoft.gpg] https://packages.microsoft.com/repos/code stable main" | sudo tee /etc/apt/sources.list.d/vscode.list
sudo apt update && sudo apt install code

macOS — Homebrew cask:

brew install --cask visual-studio-code

Snap (Ubuntu, official channel):

sudo snap install code --classic

VSCodium:

brew install --cask vscodium       # macOS
sudo snap install codium --classic # Linux

code CLI: bundled with GUI on Linux/Windows. macOS → run Shell Command: Install 'code' command in PATH from palette once.

code .                          # open cwd as workspace
code -g file.py:42:10           # open at line:column (--goto required for the colon syntax)
code --diff a.txt b.txt         # diff view
code --wait commit-msg.txt      # block until file closes (use as $EDITOR)
code --install-extension ms-python.python
code --list-extensions --show-versions
code --user-data-dir /tmp/clean # disposable profile

VS Code as git editor:

git config --global core.editor "code --wait"

3. Command Palette

Ctrl/Cmd+Shift+P → palette. Every editor action is a command (formatting, terminal split, theme, extension install, word wrap). Keybindings optional; palette is not.

Prefix Effect
(none) Search commands
> Search commands (explicit)
@ Symbols in current file
@: Symbols grouped by category
# Symbols in workspace
: Go to line number
? Help — list all available prefixes

Ctrl/Cmd+P → same palette in Quick Open mode (file search, no leading >).


4. Editing

4.1 Cursor and Selection

Action Shortcut
Move by word Ctrl+Left/Right (Mac: Alt+)
Move to line start/end Home / End
Move to file start/end Ctrl/Cmd+Home / End
Select to word/line end Add Shift
Expand/shrink selection Shift+Alt+Right/Left
Select current line Ctrl/Cmd+L
Delete line Ctrl+Shift+K (Mac: Cmd+Shift+K)
Move line up/down Alt+Up/Down (Mac: Option+Up/Down)
Copy line up/down Win/Mac: Shift+Alt+Up/Down  ·  Linux: Ctrl+Shift+Alt+Up/Down
Indent / outdent Tab / Shift+Tab
Toggle line comment Ctrl/Cmd+/
Toggle block comment Shift+Alt+A

4.2 Multi-Cursor

Single biggest productivity win. Every keystroke after placement applies to all cursors.

Action Shortcut
Add cursor at click Alt+Click (Mac: Option+Click)
Add cursor above/below Win: Ctrl+Alt+Up/Down  ·  Linux: Shift+Alt+Up/Down  ·  Mac: Option+Cmd+Up/Down
Add next occurrence of selection Ctrl/Cmd+D
Skip current, add next Ctrl/Cmd+K then Ctrl/Cmd+D
Select all occurrences of selection Ctrl+Shift+L (Mac: Cmd+Shift+L)
Cursor at end of every selected line Shift+Alt+I
Undo last cursor Ctrl/Cmd+U

4.3 Column (Box) Selection

Rectangular drag → edit aligned columns.

Action Shortcut
Column-select with mouse Shift+Alt+Drag (Mac: Shift+Option+Drag)
Column-select with keyboard Ctrl+Shift+Alt+Arrow (Mac: Cmd+Shift+Option+Arrow)
Toggle Column Selection mode Command palette → "Toggle Column Selection"

4.4 Snippets and Emmet

Snippets — language-aware templates, triggered from completion or Insert Snippet in palette. Built-in with most language extensions. User snippets → ~/.config/Code/User/snippets/ (Linux) or ~/Library/Application Support/Code/User/snippets/ (macOS).

Example user snippet (python.json):

{
  "Pytest function": {
    "prefix": "deftest",
    "body": [
      "def test_${1:name}():",
      "\t${2:pass}"
    ],
    "description": "pytest test function"
  }
}

Emmet — built in for HTML/CSS/JSX. Type abbreviation, press Tab:

ul>li.item*3        → <ul><li class="item"></li>×3</ul>
div#main>p{Hello}   → <div id="main"><p>Hello</p></div>

Other languages → emmet.includeLanguages.


5. Navigation

Action Shortcut
Quick open file Ctrl/Cmd+P
Workspace symbol search Ctrl/Cmd+T
Symbol in current file Ctrl+Shift+O (Mac: Cmd+Shift+O)
Go to line Ctrl+G
Go to definition F12
Peek definition Alt+F12 (Mac: Option+F12)
Go to references Shift+F12
Go to implementation Ctrl/Cmd+F12
Go to type definition Command palette
Navigate back / forward Linux: Ctrl+Alt+- / Ctrl+Shift+-  ·  Win: Alt+Left/Right  ·  Mac: Ctrl+- / Ctrl+Shift+-
Switch between tabs Ctrl/Cmd+PageUp/PageDown
Recently used tabs Ctrl+Tab

Peek vs jump — jump (F12) replaces view + pushes nav stack; peek (Alt+F12) inline preview, no nav. Peek for lookup, jump to land. Esc closes peek.

Breadcrumbs (View → Show Breadcrumbs) — file path + symbol hierarchy. Click any segment → navigable picker.


6. Find and Replace

6.1 In File

Ctrl/Cmd+F → find. Ctrl/Cmd+H → find+replace.

Toggle Shortcut (when widget focused)
Match Case Alt+C
Match Whole Word Alt+W
Use Regex Alt+R
Find in Selection Alt+L
Preserve Case toggle in widget

Regex → JS flavor. Capture groups → $1, $2 in replace field.

6.2 Across Workspace

Ctrl/Cmd+Shift+F → search. Ctrl/Cmd+Shift+H → replace. Same regex/case/word toggles. files to include / files to exclude accept globs:

include: src/**/*.{ts,tsx}
exclude: **/dist/**, **/node_modules/**

Workspace replace → diff preview before apply.


7. IntelliSense and LSP

IntelliSense = VS Code's branding for LSP features: completion, signature help, hover docs, diagnostics, code actions.

Feature Shortcut / Trigger
Trigger completion Ctrl+Space
Signature help Ctrl+Shift+Space (Mac: Cmd+Shift+Space)
Hover hover with mouse, or Ctrl+K Ctrl+I
Quick Fix / actions Ctrl+. (Mac: Cmd+.)
Show problems panel Ctrl+Shift+M (Mac: Cmd+Shift+M)
Next/prev problem F8 / Shift+F8

How LSP plugs in:

  • Extension declares activation file types.
  • Spawns language server as subprocess. Pipes JSON-RPC over stdio.
  • Server emits diagnostics + responds to completion/hover/etc.
  • Editor stays language-agnostic. New language → new server, no editor changes.
  • Diagnostics → squiggles. Problems panel aggregates workspace-wide.

Quick Fix (Ctrl+.) — offered when cursor sits on a diagnostic with associated codeAction: add missing import, convert to arrow function, satisfy interface. Most useful keybinding after the palette.


8. Refactoring

Quality depends entirely on the language server.

Action Shortcut
Rename symbol F2
Format document Win: Shift+Alt+F  ·  Linux: Ctrl+Shift+I  ·  Mac: Shift+Option+F
Format selection Ctrl+K Ctrl+F (Mac: Cmd+K Cmd+F)
Organize imports Shift+Alt+O (Mac: Shift+Option+O)
Refactor menu Ctrl+Shift+R (Mac: Ctrl+Shift+R)
Quick Fix Ctrl/Cmd+.

Rename (F2) — project-wide, scope-aware. Not find-and-replace. TS/Python/Rust/Go servers all solid.

Extract function / variable — under Ctrl/Cmd+. on candidate expression. TS excellent, Python (Pylance) decent, C++ (clangd) minimal.

Format on save — standard workflow:

{
  "editor.formatOnSave": true,
  "editor.codeActionsOnSave": {
    "source.organizeImports": "explicit",
    "source.fixAll.eslint": "explicit"
  }
}

Pick default formatter per language → avoid conflicts:

"[typescript]": { "editor.defaultFormatter": "esbenp.prettier-vscode" },
"[python]":     { "editor.defaultFormatter": "ms-python.black-formatter" },
"[rust]":       { "editor.defaultFormatter": "rust-lang.rust-analyzer" }

9. Settings

Three scopes, top-down (later wins):

  1. User~/.config/Code/User/settings.json (Linux) / ~/Library/Application Support/Code/User/settings.json (macOS)
  2. Workspace.vscode/settings.json in project, or inside a .code-workspace file
  3. Folder — per-folder in multi-root workspaces

Ctrl/Cmd+, → settings UI. {} icon top-right → JSON (comments allowed; what most engineers actually edit).

9.1 settings.json

Worth setting once:

{
  // editor
  "editor.formatOnSave": true,
  "editor.fontFamily": "JetBrains Mono, Menlo, monospace",
  "editor.fontSize": 13,
  "editor.tabSize": 2,
  "editor.insertSpaces": true,
  "editor.rulers": [80, 120],
  "editor.minimap.enabled": false,
  "editor.bracketPairColorization.enabled": true,
  "editor.guides.bracketPairs": "active",
  "editor.linkedEditing": true,
  "editor.stickyScroll.enabled": true,
  "editor.inlayHints.enabled": "onUnlessPressed",

  // files
  "files.autoSave": "onFocusChange",
  "files.insertFinalNewline": true,
  "files.trimTrailingWhitespace": true,
  "files.eol": "\n",
  "files.exclude": {
    "**/__pycache__": true,
    "**/.pytest_cache": true
  },

  // workbench
  "workbench.editor.enablePreview": false,
  "workbench.colorTheme": "Default Light Modern",

  // terminal
  "terminal.integrated.fontSize": 13,
  "terminal.integrated.scrollback": 10000
}

9.2 Keybindings

Keyboard Shortcuts (Ctrl/Cmd+K Ctrl/Cmd+S) or edit keybindings.json:

[
  {
    "key": "ctrl+shift+t",
    "command": "workbench.action.terminal.toggleTerminal"
  },
  {
    "key": "alt+j",
    "command": "editor.action.moveLinesDownAction",
    "when": "editorTextFocus && !editorReadonly"
  }
]

when clauses restrict where binding fires → see When Context Reference in docs.


10. Extensions

Ctrl+Shift+X → extensions sidebar. Install via button or code --install-extension <id>.

Extension ID Use
Python ms-python.python Pylance + debugger
Pylance ms-python.vscode-pylance Python LSP (proprietary)
Rust Analyzer rust-lang.rust-analyzer Rust LSP
Go golang.go Go LSP + dlv
C/C++ ms-vscode.cpptools C/C++ debugger + IntelliSense
clangd llvm-vs-code-extensions.vscode-clangd C/C++ LSP (preferred over MS one)
ESLint dbaeumer.vscode-eslint JS/TS linting
Prettier esbenp.prettier-vscode JS/TS/MD formatting
Vim vscodevim.vim Modal editing
Remote - SSH ms-vscode-remote.remote-ssh Edit on remote host
Dev Containers ms-vscode-remote.remote-containers Edit inside containers
GitLens eamodio.gitlens Blame, history overlays
Error Lens usernamehw.errorlens Inline diagnostics
Even Better TOML tamasfe.even-better-toml TOML LSP

Workspace recommendations — commit .vscode/extensions.json → collaborators prompted:

{
  "recommendations": [
    "esbenp.prettier-vscode",
    "dbaeumer.vscode-eslint",
    "ms-python.python"
  ],
  "unwantedRecommendations": []
}

11. Tasks and Launch

11.1 Tasks (.vscode/tasks.json)

Run shell commands, parse output via problem matchers. Ctrl/Cmd+Shift+B → default build task; or Tasks: Run Task from palette.

{
  "version": "2.0.0",
  "tasks": [
    {
      "label": "build",
      "type": "shell",
      "command": "pnpm",
      "args": ["build"],
      "group": { "kind": "build", "isDefault": true },
      "problemMatcher": ["$tsc"]
    },
    {
      "label": "test",
      "type": "shell",
      "command": "pytest",
      "args": ["-x", "-q"],
      "group": { "kind": "test", "isDefault": true },
      "presentation": { "reveal": "always", "panel": "dedicated" }
    }
  ]
}

11.2 Launch (.vscode/launch.json)

Debug configs. F5 → default config; Ctrl+F5 → run without debugging.

{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Node: current file",
      "type": "node",
      "request": "launch",
      "program": "${file}",
      "skipFiles": ["<node_internals>/**"]
    },
    {
      "name": "Python: current file",
      "type": "debugpy",
      "request": "launch",
      "program": "${file}",
      "console": "integratedTerminal"
    },
    {
      "name": "C++: gdb",
      "type": "cppdbg",
      "request": "launch",
      "program": "${workspaceFolder}/build/app",
      "args": [],
      "cwd": "${workspaceFolder}",
      "MIMode": "gdb"
    },
    {
      "name": "Go: package",
      "type": "go",
      "request": "launch",
      "mode": "auto",
      "program": "${fileDirname}"
    }
  ]
}

Debugger keys — F5 continue · F10 step over · F11 step in · Shift+F11 step out · Shift+F5 stop.


12. Integrated Terminal

Ctrl+` → toggle terminal panel.

Action Shortcut
New terminal Ctrl+Shift+\`` (Mac: `` Ctrl+Shift+ ``)
Split terminal Ctrl+Shift+5
Focus next/prev split Alt+Right/Left
Switch terminal dropdown / Terminal: Focus Next Terminal
Clear terminal Ctrl/Cmd+K (when terminal focused)
Find in terminal Ctrl/Cmd+F

Profiles — which shell launches:

{
  "terminal.integrated.defaultProfile.linux": "bash",
  "terminal.integrated.profiles.linux": {
    "bash":    { "path": "/bin/bash" },
    "zsh":     { "path": "/bin/zsh" },
    "dev-box": {
      "path": "ssh",
      "args": ["dev-box"],
      "icon": "remote"
    }
  }
}

Terminal inherits workspace env, incl. python.envFile exports + Remote-SSH session → python in terminal hits same interpreter as editor.


13. Remote Development

Remote extensions split VS Code in two — local client (UI, keybindings, themes) + remote server (file system, language servers, extensions, debug adapters). Server = small Node binary, client copies over on first connect.

13.1 Remote-SSH

ms-vscode-remote.remote-ssh. Reads ~/.ssh/config:

Host dev-box
  HostName 10.0.1.42
  User yu
  IdentityFile ~/.ssh/id_ed25519

Palette → Remote-SSH: Connect to Host → pick dev-box. New window opens; status bar bottom-left → SSH: dev-box. Local vs remote extensions tracked separately; marketplace UI shows both columns.

13.2 Dev Containers

ms-vscode-remote.remote-containers. .devcontainer/devcontainer.json declares image + post-create:

{
  "name": "node-20",
  "image": "mcr.microsoft.com/devcontainers/typescript-node:20",
  "features": {
    "ghcr.io/devcontainers/features/docker-in-docker:2": {}
  },
  "postCreateCommand": "pnpm install",
  "customizations": {
    "vscode": {
      "extensions": ["esbenp.prettier-vscode", "dbaeumer.vscode-eslint"]
    }
  }
}

Dev Containers: Reopen in Container → editor mounts workspace into container. Language server + integrated terminal all run inside.

13.3 WSL

ms-vscode-remote.remote-wsl (Windows only). Opens WSL distro like Remote-SSH opens a host. Keep files on Linux side (/home/...), not Windows side (/mnt/c/...) → avoid cross-FS performance penalty.


14. Pitfalls

14.1 Settings Sync

Built-in Settings Sync (Settings Sync: Turn On) → syncs settings, keybindings, snippets, extensions, UI state via GitHub or MS account. Older Shan Khan / Settings Sync extension is obsolete — don't install both. Workspace settings (.vscode/settings.json) live in the repo, not sync. Rule of thumb: minimal user settings; per-language formatting in workspace settings → collaborators inherit project style, not global.

14.2 Marketplace Differences

Code-OSS / VSCodium → Open VSX (open-vsx.org), not MS marketplace. Most popular extensions mirrored; MS proprietary ones absent — Remote-SSH, Pylance, C/C++ IntelliSense, Live Share, Remote Containers, Dev Tunnels (licensed only for MS-branded VS Code). Workarounds → switch to MS VS Code, or substitutes (open-remote-ssh, Open-Remote-SSH, clangd, Pyright instead of Pylance).

14.3 Line Endings and Encoding

Windows checkouts → CRLF risk. Pin LF per-project:

// .vscode/settings.json
{
  "files.eol": "\n"
}

Pair with repo-level .gitattributes:

* text=auto eol=lf
*.bat text eol=crlf

Status bar shows active EOL + encoding → click to convert.

14.4 Workspace Trust

First open of untrusted folder → VS Code prompts. Restricted Mode disables tasks, debug, many extensions → blocks a hostile .vscode/tasks.json from running on Ctrl+Shift+B. Long-term safe paths → Trusted Folders in settings:

"security.workspace.trust.untrustedFiles": "prompt",
"security.workspace.trust.banner": "always"

14.5 Telemetry

MS-branded VS Code → telemetry on by default. Disable:

"telemetry.telemetryLevel": "off"

Master switch propagates to MS-published extensions (Python, C/C++) with own toggles; third-party extensions ignore it. Want telemetry off at binary level → VSCodium.

14.6 Extension Bloat

Each extension activates language servers + event listeners. Heavy stack (Pylance + Jupyter + GitLens + Live Share + Remote-SSH + ESLint + Prettier + Docker + GitHub PRs) → noticeable CPU/RAM. Diagnose via Extensions: Show Running Extensions + Help → Open Process Explorer.


15. References