aboutsummaryrefslogtreecommitdiff
path: root/editors/code/src
diff options
context:
space:
mode:
Diffstat (limited to 'editors/code/src')
-rw-r--r--editors/code/src/ast_inspector.ts (renamed from editors/code/src/commands/syntax_tree.ts)88
-rw-r--r--editors/code/src/commands.ts (renamed from editors/code/src/commands/index.ts)97
-rw-r--r--editors/code/src/main.ts1
-rw-r--r--editors/code/src/run.ts (renamed from editors/code/src/commands/runnables.ts)26
4 files changed, 103 insertions, 109 deletions
diff --git a/editors/code/src/commands/syntax_tree.ts b/editors/code/src/ast_inspector.ts
index a5446c327..4fdd167bd 100644
--- a/editors/code/src/commands/syntax_tree.ts
+++ b/editors/code/src/ast_inspector.ts
@@ -1,93 +1,15 @@
1import * as vscode from 'vscode'; 1import * as vscode from 'vscode';
2import * as ra from '../rust-analyzer-api';
3
4import { Ctx, Cmd, Disposable } from '../ctx';
5import { isRustDocument, RustEditor, isRustEditor, sleep } from '../util';
6
7const AST_FILE_SCHEME = "rust-analyzer";
8
9// Opens the virtual file that will show the syntax tree
10//
11// The contents of the file come from the `TextDocumentContentProvider`
12export function syntaxTree(ctx: Ctx): Cmd {
13 const tdcp = new TextDocumentContentProvider(ctx);
14
15 void new AstInspector(ctx);
16
17 ctx.pushCleanup(vscode.workspace.registerTextDocumentContentProvider(AST_FILE_SCHEME, tdcp));
18 ctx.pushCleanup(vscode.languages.setLanguageConfiguration("ra_syntax_tree", {
19 brackets: [["[", ")"]],
20 }));
21
22 return async () => {
23 const editor = vscode.window.activeTextEditor;
24 const rangeEnabled = !!editor && !editor.selection.isEmpty;
25
26 const uri = rangeEnabled
27 ? vscode.Uri.parse(`${tdcp.uri.toString()}?range=true`)
28 : tdcp.uri;
29
30 const document = await vscode.workspace.openTextDocument(uri);
31
32 tdcp.eventEmitter.fire(uri);
33
34 void await vscode.window.showTextDocument(document, {
35 viewColumn: vscode.ViewColumn.Two,
36 preserveFocus: true
37 });
38 };
39}
40
41class TextDocumentContentProvider implements vscode.TextDocumentContentProvider {
42 readonly uri = vscode.Uri.parse('rust-analyzer://syntaxtree/tree.rast');
43 readonly eventEmitter = new vscode.EventEmitter<vscode.Uri>();
44
45
46 constructor(private readonly ctx: Ctx) {
47 vscode.workspace.onDidChangeTextDocument(this.onDidChangeTextDocument, this, ctx.subscriptions);
48 vscode.window.onDidChangeActiveTextEditor(this.onDidChangeActiveTextEditor, this, ctx.subscriptions);
49 }
50
51 private onDidChangeTextDocument(event: vscode.TextDocumentChangeEvent) {
52 if (isRustDocument(event.document)) {
53 // We need to order this after language server updates, but there's no API for that.
54 // Hence, good old sleep().
55 void sleep(10).then(() => this.eventEmitter.fire(this.uri));
56 }
57 }
58 private onDidChangeActiveTextEditor(editor: vscode.TextEditor | undefined) {
59 if (editor && isRustEditor(editor)) {
60 this.eventEmitter.fire(this.uri);
61 }
62 }
63
64 provideTextDocumentContent(uri: vscode.Uri, ct: vscode.CancellationToken): vscode.ProviderResult<string> {
65 const rustEditor = this.ctx.activeRustEditor;
66 if (!rustEditor) return '';
67
68 // When the range based query is enabled we take the range of the selection
69 const range = uri.query === 'range=true' && !rustEditor.selection.isEmpty
70 ? this.ctx.client.code2ProtocolConverter.asRange(rustEditor.selection)
71 : null;
72
73 const params = { textDocument: { uri: rustEditor.document.uri.toString() }, range, };
74 return this.ctx.client.sendRequest(ra.syntaxTree, params, ct);
75 }
76
77 get onDidChange(): vscode.Event<vscode.Uri> {
78 return this.eventEmitter.event;
79 }
80}
81 2
3import { Ctx, Disposable } from './ctx';
4import { RustEditor, isRustEditor } from './util';
82 5
83// FIXME: consider implementing this via the Tree View API? 6// FIXME: consider implementing this via the Tree View API?
84// https://code.visualstudio.com/api/extension-guides/tree-view 7// https://code.visualstudio.com/api/extension-guides/tree-view
85class AstInspector implements vscode.HoverProvider, vscode.DefinitionProvider, Disposable { 8export class AstInspector implements vscode.HoverProvider, vscode.DefinitionProvider, Disposable {
86 private readonly astDecorationType = vscode.window.createTextEditorDecorationType({ 9 private readonly astDecorationType = vscode.window.createTextEditorDecorationType({
87 borderColor: new vscode.ThemeColor('rust_analyzer.syntaxTreeBorder'), 10 borderColor: new vscode.ThemeColor('rust_analyzer.syntaxTreeBorder'),
88 borderStyle: "solid", 11 borderStyle: "solid",
89 borderWidth: "2px", 12 borderWidth: "2px",
90
91 }); 13 });
92 private rustEditor: undefined | RustEditor; 14 private rustEditor: undefined | RustEditor;
93 15
@@ -113,7 +35,7 @@ class AstInspector implements vscode.HoverProvider, vscode.DefinitionProvider, D
113 }); 35 });
114 36
115 constructor(ctx: Ctx) { 37 constructor(ctx: Ctx) {
116 ctx.pushCleanup(vscode.languages.registerHoverProvider({ scheme: AST_FILE_SCHEME }, this)); 38 ctx.pushCleanup(vscode.languages.registerHoverProvider({ scheme: 'rust-analyzer' }, this));
117 ctx.pushCleanup(vscode.languages.registerDefinitionProvider({ language: "rust" }, this)); 39 ctx.pushCleanup(vscode.languages.registerDefinitionProvider({ language: "rust" }, this));
118 vscode.workspace.onDidCloseTextDocument(this.onDidCloseTextDocument, this, ctx.subscriptions); 40 vscode.workspace.onDidCloseTextDocument(this.onDidCloseTextDocument, this, ctx.subscriptions);
119 vscode.workspace.onDidChangeTextDocument(this.onDidChangeTextDocument, this, ctx.subscriptions); 41 vscode.workspace.onDidChangeTextDocument(this.onDidChangeTextDocument, this, ctx.subscriptions);
@@ -146,7 +68,7 @@ class AstInspector implements vscode.HoverProvider, vscode.DefinitionProvider, D
146 } 68 }
147 69
148 private findAstTextEditor(): undefined | vscode.TextEditor { 70 private findAstTextEditor(): undefined | vscode.TextEditor {
149 return vscode.window.visibleTextEditors.find(it => it.document.uri.scheme === AST_FILE_SCHEME); 71 return vscode.window.visibleTextEditors.find(it => it.document.uri.scheme === 'rust-analyzer');
150 } 72 }
151 73
152 private setRustEditor(newRustEditor: undefined | RustEditor) { 74 private setRustEditor(newRustEditor: undefined | RustEditor) {
diff --git a/editors/code/src/commands/index.ts b/editors/code/src/commands.ts
index 1585912a2..573af5aa5 100644
--- a/editors/code/src/commands/index.ts
+++ b/editors/code/src/commands.ts
@@ -1,13 +1,16 @@
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';
4 4
5import { Ctx, Cmd } from '../ctx'; 5import { Ctx, Cmd } from './ctx';
6import { applySnippetWorkspaceEdit } from '../snippets'; 6import { applySnippetWorkspaceEdit } from './snippets';
7import { spawnSync } from 'child_process'; 7import { spawnSync } from 'child_process';
8import { RunnableQuickPick, selectRunnable, createTask } from './run';
9import { AstInspector } from './ast_inspector';
10import { isRustDocument, sleep, isRustEditor } from './util';
8 11
9export * from './syntax_tree'; 12export * from './ast_inspector';
10export * from './runnables'; 13export * from './run';
11 14
12export function analyzerStatus(ctx: Ctx): Cmd { 15export function analyzerStatus(ctx: Ctx): Cmd {
13 const tdcp = new class implements vscode.TextDocumentContentProvider { 16 const tdcp = new class implements vscode.TextDocumentContentProvider {
@@ -194,6 +197,90 @@ export function toggleInlayHints(ctx: Ctx): Cmd {
194 }; 197 };
195} 198}
196 199
200export function run(ctx: Ctx): Cmd {
201 let prevRunnable: RunnableQuickPick | undefined;
202
203 return async () => {
204 const item = await selectRunnable(ctx, prevRunnable);
205 if (!item) return;
206
207 item.detail = 'rerun';
208 prevRunnable = item;
209 const task = createTask(item.runnable);
210 return await vscode.tasks.executeTask(task);
211 };
212}
213
214// Opens the virtual file that will show the syntax tree
215//
216// The contents of the file come from the `TextDocumentContentProvider`
217export function syntaxTree(ctx: Ctx): Cmd {
218 const tdcp = new class implements vscode.TextDocumentContentProvider {
219 readonly uri = vscode.Uri.parse('rust-analyzer://syntaxtree/tree.rast');
220 readonly eventEmitter = new vscode.EventEmitter<vscode.Uri>();
221 constructor() {
222 vscode.workspace.onDidChangeTextDocument(this.onDidChangeTextDocument, this, ctx.subscriptions);
223 vscode.window.onDidChangeActiveTextEditor(this.onDidChangeActiveTextEditor, this, ctx.subscriptions);
224 }
225
226 private onDidChangeTextDocument(event: vscode.TextDocumentChangeEvent) {
227 if (isRustDocument(event.document)) {
228 // We need to order this after language server updates, but there's no API for that.
229 // Hence, good old sleep().
230 void sleep(10).then(() => this.eventEmitter.fire(this.uri));
231 }
232 }
233 private onDidChangeActiveTextEditor(editor: vscode.TextEditor | undefined) {
234 if (editor && isRustEditor(editor)) {
235 this.eventEmitter.fire(this.uri);
236 }
237 }
238
239 provideTextDocumentContent(uri: vscode.Uri, ct: vscode.CancellationToken): vscode.ProviderResult<string> {
240 const rustEditor = ctx.activeRustEditor;
241 if (!rustEditor) return '';
242
243 // When the range based query is enabled we take the range of the selection
244 const range = uri.query === 'range=true' && !rustEditor.selection.isEmpty
245 ? ctx.client.code2ProtocolConverter.asRange(rustEditor.selection)
246 : null;
247
248 const params = { textDocument: { uri: rustEditor.document.uri.toString() }, range, };
249 return ctx.client.sendRequest(ra.syntaxTree, params, ct);
250 }
251
252 get onDidChange(): vscode.Event<vscode.Uri> {
253 return this.eventEmitter.event;
254 }
255 };
256
257 void new AstInspector(ctx);
258
259 ctx.pushCleanup(vscode.workspace.registerTextDocumentContentProvider('rust-analyzer', tdcp));
260 ctx.pushCleanup(vscode.languages.setLanguageConfiguration("ra_syntax_tree", {
261 brackets: [["[", ")"]],
262 }));
263
264 return async () => {
265 const editor = vscode.window.activeTextEditor;
266 const rangeEnabled = !!editor && !editor.selection.isEmpty;
267
268 const uri = rangeEnabled
269 ? vscode.Uri.parse(`${tdcp.uri.toString()}?range=true`)
270 : tdcp.uri;
271
272 const document = await vscode.workspace.openTextDocument(uri);
273
274 tdcp.eventEmitter.fire(uri);
275
276 void await vscode.window.showTextDocument(document, {
277 viewColumn: vscode.ViewColumn.Two,
278 preserveFocus: true
279 });
280 };
281}
282
283
197// Opens the virtual file that will show the syntax tree 284// Opens the virtual file that will show the syntax tree
198// 285//
199// The contents of the file come from the `TextDocumentContentProvider` 286// The contents of the file come from the `TextDocumentContentProvider`
diff --git a/editors/code/src/main.ts b/editors/code/src/main.ts
index 0e5a20641..31ac81ee8 100644
--- a/editors/code/src/main.ts
+++ b/editors/code/src/main.ts
@@ -92,7 +92,6 @@ export async function activate(context: vscode.ExtensionContext) {
92 ctx.registerCommand('runSingle', commands.runSingle); 92 ctx.registerCommand('runSingle', commands.runSingle);
93 ctx.registerCommand('debugSingle', commands.debugSingle); 93 ctx.registerCommand('debugSingle', commands.debugSingle);
94 ctx.registerCommand('showReferences', commands.showReferences); 94 ctx.registerCommand('showReferences', commands.showReferences);
95 ctx.registerCommand('applySourceChange', commands.applySourceChange);
96 ctx.registerCommand('applySnippetWorkspaceEdit', commands.applySnippetWorkspaceEditCommand); 95 ctx.registerCommand('applySnippetWorkspaceEdit', commands.applySnippetWorkspaceEditCommand);
97 ctx.registerCommand('applyActionGroup', commands.applyActionGroup); 96 ctx.registerCommand('applyActionGroup', commands.applyActionGroup);
98 97
diff --git a/editors/code/src/commands/runnables.ts b/editors/code/src/run.ts
index 0bd30fb07..8f0487d74 100644
--- a/editors/code/src/commands/runnables.ts
+++ b/editors/code/src/run.ts
@@ -1,13 +1,13 @@
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';
4 4
5import { Ctx, Cmd } from '../ctx'; 5import { Ctx, Cmd } from './ctx';
6import { startDebugSession, getDebugConfiguration } from '../debug'; 6import { startDebugSession, getDebugConfiguration } from './debug';
7 7
8const quickPickButtons = [{ iconPath: new vscode.ThemeIcon("save"), tooltip: "Save as a launch.json configurtation." }]; 8const quickPickButtons = [{ iconPath: new vscode.ThemeIcon("save"), tooltip: "Save as a launch.json configurtation." }];
9 9
10async function selectRunnable(ctx: Ctx, prevRunnable?: RunnableQuickPick, debuggeeOnly = false, showButtons: boolean = true): Promise<RunnableQuickPick | undefined> { 10export async function selectRunnable(ctx: Ctx, prevRunnable?: RunnableQuickPick, debuggeeOnly = false, showButtons: boolean = true): Promise<RunnableQuickPick | undefined> {
11 const editor = ctx.activeRustEditor; 11 const editor = ctx.activeRustEditor;
12 const client = ctx.client; 12 const client = ctx.client;
13 if (!editor || !client) return; 13 if (!editor || !client) return;
@@ -83,20 +83,6 @@ async function selectRunnable(ctx: Ctx, prevRunnable?: RunnableQuickPick, debugg
83 }); 83 });
84} 84}
85 85
86export 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
100export function runSingle(ctx: Ctx): Cmd { 86export function runSingle(ctx: Ctx): Cmd {
101 return async (runnable: ra.Runnable) => { 87 return async (runnable: ra.Runnable) => {
102 const editor = ctx.activeRustEditor; 88 const editor = ctx.activeRustEditor;
@@ -165,7 +151,7 @@ export function newDebugConfig(ctx: Ctx): Cmd {
165 }; 151 };
166} 152}
167 153
168class RunnableQuickPick implements vscode.QuickPickItem { 154export class RunnableQuickPick implements vscode.QuickPickItem {
169 public label: string; 155 public label: string;
170 public description?: string | undefined; 156 public description?: string | undefined;
171 public detail?: string | undefined; 157 public detail?: string | undefined;
@@ -184,7 +170,7 @@ interface CargoTaskDefinition extends vscode.TaskDefinition {
184 env?: { [key: string]: string }; 170 env?: { [key: string]: string };
185} 171}
186 172
187function createTask(spec: ra.Runnable): vscode.Task { 173export function createTask(spec: ra.Runnable): vscode.Task {
188 const TASK_SOURCE = 'Rust'; 174 const TASK_SOURCE = 'Rust';
189 const definition: CargoTaskDefinition = { 175 const definition: CargoTaskDefinition = {
190 type: 'cargo', 176 type: 'cargo',