diff --git a/extension/README.md b/extension/README.md index 7494c765..5e775cc9 100644 --- a/extension/README.md +++ b/extension/README.md @@ -90,6 +90,7 @@ also appear in the editor title bar, the Explorer, or **Project Options**. | **Project Options** | Open the project menu | | **Build** | Build without running | | **Run** | Build and run in the emulator | +| **Debug** | Build and debug in the emulator, with breakpoints and step back | | **Run This File** | Run the active file, without changing the project | | **Run Main File** | Run the project's main file | | **Follow Active Editor** | Run whichever program is in the editor | diff --git a/extension/docs/emulator.md b/extension/docs/emulator.md index ca3e8b14..a7cad317 100644 --- a/extension/docs/emulator.md +++ b/extension/docs/emulator.md @@ -55,8 +55,10 @@ states, so it keeps about 10 seconds. ## Debug -Press F5 to build the program and debug it. Press -Ctrl+F5 (**Run Without Debugging**) to just run it. +Click **Debug** (the bug button beside **Run**, at the top right of the +editor) or run **8bitworkshop: Debug** to build the program and debug it. +In a folder with a launch configuration, F5 does the same, and +Ctrl+F5 (**Run Without Debugging**) just runs it. - **Breakpoints:** click left of a line number in C or assembly. You can also add a breakpoint on a function by name (**+** in the Breakpoints diff --git a/extension/package.json b/extension/package.json index 7c1ab897..eb2f6866 100644 --- a/extension/package.json +++ b/extension/package.json @@ -111,6 +111,12 @@ "category": "8bitworkshop", "icon": "$(play)" }, + { + "command": "8bitworkshop.debug", + "title": "Debug", + "category": "8bitworkshop", + "icon": "$(debug-alt)" + }, { "command": "8bitworkshop.runThisFile", "title": "Run This File", @@ -358,6 +364,11 @@ "when": "8bitworkshop.canRun && activeWebviewPanelId != '8bitworkshop.emulator'", "group": "navigation" }, + { + "command": "8bitworkshop.debug", + "when": "8bitworkshop.canRun && activeWebviewPanelId != '8bitworkshop.emulator' && !inDebugMode", + "group": "navigation" + }, { "command": "8bitworkshop.copyToWorkspace", "when": "resourceScheme == 8bws-preset", diff --git a/extension/src/extension.ts b/extension/src/extension.ts index 6a676eb0..d83658c2 100644 --- a/extension/src/extension.ts +++ b/extension/src/extension.ts @@ -84,6 +84,7 @@ export function activate(ctx: vscode.ExtensionContext) { })); command('build', () => buildCommand(false)); command('run', () => buildCommand(true)); + command('debug', () => debugCommand()); command('runThisFile', (uri?: vscode.Uri) => runThisFile(uri)); command('runMainFile', () => runMainFile()); command('followActiveEditor', () => followActiveEditor()); @@ -371,19 +372,30 @@ async function projectMenu() { ////// build and run async function buildCommand(run: boolean) { + var target = await ensureTarget(); + if (target) await buildAndMaybeRun(target, run, 'command'); +} + +/** Debug the current target, as F5 would with no launch configuration. */ +async function debugCommand() { + var target = await ensureTarget(); + if (!target) return; + // no mainFile: the launch debugs the current target (see launchTarget) + await vscode.debug.startDebugging(vscode.workspace.getWorkspaceFolder(target.main), + { type: '8bitworkshop', request: 'launch', name: `Debug ${describeTarget(target)}` }); +} + +/** The current target; for a file no project owns yet, start one from it (case 2). */ +async function ensureTarget(): Promise { var target = currentTarget(); - if (!target) { - // no project owns this file yet: start one from it (case 2) - var uri = activeUri(); - if (!uri || !isSourceFile(uri.fsPath)) { - vscode.window.showWarningMessage('8bitworkshop: open a source file, or run "8bitworkshop: New Project...".'); - return; - } - if (!await setMainFile(uri)) return; - target = currentTarget(); - if (!target) return; + if (target) return target; + var uri = activeUri(); + if (!uri || !isSourceFile(uri.fsPath)) { + vscode.window.showWarningMessage('8bitworkshop: open a source file, or run "8bitworkshop: New Project...".'); + return undefined; } - await buildAndMaybeRun(target, run, 'command'); + if (!await setMainFile(uri)) return undefined; + return currentTarget(); } async function buildAndMaybeRun(target: Target, run: boolean, reason: BuildReason) {