aboutsummaryrefslogtreecommitdiff
path: root/editors
diff options
context:
space:
mode:
authorvsrs <[email protected]>2020-05-11 14:06:57 +0100
committervsrs <[email protected]>2020-05-11 14:06:57 +0100
commit155f0601421620086a256c9e313568d5bd7391e0 (patch)
tree88e80aaffb643fd168e272abd67281757e55a8d9 /editors
parenteb892d707c379eff514df9c2a6b2203f38874b14 (diff)
"rust-analyzer.debug" command
Diffstat (limited to 'editors')
-rw-r--r--editors/code/package.json5
-rw-r--r--editors/code/src/commands/runnables.ts149
-rw-r--r--editors/code/src/debug.ts95
-rw-r--r--editors/code/src/main.ts1
4 files changed, 144 insertions, 106 deletions
diff --git a/editors/code/package.json b/editors/code/package.json
index c6fc13519..2f90d3baf 100644
--- a/editors/code/package.json
+++ b/editors/code/package.json
@@ -121,6 +121,11 @@
121 "category": "Rust Analyzer" 121 "category": "Rust Analyzer"
122 }, 122 },
123 { 123 {
124 "command": "rust-analyzer.debug",
125 "title": "Debug",
126 "category": "Rust Analyzer"
127 },
128 {
124 "command": "rust-analyzer.analyzerStatus", 129 "command": "rust-analyzer.analyzerStatus",
125 "title": "Status", 130 "title": "Status",
126 "category": "Rust Analyzer" 131 "category": "Rust Analyzer"
diff --git a/editors/code/src/commands/runnables.ts b/editors/code/src/commands/runnables.ts
index ae328d2a4..c1b872bce 100644
--- a/editors/code/src/commands/runnables.ts
+++ b/editors/code/src/commands/runnables.ts
@@ -1,43 +1,46 @@
1import * as vscode from 'vscode'; 1import * as vscode from 'vscode';
2import * as lc from 'vscode-languageclient'; 2import * as lc from 'vscode-languageclient';
3import * as ra from '../rust-analyzer-api'; 3import * as ra from '../rust-analyzer-api';
4import * as os from "os";
5 4
6import { Ctx, Cmd } from '../ctx'; 5import { Ctx, Cmd } from '../ctx';
7import { Cargo } from '../cargo'; 6import { startDebugSession } from '../debug';
7
8async function selectRunnable(ctx: Ctx, prevRunnable: RunnableQuickPick | undefined): Promise<RunnableQuickPick | undefined> {
9 const editor = ctx.activeRustEditor;
10 const client = ctx.client;
11 if (!editor || !client) return;
12
13 const textDocument: lc.TextDocumentIdentifier = {
14 uri: editor.document.uri.toString(),
15 };
16
17 const runnables = await client.sendRequest(ra.runnables, {
18 textDocument,
19 position: client.code2ProtocolConverter.asPosition(
20 editor.selection.active,
21 ),
22 });
23 const items: RunnableQuickPick[] = [];
24 if (prevRunnable) {
25 items.push(prevRunnable);
26 }
27 for (const r of runnables) {
28 if (
29 prevRunnable &&
30 JSON.stringify(prevRunnable.runnable) === JSON.stringify(r)
31 ) {
32 continue;
33 }
34 items.push(new RunnableQuickPick(r));
35 }
36 return await vscode.window.showQuickPick(items);
37}
8 38
9export function run(ctx: Ctx): Cmd { 39export function run(ctx: Ctx): Cmd {
10 let prevRunnable: RunnableQuickPick | undefined; 40 let prevRunnable: RunnableQuickPick | undefined;
11 41
12 return async () => { 42 return async () => {
13 const editor = ctx.activeRustEditor; 43 const item = await selectRunnable(ctx, prevRunnable);
14 const client = ctx.client;
15 if (!editor || !client) return;
16
17 const textDocument: lc.TextDocumentIdentifier = {
18 uri: editor.document.uri.toString(),
19 };
20
21 const runnables = await client.sendRequest(ra.runnables, {
22 textDocument,
23 position: client.code2ProtocolConverter.asPosition(
24 editor.selection.active,
25 ),
26 });
27 const items: RunnableQuickPick[] = [];
28 if (prevRunnable) {
29 items.push(prevRunnable);
30 }
31 for (const r of runnables) {
32 if (
33 prevRunnable &&
34 JSON.stringify(prevRunnable.runnable) === JSON.stringify(r)
35 ) {
36 continue;
37 }
38 items.push(new RunnableQuickPick(r));
39 }
40 const item = await vscode.window.showQuickPick(items);
41 if (!item) return; 44 if (!item) return;
42 45
43 item.detail = 'rerun'; 46 item.detail = 'rerun';
@@ -64,88 +67,22 @@ export function runSingle(ctx: Ctx): Cmd {
64 }; 67 };
65} 68}
66 69
67function getLldbDebugConfig(config: ra.Runnable, executable: string, sourceFileMap?: Record<string, string>): vscode.DebugConfiguration { 70export function debug(ctx: Ctx): Cmd {
68 return { 71 let prevDebuggee: RunnableQuickPick | undefined;
69 type: "lldb",
70 request: "launch",
71 name: config.label,
72 program: executable,
73 args: config.extraArgs,
74 cwd: config.cwd,
75 sourceMap: sourceFileMap,
76 sourceLanguages: ["rust"]
77 };
78}
79
80function getCppvsDebugConfig(config: ra.Runnable, executable: string, sourceFileMap?: Record<string, string>): vscode.DebugConfiguration {
81 return {
82 type: (os.platform() === "win32") ? "cppvsdbg" : 'cppdbg',
83 request: "launch",
84 name: config.label,
85 program: executable,
86 args: config.extraArgs,
87 cwd: config.cwd,
88 sourceFileMap: sourceFileMap,
89 };
90}
91 72
92const debugOutput = vscode.window.createOutputChannel("Debug"); 73 return async () => {
93 74 const item = await selectRunnable(ctx, prevDebuggee);
94async function getDebugExecutable(config: ra.Runnable): Promise<string> { 75 if (!item) return;
95 const cargo = new Cargo(config.cwd || '.', debugOutput);
96 const executable = await cargo.executableFromArgs(config.args);
97 76
98 // if we are here, there were no compilation errors. 77 item.detail = 'restart';
99 return executable; 78 prevDebuggee = item;
79 return await startDebugSession(ctx, item.runnable);
80 };
100} 81}
101 82
102type DebugConfigProvider = (config: ra.Runnable, executable: string, sourceFileMap?: Record<string, string>) => vscode.DebugConfiguration;
103
104export function debugSingle(ctx: Ctx): Cmd { 83export function debugSingle(ctx: Ctx): Cmd {
105 return async (config: ra.Runnable) => { 84 return async (config: ra.Runnable) => {
106 const editor = ctx.activeRustEditor; 85 await startDebugSession(ctx, config);
107 if (!editor) return;
108
109 const knownEngines: Record<string, DebugConfigProvider> = {
110 "vadimcn.vscode-lldb": getLldbDebugConfig,
111 "ms-vscode.cpptools": getCppvsDebugConfig
112 };
113 const debugOptions = ctx.config.debug;
114
115 let debugEngine = null;
116 if (debugOptions.engine === "auto") {
117 for (var engineId in knownEngines) {
118 debugEngine = vscode.extensions.getExtension(engineId);
119 if (debugEngine) break;
120 }
121 }
122 else {
123 debugEngine = vscode.extensions.getExtension(debugOptions.engine);
124 }
125
126 if (!debugEngine) {
127 vscode.window.showErrorMessage(`Install [CodeLLDB](https://marketplace.visualstudio.com/items?itemName=vadimcn.vscode-lldb)`
128 + ` or [MS C++ tools](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools) extension for debugging.`);
129 return;
130 }
131
132 debugOutput.clear();
133 if (ctx.config.debug.openUpDebugPane) {
134 debugOutput.show(true);
135 }
136
137 const executable = await getDebugExecutable(config);
138 const debugConfig = knownEngines[debugEngine.id](config, executable, debugOptions.sourceFileMap);
139 if (debugConfig.type in debugOptions.engineSettings) {
140 const settingsMap = (debugOptions.engineSettings as any)[debugConfig.type];
141 for (var key in settingsMap) {
142 debugConfig[key] = settingsMap[key];
143 }
144 }
145
146 debugOutput.appendLine("Launching debug configuration:");
147 debugOutput.appendLine(JSON.stringify(debugConfig, null, 2));
148 return vscode.debug.startDebugging(undefined, debugConfig);
149 }; 86 };
150} 87}
151 88
diff --git a/editors/code/src/debug.ts b/editors/code/src/debug.ts
new file mode 100644
index 000000000..4f4b88adf
--- /dev/null
+++ b/editors/code/src/debug.ts
@@ -0,0 +1,95 @@
1import * as os from "os";
2import * as vscode from 'vscode';
3import * as ra from './rust-analyzer-api';
4
5import { Cargo } from './cargo';
6import { Ctx } from "./ctx";
7
8const debugOutput = vscode.window.createOutputChannel("Debug");
9type DebugConfigProvider = (config: ra.Runnable, executable: string, sourceFileMap?: Record<string, string>) => vscode.DebugConfiguration;
10
11function getLldbDebugConfig(config: ra.Runnable, executable: string, sourceFileMap?: Record<string, string>): vscode.DebugConfiguration {
12 return {
13 type: "lldb",
14 request: "launch",
15 name: config.label,
16 program: executable,
17 args: config.extraArgs,
18 cwd: config.cwd,
19 sourceMap: sourceFileMap,
20 sourceLanguages: ["rust"]
21 };
22}
23
24function getCppvsDebugConfig(config: ra.Runnable, executable: string, sourceFileMap?: Record<string, string>): vscode.DebugConfiguration {
25 return {
26 type: (os.platform() === "win32") ? "cppvsdbg" : "cppdbg",
27 request: "launch",
28 name: config.label,
29 program: executable,
30 args: config.extraArgs,
31 cwd: config.cwd,
32 sourceFileMap: sourceFileMap,
33 };
34}
35
36async function getDebugExecutable(config: ra.Runnable): Promise<string> {
37 const cargo = new Cargo(config.cwd || '.', debugOutput);
38 const executable = await cargo.executableFromArgs(config.args);
39
40 // if we are here, there were no compilation errors.
41 return executable;
42}
43
44export async function getDebugConfiguration(ctx: Ctx, config: ra.Runnable): Promise<vscode.DebugConfiguration | undefined> {
45 const editor = ctx.activeRustEditor;
46 if (!editor) return;
47
48 const knownEngines: Record<string, DebugConfigProvider> = {
49 "vadimcn.vscode-lldb": getLldbDebugConfig,
50 "ms-vscode.cpptools": getCppvsDebugConfig
51 };
52 const debugOptions = ctx.config.debug;
53
54 let debugEngine = null;
55 if (debugOptions.engine === "auto") {
56 for (var engineId in knownEngines) {
57 debugEngine = vscode.extensions.getExtension(engineId);
58 if (debugEngine) break;
59 }
60 }
61 else {
62 debugEngine = vscode.extensions.getExtension(debugOptions.engine);
63 }
64
65 if (!debugEngine) {
66 vscode.window.showErrorMessage(`Install [CodeLLDB](https://marketplace.visualstudio.com/items?itemName=vadimcn.vscode-lldb)`
67 + ` or [MS C++ tools](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools) extension for debugging.`);
68 return;
69 }
70
71 debugOutput.clear();
72 if (ctx.config.debug.openUpDebugPane) {
73 debugOutput.show(true);
74 }
75
76 const executable = await getDebugExecutable(config);
77 const debugConfig = knownEngines[debugEngine.id](config, executable, debugOptions.sourceFileMap);
78 if (debugConfig.type in debugOptions.engineSettings) {
79 const settingsMap = (debugOptions.engineSettings as any)[debugConfig.type];
80 for (var key in settingsMap) {
81 debugConfig[key] = settingsMap[key];
82 }
83 }
84
85 return debugConfig;
86}
87
88export async function startDebugSession(ctx: Ctx, config: ra.Runnable): Promise<boolean> {
89 const debugConfig = await getDebugConfiguration(ctx, config);
90 if (!debugConfig) return false;
91
92 debugOutput.appendLine("Launching debug configuration:");
93 debugOutput.appendLine(JSON.stringify(debugConfig, null, 2));
94 return vscode.debug.startDebugging(undefined, debugConfig);
95}
diff --git a/editors/code/src/main.ts b/editors/code/src/main.ts
index 9b020d001..5fdeebd68 100644
--- a/editors/code/src/main.ts
+++ b/editors/code/src/main.ts
@@ -77,6 +77,7 @@ export async function activate(context: vscode.ExtensionContext) {
77 ctx.registerCommand('syntaxTree', commands.syntaxTree); 77 ctx.registerCommand('syntaxTree', commands.syntaxTree);
78 ctx.registerCommand('expandMacro', commands.expandMacro); 78 ctx.registerCommand('expandMacro', commands.expandMacro);
79 ctx.registerCommand('run', commands.run); 79 ctx.registerCommand('run', commands.run);
80 ctx.registerCommand('debug', commands.debug);
80 81
81 defaultOnEnter.dispose(); 82 defaultOnEnter.dispose();
82 ctx.registerCommand('onEnter', commands.onEnter); 83 ctx.registerCommand('onEnter', commands.onEnter);