aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--editors/code/package.json14
-rw-r--r--editors/code/src/commands/index.ts4
-rw-r--r--editors/code/src/commands/inlay_hints.ts104
-rw-r--r--editors/code/src/config.ts5
-rw-r--r--editors/code/src/extension.ts24
5 files changed, 150 insertions, 1 deletions
diff --git a/editors/code/package.json b/editors/code/package.json
index fd30c7946..060a3a247 100644
--- a/editors/code/package.json
+++ b/editors/code/package.json
@@ -238,6 +238,11 @@
238 "type": "number", 238 "type": "number",
239 "default": null, 239 "default": null,
240 "description": "Number of syntax trees rust-analyzer keeps in memory" 240 "description": "Number of syntax trees rust-analyzer keeps in memory"
241 },
242 "rust-analyzer.displayInlayHints": {
243 "type": "boolean",
244 "default": true,
245 "description": "Display additional type information in the editor"
241 } 246 }
242 } 247 }
243 }, 248 },
@@ -444,6 +449,15 @@
444 "light": "#000000", 449 "light": "#000000",
445 "highContrast": "#FFFFFF" 450 "highContrast": "#FFFFFF"
446 } 451 }
452 },
453 {
454 "id": "ralsp.inlayHint",
455 "description": "Color for inlay hints",
456 "defaults": {
457 "dark": "#A0A0A0F0",
458 "light": "#747474",
459 "highContrast": "#BEBEBE"
460 }
447 } 461 }
448 ] 462 ]
449 } 463 }
diff --git a/editors/code/src/commands/index.ts b/editors/code/src/commands/index.ts
index 194658497..c194bd2ea 100644
--- a/editors/code/src/commands/index.ts
+++ b/editors/code/src/commands/index.ts
@@ -1,5 +1,6 @@
1import * as analyzerStatus from './analyzer_status'; 1import * as analyzerStatus from './analyzer_status';
2import * as applySourceChange from './apply_source_change'; 2import * as applySourceChange from './apply_source_change';
3import * as inlayHints from './inlay_hints';
3import * as joinLines from './join_lines'; 4import * as joinLines from './join_lines';
4import * as matchingBrace from './matching_brace'; 5import * as matchingBrace from './matching_brace';
5import * as onEnter from './on_enter'; 6import * as onEnter from './on_enter';
@@ -15,5 +16,6 @@ export {
15 parentModule, 16 parentModule,
16 runnables, 17 runnables,
17 syntaxTree, 18 syntaxTree,
18 onEnter 19 onEnter,
20 inlayHints
19}; 21};
diff --git a/editors/code/src/commands/inlay_hints.ts b/editors/code/src/commands/inlay_hints.ts
new file mode 100644
index 000000000..8154af8dc
--- /dev/null
+++ b/editors/code/src/commands/inlay_hints.ts
@@ -0,0 +1,104 @@
1import * as vscode from 'vscode';
2import { Range, TextDocumentChangeEvent, TextEditor } from 'vscode';
3import { TextDocumentIdentifier } from 'vscode-languageclient';
4import { Server } from '../server';
5
6interface InlayHintsParams {
7 textDocument: TextDocumentIdentifier;
8}
9
10interface InlayHint {
11 range: Range;
12 kind: string;
13 label: string;
14}
15
16const typeHintDecorationType = vscode.window.createTextEditorDecorationType({
17 after: {
18 color: new vscode.ThemeColor('ralsp.inlayHint')
19 }
20});
21
22export class HintsUpdater {
23 private displayHints = true;
24
25 public async loadHints(
26 editor: vscode.TextEditor | undefined
27 ): Promise<void> {
28 if (
29 this.displayHints &&
30 editor !== undefined &&
31 this.isRustDocument(editor.document)
32 ) {
33 await this.updateDecorationsFromServer(
34 editor.document.uri.toString(),
35 editor
36 );
37 }
38 }
39
40 public async toggleHintsDisplay(displayHints: boolean): Promise<void> {
41 if (this.displayHints !== displayHints) {
42 this.displayHints = displayHints;
43
44 if (displayHints) {
45 return this.updateHints();
46 } else {
47 const editor = vscode.window.activeTextEditor;
48 if (editor != null) {
49 return editor.setDecorations(typeHintDecorationType, []);
50 }
51 }
52 }
53 }
54
55 public async updateHints(cause?: TextDocumentChangeEvent): Promise<void> {
56 if (!this.displayHints) {
57 return;
58 }
59 const editor = vscode.window.activeTextEditor;
60 if (editor == null) {
61 return;
62 }
63 const document = cause == null ? editor.document : cause.document;
64 if (!this.isRustDocument(document)) {
65 return;
66 }
67
68 return await this.updateDecorationsFromServer(
69 document.uri.toString(),
70 editor
71 );
72 }
73
74 private isRustDocument(document: vscode.TextDocument): boolean {
75 return document && document.languageId === 'rust';
76 }
77
78 private async updateDecorationsFromServer(
79 documentUri: string,
80 editor: TextEditor
81 ): Promise<void> {
82 const newHints = (await this.queryHints(documentUri)) || [];
83 const newDecorations = newHints.map(hint => ({
84 range: hint.range,
85 renderOptions: { after: { contentText: `: ${hint.label}` } }
86 }));
87 return editor.setDecorations(typeHintDecorationType, newDecorations);
88 }
89
90 private async queryHints(documentUri: string): Promise<InlayHint[] | null> {
91 const request: InlayHintsParams = {
92 textDocument: { uri: documentUri }
93 };
94 const client = Server.client;
95 return client
96 .onReady()
97 .then(() =>
98 client.sendRequest<InlayHint[] | null>(
99 'rust-analyzer/inlayHints',
100 request
101 )
102 );
103 }
104}
diff --git a/editors/code/src/config.ts b/editors/code/src/config.ts
index 3f1b482e3..4d58a1a93 100644
--- a/editors/code/src/config.ts
+++ b/editors/code/src/config.ts
@@ -21,6 +21,7 @@ export class Config {
21 public raLspServerPath = RA_LSP_DEBUG || 'ra_lsp_server'; 21 public raLspServerPath = RA_LSP_DEBUG || 'ra_lsp_server';
22 public showWorkspaceLoadedNotification = true; 22 public showWorkspaceLoadedNotification = true;
23 public lruCapacity: null | number = null; 23 public lruCapacity: null | number = null;
24 public displayInlayHints = true;
24 public cargoWatchOptions: CargoWatchOptions = { 25 public cargoWatchOptions: CargoWatchOptions = {
25 enableOnStartup: 'ask', 26 enableOnStartup: 'ask',
26 trace: 'off', 27 trace: 'off',
@@ -123,5 +124,9 @@ export class Config {
123 if (config.has('lruCapacity')) { 124 if (config.has('lruCapacity')) {
124 this.lruCapacity = config.get('lruCapacity') as number; 125 this.lruCapacity = config.get('lruCapacity') as number;
125 } 126 }
127
128 if (config.has('displayInlayHints')) {
129 this.displayInlayHints = config.get('displayInlayHints') as boolean;
130 }
126 } 131 }
127} 132}
diff --git a/editors/code/src/extension.ts b/editors/code/src/extension.ts
index c8c3004a7..c6efc2e7e 100644
--- a/editors/code/src/extension.ts
+++ b/editors/code/src/extension.ts
@@ -3,6 +3,7 @@ import * as lc from 'vscode-languageclient';
3 3
4import * as commands from './commands'; 4import * as commands from './commands';
5import { CargoWatchProvider } from './commands/cargo_watch'; 5import { CargoWatchProvider } from './commands/cargo_watch';
6import { HintsUpdater } from './commands/inlay_hints';
6import { 7import {
7 interactivelyStartCargoWatch, 8 interactivelyStartCargoWatch,
8 startCargoWatch 9 startCargoWatch
@@ -147,6 +148,29 @@ export function activate(context: vscode.ExtensionContext) {
147 148
148 // Start the language server, finally! 149 // Start the language server, finally!
149 startServer(); 150 startServer();
151
152 if (Server.config.displayInlayHints) {
153 const hintsUpdater = new HintsUpdater();
154 hintsUpdater.loadHints(vscode.window.activeTextEditor).then(() => {
155 disposeOnDeactivation(
156 vscode.window.onDidChangeActiveTextEditor(editor =>
157 hintsUpdater.loadHints(editor)
158 )
159 );
160 disposeOnDeactivation(
161 vscode.workspace.onDidChangeTextDocument(e =>
162 hintsUpdater.updateHints(e)
163 )
164 );
165 disposeOnDeactivation(
166 vscode.workspace.onDidChangeConfiguration(_ =>
167 hintsUpdater.toggleHintsDisplay(
168 Server.config.displayInlayHints
169 )
170 )
171 );
172 });
173 }
150} 174}
151 175
152export function deactivate(): Thenable<void> { 176export function deactivate(): Thenable<void> {