0. VS Code for Delphi developers

You have spent years in an IDE where you know where everything is without looking. This page is about getting some of that back quickly, because almost nothing here is where you expect it and two of the keys do the opposite of what your hands are about to do.

It assumes Visual Studio Code is installed and you can open a folder in it. It does not try to teach the editor — Microsoft’s own documentation does that better than we would. What follows is only the translation.

Delphi shortcuts below are the Default keymapping in RAD Studio. If you use the Classic scheme, or have customised yours, your keys will differ — the mapping to VS Code still holds, only the left-hand column changes.

Read this one first: F5 and F9 are swapped

KeyIn DelphiIn VS Code
F5 Toggle a breakpoint Start / continue the program
F9 Run the program Toggle a breakpoint

They are exactly exchanged. Your first instinct — F5 to mark a line — starts the application instead, and F9 to launch it silently drops a breakpoint on whatever line the cursor was on. This costs everyone the same confused thirty seconds, so now you have had them here instead.

You can swap them back if you want to; see changing the keys below. Read the rest of this page before deciding.

Where the debug windows went

Delphi scatters its debug windows across the desktop and you summon them with Ctrl+Alt-something. VS Code puts nearly all of them in a single side bar panel: the Run and Debug view, opened with Ctrl+Shift+D. Inside it are collapsible sections, and those sections are your old windows.

Delphi windowWhere it is now
Local VariablesCtrl+Alt+LVARIABLES section
WatchesCtrl+Alt+WWATCH section
Call StackCtrl+Alt+SCALL STACK section
BreakpointsCtrl+Alt+BBREAKPOINTS section — which is also where the exception filters live
Thread StatusCtrl+Alt+TNo separate window: threads are the top-level rows of the CALL STACK section, and expanding one shows its frames
ModulesCtrl+Alt+MDelphi Modules section — added by this extension, not part of VS Code
CPU / DisassemblyCtrl+Alt+C / Ctrl+Alt+DThe Disassembly View, opened from the Call Stack’s context menu
Event LogCtrl+Alt+VSplit in two: your program’s output goes to the Debug Console, the debugger’s own messages to an Output panel channel
Raw values in the stackCtrl+Alt+RThe raw stack scan — same idea, same caveats, switched on from the Call Stack title bar
The Run and Debug side bar during a paused session, all sections expanded: Variables with Locals and Registers scopes, Watch, Call Stack listing two threads with their frames, Breakpoints with the exception filters and two source breakpoints, and the Delphi Modules tree showing per-module paths and debug info.
The whole table above in one picture. Top to bottom: VARIABLES (with the Registers scope — the register pane of Delphi’s CPU window lives here), WATCH, CALL STACK with each thread as a top-level row, BREAKPOINTS holding both the exception filters and the source breakpoints, and the Delphi Modules tree this extension adds. In the editor, the red dots and the yellow arrow work exactly as they do in Delphi.

The rest of the keys

What you wantDelphiVS Code
Run with debuggingF9F5
Run without debuggingCtrl+Shift+F9Ctrl+F5
Toggle breakpointF5F9
Step overF8F10
Step intoF7 (Trace Into)F11
Run until the routine returnsShift+F8Shift+F11
Stop the programCtrl+F2 (Program Reset)Shift+F5
RestartCtrl+Shift+F5
Run to the cursorF4Run to Cursor, from the editor’s right-click menu while stopped
Move the execution pointdrag the arrowJump to Cursor, in that same menu — see chapter 3
Evaluate / modify a valueCtrl+F7Type it in the Debug Console, or edit the value in place in VARIABLES
Inspect a valuehover, or Debug InspectorHover — and if you select an expression first, the selection is what gets evaluated, as in Delphi
Two that do not exist here. There is no Trace to next source line (Shift+F7): step into already walks to the next line that has source. And there is no drag gesture for the execution point — VS Code does not implement one.

Changing the keys

None of this is fixed. Ctrl+K then Ctrl+S opens the Keyboard Shortcuts editor: search for a command, click the pencil, press the combination you want. Everything you change is written to a keybindings.json you can version and share.

So you can put F9 back on Run and F5 back on Toggle Breakpoint, and if you spend most of your day in Delphi that may well be the right call — fighting your own muscle memory all day is a real cost.

The argument for leaving them alone: every VS Code tutorial, every answer you find online, every colleague looking over your shoulder and every article about this debugger assumes the defaults. Remap them and you are on your own whenever you look something up. It is a genuine trade-off — just make it deliberately rather than discovering it later.
The Keyboard Shortcuts editor, opened with Ctrl+K Ctrl+S, filtered by a search term. Each row shows the command, its keybinding, an optional when clause, and where the binding comes from; hovering a row reveals a pencil icon to rebind it.
The Keyboard Shortcuts editor (Ctrl+K Ctrl+S) — type anything in the search box to filter, including a command ID, a key combination, or just a word like Clipboard shown here. Hover a row for the pencil icon that lets you rebind it. The same editor filters on any of this manual’s debug commands just as well.

Where things hide

Delphi puts its commands in menus. VS Code hides most of them, and knowing the four hiding places is most of what makes it usable.

  • View title bars. Small icons at the top-right of a section — but only when the mouse is over that section. Edit Exception Rules and Toggle Raw Stack Scan live there, and you will never see them by staring at a stationary screen.
  • Inline row icons. Some commands appear as an icon on a row when you hover it, not in its right-click menu. View Memory (Delphi) is one, so looking for it under right-click fails.
  • The Command PaletteCtrl+Shift+P, type a few letters of what you want. Everything this extension contributes is prefixed Delphi Debugger:, so typing that lists the lot. A handful are deliberately excluded because they only make sense on a row you clicked.
  • The editor’s right-click menu while stopped, which is where Run to Cursor and Jump to Cursor are.
A VS Code habit worth acquiring early: when a button is not where you expect, it is usually absent rather than greyed out. VS Code hides commands that do not apply instead of disabling them, so a missing button is telling you the state is wrong — not stopped, wrong debug type, no session — rather than that you have looked in the wrong place.
The Call Stack section title bar with three icons on its right edge; the cursor hovers the magnifying-glass icon, revealing the tooltip Toggle Raw Stack Scan.
The Call Stack title bar, hovered. Those three icons only show up on hover — the magnifying glass here is Toggle Raw Stack Scan, covered in chapter 6. Every section’s title bar works the same way: rest the pointer on it before assuming a command is not there.

There is no project options dialog

Everything you would set in Project → Options — what to run, where the symbols are, where the sources are — is a JSON file, .vscode/launch.json. There is no dialog, and hand-writing it for a real Delphi project means transcribing a couple of hundred search paths.

Do not do that. The Edit in VS Code IDE plugin generates the whole thing from the project you already have open in Delphi. Chapter 1 covers what ends up in it.

Settings a Delphi codebase needs

VS Code’s defaults assume a codebase that is not yours. Five settings make it behave around Delphi sources, and the first one is not optional.

Encoding detection — the one that looks like corruption

"files.autoGuessEncoding": true

VS Code opens every file as UTF-8. Plenty of Delphi code predates that and is stored in a local ANSI code page, so the moment you open a unit with accented characters in it you get mojibake — and if you save, you write the damage to disk. Turning detection on fixes it. This is the setting that makes people conclude VS Code “does not work with Delphi” and give up in the first ten minutes.

Hide the build output

"files.exclude": {
  "**/Win32/Debug": true,
  "**/Win64/Debug": true,
  "**/__history": true,
  "**/__recovery": true,
  "**/*.res": true
}

Without this, the file tree and every search are full of build output and IDE backups. __history is the worst of them: it holds old copies of your own units, so a search for a routine name returns the current version and nine previous ones with no indication of which is which.

Stop the editor guessing indentation

"editor.detectIndentation": false

By default VS Code infers tabs-versus-spaces per file from what it finds. On a codebase with decades of mixed history that means the setting changes as you move between units, and your edits inherit whatever the file happened to have.

Let folding work on big units

"editor.foldingMaximumRegions": 8000

Folding gives up past a fixed number of regions, and a large Delphi unit blows through the default. It fails quietly — folding simply stops working, with no message.

Teach it that begin/end is a bracket pair

VS Code understands {} and (). It has no idea that begin and end belong together, so bracket matching and folding do nothing useful in Pascal until you tell it — the same for case/end, repeat/until, try/end.

You do not have to type any of this. The Edit in VS Code plugin writes them all into a vscode-workspace-defaults.json next to your project, together with the recommendation to install DelphiLSP. Put that file under version control and your colleagues get the same editor behaviour on checkout, which is the point of it existing.

One more, from the File menu

Turn on Auto Save. You will be switching between Delphi and VS Code constantly, and this way the file on disk is already current when you switch back. Note the asymmetry: Delphi does not auto-save when you leave it, unless you left through the plugin’s own Edit in Visual Studio Code command.

Next

That is the orientation. Chapter 1 is about getting your project compiled so the debugger has something to read — which is the other thing that stops people on day one, and has nothing to do with VS Code.