diff --git a/editors/code/src/debug.ts b/editors/code/src/debug.ts index d9c6b6ac4566..1168f0a42a7b 100644 --- a/editors/code/src/debug.ts +++ b/editors/code/src/debug.ts @@ -81,8 +81,9 @@ async function getDebugConfiguration( if (!editor) return; const knownEngines: Record = { - "vadimcn.vscode-lldb": getLldbDebugConfig, - "ms-vscode.cpptools": getCppvsDebugConfig, + "ms-vscode.cpptools": getCCppDebugConfig, + "vadimcn.vscode-lldb": getCodeLldbDebugConfig, + "webfreak.debug": getNativeDebugConfig, }; const debugOptions = ctx.config.debug; @@ -97,12 +98,14 @@ async function getDebugConfiguration( } if (!debugEngine) { + const commandCCpp: string = createCommandLink("ms-vscode.cpptools"); const commandCodeLLDB: string = createCommandLink("vadimcn.vscode-lldb"); - const commandCpp: string = createCommandLink("ms-vscode.cpptools"); + const commandNativeDebug: string = createCommandLink("webfreak.debug"); await vscode.window.showErrorMessage( `Install [CodeLLDB](command:${commandCodeLLDB} "Open CodeLLDB")` + - ` or [C/C++](command:${commandCpp} "Open C/C++") extension for debugging.`, + `, [C/C++](command:${commandCCpp} "Open C/C++") ` + + `or [Native Debug](command:${commandNativeDebug} "Open Native Debug") for debugging.`, ); return; } @@ -120,7 +123,7 @@ async function getDebugConfiguration( !isMultiFolderWorkspace || !runnable.args.workspaceRoot ? firstWorkspace : workspaceFolders.find((w) => runnable.args.workspaceRoot?.includes(w.uri.fsPath)) || - firstWorkspace; + firstWorkspace; const workspace = unwrapUndefinable(maybeWorkspace); const wsFolder = path.normalize(workspace.uri.fsPath); @@ -184,7 +187,7 @@ async function getDebugExecutableInfo( return executableInfo; } -function getLldbDebugConfig( +function getCCppDebugConfig( runnable: ra.Runnable, executable: string, cargoWorkspace: string, @@ -192,19 +195,18 @@ function getLldbDebugConfig( sourceFileMap?: Record, ): vscode.DebugConfiguration { return { - type: "lldb", + type: os.platform() === "win32" ? "cppvsdbg" : "cppdbg", request: "launch", name: runnable.label, program: executable, args: runnable.args.executableArgs, cwd: cargoWorkspace || runnable.args.workspaceRoot, - sourceMap: sourceFileMap, - sourceLanguages: ["rust"], + sourceFileMap, env, }; } -function getCppvsDebugConfig( +function getCodeLldbDebugConfig( runnable: ra.Runnable, executable: string, cargoWorkspace: string, @@ -212,13 +214,47 @@ function getCppvsDebugConfig( sourceFileMap?: Record, ): vscode.DebugConfiguration { return { - type: os.platform() === "win32" ? "cppvsdbg" : "cppdbg", + type: "lldb", request: "launch", name: runnable.label, program: executable, args: runnable.args.executableArgs, cwd: cargoWorkspace || runnable.args.workspaceRoot, - sourceFileMap, + sourceMap: sourceFileMap, + sourceLanguages: ["rust"], env, }; } + +function getNativeDebugConfig( + runnable: ra.Runnable, + executable: string, + cargoWorkspace: string, + env: Record, + _sourceFileMap?: Record, +): vscode.DebugConfiguration { + return { + type: "gdb", + request: "launch", + name: runnable.label, + target: executable, + // See https://github.com/WebFreak001/code-debug/issues/359 + arguments: quote(runnable.args.executableArgs), + cwd: cargoWorkspace || runnable.args.workspaceRoot, + env, + valuesFormatting: "prettyPrinters", + }; +} + +// Based on https://github.com/ljharb/shell-quote/blob/main/quote.js +function quote(xs: string[]) { + return xs.map(function (s) { + if ((/["\s]/).test(s) && !(/'/).test(s)) { + return "'" + s.replace(/(['\\])/g, '\\$1') + "'"; + } + if ((/["'\s]/).test(s)) { + return '"' + s.replace(/(["\\$`!])/g, '\\$1') + '"'; + } + return s.replace(/([A-Za-z]:)?([#!"$&'()*,:;<=>?@[\\\]^`{|}])/g, '$1\\$2'); + }).join(' '); +}