1 import * as vscode from 'vscode';
2 import * as lc from 'vscode-languageclient';
4 import { Ctx } from './ctx';
6 export function activateInlayHints(ctx: Ctx) {
7 const hintsUpdater = new HintsUpdater(ctx);
8 vscode.window.onDidChangeVisibleTextEditors(async _ => {
9 await hintsUpdater.refresh();
10 }, ctx.subscriptions);
12 vscode.workspace.onDidChangeTextDocument(async e => {
13 if (e.contentChanges.length === 0) return;
14 if (e.document.languageId !== 'rust') return;
15 await hintsUpdater.refresh();
16 }, ctx.subscriptions);
18 vscode.workspace.onDidChangeConfiguration(_ => {
19 hintsUpdater.setEnabled(ctx.config.displayInlayHints);
20 }, ctx.subscriptions);
22 // XXX: don't await here;
23 // Who knows what happens if an exception is thrown here...
24 hintsUpdater.refresh();
27 interface InlayHintsParams {
28 textDocument: lc.TextDocumentIdentifier;
37 const typeHintDecorationType = vscode.window.createTextEditorDecorationType({
39 color: new vscode.ThemeColor('ralsp.inlayHint'),
45 private enabled = true;
47 constructor(ctx: Ctx) {
51 async setEnabled(enabled: boolean) {
52 if (this.enabled == enabled) return;
53 this.enabled = enabled;
58 this.allEditors.forEach(it => this.setDecorations(it, []));
63 if (!this.enabled) return;
64 const promises = this.allEditors.map(it => this.refreshEditor(it));
65 await Promise.all(promises);
68 private async refreshEditor(editor: vscode.TextEditor): Promise<void> {
69 const newHints = await this.queryHints(editor.document.uri.toString());
70 const newDecorations = (newHints ? newHints : []).map(hint => ({
74 contentText: `: ${hint.label}`,
78 this.setDecorations(editor, newDecorations);
81 private get allEditors(): vscode.TextEditor[] {
82 return vscode.window.visibleTextEditors.filter(
83 editor => editor.document.languageId === 'rust',
87 private setDecorations(
88 editor: vscode.TextEditor,
89 decorations: vscode.DecorationOptions[],
91 editor.setDecorations(
92 typeHintDecorationType,
93 this.enabled ? decorations : [],
97 private async queryHints(documentUri: string): Promise<InlayHint[] | null> {
98 const request: InlayHintsParams = {
99 textDocument: { uri: documentUri },
101 return this.ctx.sendRequestWithRetry<InlayHint[] | null>(
102 'rust-analyzer/inlayHints',