aboutsummaryrefslogtreecommitdiff
path: root/editors/code/src/commands/inlay_hints.ts
diff options
context:
space:
mode:
Diffstat (limited to 'editors/code/src/commands/inlay_hints.ts')
-rw-r--r--editors/code/src/commands/inlay_hints.ts109
1 files changed, 109 insertions, 0 deletions
diff --git a/editors/code/src/commands/inlay_hints.ts b/editors/code/src/commands/inlay_hints.ts
new file mode 100644
index 000000000..3ba9da48b
--- /dev/null
+++ b/editors/code/src/commands/inlay_hints.ts
@@ -0,0 +1,109 @@
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 if (newHints != null) {
84 const newDecorations = newHints.map(hint => ({
85 range: hint.range,
86 renderOptions: { after: { contentText: `: ${hint.label}` } }
87 }));
88 return editor.setDecorations(
89 typeHintDecorationType,
90 newDecorations
91 );
92 }
93 }
94
95 private async queryHints(documentUri: string): Promise<InlayHint[] | null> {
96 const request: InlayHintsParams = {
97 textDocument: { uri: documentUri }
98 };
99 const client = Server.client;
100 return client
101 .onReady()
102 .then(() =>
103 client.sendRequest<InlayHint[] | null>(
104 'rust-analyzer/inlayHints',
105 request
106 )
107 );
108 }
109}