diff options
Diffstat (limited to 'editors/code/src/commands/runnables.ts')
-rw-r--r-- | editors/code/src/commands/runnables.ts | 218 |
1 files changed, 0 insertions, 218 deletions
diff --git a/editors/code/src/commands/runnables.ts b/editors/code/src/commands/runnables.ts deleted file mode 100644 index 0bd30fb07..000000000 --- a/editors/code/src/commands/runnables.ts +++ /dev/null | |||
@@ -1,218 +0,0 @@ | |||
1 | import * as vscode from 'vscode'; | ||
2 | import * as lc from 'vscode-languageclient'; | ||
3 | import * as ra from '../rust-analyzer-api'; | ||
4 | |||
5 | import { Ctx, Cmd } from '../ctx'; | ||
6 | import { startDebugSession, getDebugConfiguration } from '../debug'; | ||
7 | |||
8 | const quickPickButtons = [{ iconPath: new vscode.ThemeIcon("save"), tooltip: "Save as a launch.json configurtation." }]; | ||
9 | |||
10 | async function selectRunnable(ctx: Ctx, prevRunnable?: RunnableQuickPick, debuggeeOnly = false, showButtons: boolean = true): Promise<RunnableQuickPick | undefined> { | ||
11 | const editor = ctx.activeRustEditor; | ||
12 | const client = ctx.client; | ||
13 | if (!editor || !client) return; | ||
14 | |||
15 | const textDocument: lc.TextDocumentIdentifier = { | ||
16 | uri: editor.document.uri.toString(), | ||
17 | }; | ||
18 | |||
19 | const runnables = await client.sendRequest(ra.runnables, { | ||
20 | textDocument, | ||
21 | position: client.code2ProtocolConverter.asPosition( | ||
22 | editor.selection.active, | ||
23 | ), | ||
24 | }); | ||
25 | const items: RunnableQuickPick[] = []; | ||
26 | if (prevRunnable) { | ||
27 | items.push(prevRunnable); | ||
28 | } | ||
29 | for (const r of runnables) { | ||
30 | if ( | ||
31 | prevRunnable && | ||
32 | JSON.stringify(prevRunnable.runnable) === JSON.stringify(r) | ||
33 | ) { | ||
34 | continue; | ||
35 | } | ||
36 | |||
37 | if (debuggeeOnly && (r.label.startsWith('doctest') || r.label.startsWith('cargo'))) { | ||
38 | continue; | ||
39 | } | ||
40 | items.push(new RunnableQuickPick(r)); | ||
41 | } | ||
42 | |||
43 | if (items.length === 0) { | ||
44 | // it is the debug case, run always has at least 'cargo check ...' | ||
45 | // see crates\rust-analyzer\src\main_loop\handlers.rs, handle_runnables | ||
46 | vscode.window.showErrorMessage("There's no debug target!"); | ||
47 | return; | ||
48 | } | ||
49 | |||
50 | return await new Promise((resolve) => { | ||
51 | const disposables: vscode.Disposable[] = []; | ||
52 | const close = (result?: RunnableQuickPick) => { | ||
53 | resolve(result); | ||
54 | disposables.forEach(d => d.dispose()); | ||
55 | }; | ||
56 | |||
57 | const quickPick = vscode.window.createQuickPick<RunnableQuickPick>(); | ||
58 | quickPick.items = items; | ||
59 | quickPick.title = "Select Runnable"; | ||
60 | if (showButtons) { | ||
61 | quickPick.buttons = quickPickButtons; | ||
62 | } | ||
63 | disposables.push( | ||
64 | quickPick.onDidHide(() => close()), | ||
65 | quickPick.onDidAccept(() => close(quickPick.selectedItems[0])), | ||
66 | quickPick.onDidTriggerButton((_button) => { | ||
67 | (async () => await makeDebugConfig(ctx, quickPick.activeItems[0]))(); | ||
68 | close(); | ||
69 | }), | ||
70 | quickPick.onDidChangeActive((active) => { | ||
71 | if (showButtons && active.length > 0) { | ||
72 | if (active[0].label.startsWith('cargo')) { | ||
73 | // save button makes no sense for `cargo test` or `cargo check` | ||
74 | quickPick.buttons = []; | ||
75 | } else if (quickPick.buttons.length === 0) { | ||
76 | quickPick.buttons = quickPickButtons; | ||
77 | } | ||
78 | } | ||
79 | }), | ||
80 | quickPick | ||
81 | ); | ||
82 | quickPick.show(); | ||
83 | }); | ||
84 | } | ||
85 | |||
86 | export function run(ctx: Ctx): Cmd { | ||
87 | let prevRunnable: RunnableQuickPick | undefined; | ||
88 | |||
89 | return async () => { | ||
90 | const item = await selectRunnable(ctx, prevRunnable); | ||
91 | if (!item) return; | ||
92 | |||
93 | item.detail = 'rerun'; | ||
94 | prevRunnable = item; | ||
95 | const task = createTask(item.runnable); | ||
96 | return await vscode.tasks.executeTask(task); | ||
97 | }; | ||
98 | } | ||
99 | |||
100 | export function runSingle(ctx: Ctx): Cmd { | ||
101 | return async (runnable: ra.Runnable) => { | ||
102 | const editor = ctx.activeRustEditor; | ||
103 | if (!editor) return; | ||
104 | |||
105 | const task = createTask(runnable); | ||
106 | task.group = vscode.TaskGroup.Build; | ||
107 | task.presentationOptions = { | ||
108 | reveal: vscode.TaskRevealKind.Always, | ||
109 | panel: vscode.TaskPanelKind.Dedicated, | ||
110 | clear: true, | ||
111 | }; | ||
112 | |||
113 | return vscode.tasks.executeTask(task); | ||
114 | }; | ||
115 | } | ||
116 | |||
117 | export function debug(ctx: Ctx): Cmd { | ||
118 | let prevDebuggee: RunnableQuickPick | undefined; | ||
119 | |||
120 | return async () => { | ||
121 | const item = await selectRunnable(ctx, prevDebuggee, true); | ||
122 | if (!item) return; | ||
123 | |||
124 | item.detail = 'restart'; | ||
125 | prevDebuggee = item; | ||
126 | return await startDebugSession(ctx, item.runnable); | ||
127 | }; | ||
128 | } | ||
129 | |||
130 | export function debugSingle(ctx: Ctx): Cmd { | ||
131 | return async (config: ra.Runnable) => { | ||
132 | await startDebugSession(ctx, config); | ||
133 | }; | ||
134 | } | ||
135 | |||
136 | async function makeDebugConfig(ctx: Ctx, item: RunnableQuickPick): Promise<void> { | ||
137 | const scope = ctx.activeRustEditor?.document.uri; | ||
138 | if (!scope) return; | ||
139 | |||
140 | const debugConfig = await getDebugConfiguration(ctx, item.runnable); | ||
141 | if (!debugConfig) return; | ||
142 | |||
143 | const wsLaunchSection = vscode.workspace.getConfiguration("launch", scope); | ||
144 | const configurations = wsLaunchSection.get<any[]>("configurations") || []; | ||
145 | |||
146 | const index = configurations.findIndex(c => c.name === debugConfig.name); | ||
147 | if (index !== -1) { | ||
148 | const answer = await vscode.window.showErrorMessage(`Launch configuration '${debugConfig.name}' already exists!`, 'Cancel', 'Update'); | ||
149 | if (answer === "Cancel") return; | ||
150 | |||
151 | configurations[index] = debugConfig; | ||
152 | } else { | ||
153 | configurations.push(debugConfig); | ||
154 | } | ||
155 | |||
156 | await wsLaunchSection.update("configurations", configurations); | ||
157 | } | ||
158 | |||
159 | export function newDebugConfig(ctx: Ctx): Cmd { | ||
160 | return async () => { | ||
161 | const item = await selectRunnable(ctx, undefined, true, false); | ||
162 | if (!item) return; | ||
163 | |||
164 | await makeDebugConfig(ctx, item); | ||
165 | }; | ||
166 | } | ||
167 | |||
168 | class RunnableQuickPick implements vscode.QuickPickItem { | ||
169 | public label: string; | ||
170 | public description?: string | undefined; | ||
171 | public detail?: string | undefined; | ||
172 | public picked?: boolean | undefined; | ||
173 | |||
174 | constructor(public runnable: ra.Runnable) { | ||
175 | this.label = runnable.label; | ||
176 | } | ||
177 | } | ||
178 | |||
179 | interface CargoTaskDefinition extends vscode.TaskDefinition { | ||
180 | type: 'cargo'; | ||
181 | label: string; | ||
182 | command: string; | ||
183 | args: string[]; | ||
184 | env?: { [key: string]: string }; | ||
185 | } | ||
186 | |||
187 | function createTask(spec: ra.Runnable): vscode.Task { | ||
188 | const TASK_SOURCE = 'Rust'; | ||
189 | const definition: CargoTaskDefinition = { | ||
190 | type: 'cargo', | ||
191 | label: spec.label, | ||
192 | command: spec.bin, | ||
193 | args: spec.extraArgs ? [...spec.args, '--', ...spec.extraArgs] : spec.args, | ||
194 | env: spec.env, | ||
195 | }; | ||
196 | |||
197 | const execOption: vscode.ShellExecutionOptions = { | ||
198 | cwd: spec.cwd || '.', | ||
199 | env: definition.env, | ||
200 | }; | ||
201 | const exec = new vscode.ShellExecution( | ||
202 | definition.command, | ||
203 | definition.args, | ||
204 | execOption, | ||
205 | ); | ||
206 | |||
207 | const f = vscode.workspace.workspaceFolders![0]; | ||
208 | const t = new vscode.Task( | ||
209 | definition, | ||
210 | f, | ||
211 | definition.label, | ||
212 | TASK_SOURCE, | ||
213 | exec, | ||
214 | ['$rustc'], | ||
215 | ); | ||
216 | t.presentationOptions.clear = true; | ||
217 | return t; | ||
218 | } | ||