diff --git a/editors/code/src/config.ts b/editors/code/src/config.ts index a88be6e350..2bd276958f 100644 --- a/editors/code/src/config.ts +++ b/editors/code/src/config.ts @@ -1,7 +1,6 @@ import * as vscode from 'vscode'; import * as scopes from './scopes'; import * as scopesMapper from './scopes_mapper'; -import { Server } from './server'; const RA_LSP_DEBUG = process.env.__RA_LSP_SERVER_DEBUG; @@ -56,8 +55,6 @@ export class Config { public userConfigChanged() { const config = vscode.workspace.getConfiguration('rust-analyzer'); - Server.highlighter.removeHighlights(); - let requireReloadMessage = null; if (config.has('highlightingOn')) { diff --git a/editors/code/src/ctx.ts b/editors/code/src/ctx.ts index d3ef27e430..39eddfcbdf 100644 --- a/editors/code/src/ctx.ts +++ b/editors/code/src/ctx.ts @@ -62,23 +62,30 @@ export class Ctx { this.extCtx.subscriptions.push(d); } - async sendRequestWithRetry(method: string, param: any, token: vscode.CancellationToken): Promise { + async sendRequestWithRetry( + method: string, + param: any, + token: vscode.CancellationToken, + ): Promise { await this.client.onReady(); for (const delay of [2, 4, 6, 8, 10, null]) { try { return await this.client.sendRequest(method, param, token); } catch (e) { - if (e.code === lc.ErrorCodes.ContentModified && delay !== null) { - await sleep(10 * (1 << delay)) + if ( + e.code === lc.ErrorCodes.ContentModified && + delay !== null + ) { + await sleep(10 * (1 << delay)); continue; } throw e; } } - throw 'unreachable' + throw 'unreachable'; } } export type Cmd = (...args: any[]) => any; -const sleep = (ms: number) => new Promise(resolve => setTimeout(resolve, ms)) +const sleep = (ms: number) => new Promise(resolve => setTimeout(resolve, ms)); diff --git a/editors/code/src/highlighting.ts b/editors/code/src/highlighting.ts index 333319b850..c7ee8c0a16 100644 --- a/editors/code/src/highlighting.ts +++ b/editors/code/src/highlighting.ts @@ -10,6 +10,36 @@ import { Server } from './server'; import { Ctx } from './ctx'; export function activateHighlighting(ctx: Ctx) { + const highlighter = new Highlighter(); + + ctx.client.onReady().then(() => { + ctx.client.onNotification( + 'rust-analyzer/publishDecorations', + (params: PublishDecorationsParams) => { + if (!ctx.config.highlightingOn) return; + + const targetEditor = vscode.window.visibleTextEditors.find( + editor => { + const unescapedUri = unescape( + editor.document.uri.toString(), + ); + // Unescaped URI looks like: + // file:///c:/Workspace/ra-test/src/main.rs + return unescapedUri === params.uri; + }, + ); + if (!targetEditor) return; + + highlighter.setHighlights(targetEditor, params.decorations); + }, + ); + }); + + vscode.workspace.onDidChangeConfiguration( + _ => highlighter.removeHighlights(), + ctx.subscriptions, + ); + vscode.window.onDidChangeActiveTextEditor( async (editor: vscode.TextEditor | undefined) => { if (!editor || editor.document.languageId !== 'rust') return; @@ -22,11 +52,17 @@ export function activateHighlighting(ctx: Ctx) { 'rust-analyzer/decorationsRequest', params, ); - Server.highlighter.setHighlights(editor, decorations); + highlighter.setHighlights(editor, decorations); }, + ctx.subscriptions, ); } +interface PublishDecorationsParams { + uri: string; + decorations: Decoration[]; +} + export interface Decoration { range: lc.Range; tag: string; @@ -81,7 +117,7 @@ function createDecorationFromTextmate( return vscode.window.createTextEditorDecorationType(decorationOptions); } -export class Highlighter { +class Highlighter { private static initDecorations(): Map< string, vscode.TextEditorDecorationType diff --git a/editors/code/src/inlay_hints.ts b/editors/code/src/inlay_hints.ts index d41297407e..a7be97db87 100644 --- a/editors/code/src/inlay_hints.ts +++ b/editors/code/src/inlay_hints.ts @@ -102,7 +102,7 @@ class HintsUpdater { }; let tokenSource = new vscode.CancellationTokenSource(); let prev = this.pending.get(documentUri); - if (prev) prev.cancel() + if (prev) prev.cancel(); this.pending.set(documentUri, tokenSource); try { return await this.ctx.sendRequestWithRetry( @@ -112,7 +112,7 @@ class HintsUpdater { ); } finally { if (!tokenSource.token.isCancellationRequested) { - this.pending.delete(documentUri) + this.pending.delete(documentUri); } } } diff --git a/editors/code/src/main.ts b/editors/code/src/main.ts index 345ae06856..20a3ea1197 100644 --- a/editors/code/src/main.ts +++ b/editors/code/src/main.ts @@ -4,7 +4,6 @@ import * as lc from 'vscode-languageclient'; import * as commands from './commands'; import { activateInlayHints } from './inlay_hints'; import { StatusDisplay } from './status_display'; -import * as notifications from './notifications'; import { Server } from './server'; import { Ctx } from './ctx'; import { activateHighlighting } from './highlighting'; @@ -35,14 +34,8 @@ export async function activate(context: vscode.ExtensionContext) { const watchStatus = new StatusDisplay(ctx.config.cargoWatchOptions.command); ctx.pushCleanup(watchStatus); - activateHighlighting(ctx); - // Notifications are events triggered by the language server const allNotifications: [string, lc.GenericNotificationHandler][] = [ - [ - 'rust-analyzer/publishDecorations', - notifications.publishDecorations.handle, - ], [ '$/progress', params => watchStatus.handleProgressNotification(params), @@ -61,6 +54,8 @@ export async function activate(context: vscode.ExtensionContext) { vscode.window.showErrorMessage(e.message); } + activateHighlighting(ctx); + if (ctx.config.displayInlayHints) { activateInlayHints(ctx); } diff --git a/editors/code/src/notifications/index.ts b/editors/code/src/notifications/index.ts deleted file mode 100644 index 74c4c35637..0000000000 --- a/editors/code/src/notifications/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -import * as publishDecorations from './publish_decorations'; - -export { publishDecorations }; diff --git a/editors/code/src/notifications/publish_decorations.ts b/editors/code/src/notifications/publish_decorations.ts deleted file mode 100644 index f23e286ad5..0000000000 --- a/editors/code/src/notifications/publish_decorations.ts +++ /dev/null @@ -1,24 +0,0 @@ -import * as vscode from 'vscode'; - -import { Decoration } from '../highlighting'; -import { Server } from '../server'; - -export interface PublishDecorationsParams { - uri: string; - decorations: Decoration[]; -} - -export function handle(params: PublishDecorationsParams) { - const targetEditor = vscode.window.visibleTextEditors.find(editor => { - const unescapedUri = unescape(editor.document.uri.toString()); - // Unescaped URI looks like: - // file:///c:/Workspace/ra-test/src/main.rs - return unescapedUri === params.uri; - }); - - if (!Server.config.highlightingOn || !targetEditor) { - return; - } - - Server.highlighter.setHighlights(targetEditor, params.decorations); -} diff --git a/editors/code/src/server.ts b/editors/code/src/server.ts index 10dc079fb4..2bb21da6be 100644 --- a/editors/code/src/server.ts +++ b/editors/code/src/server.ts @@ -3,7 +3,6 @@ import * as lc from 'vscode-languageclient'; import { window, workspace } from 'vscode'; import { Config } from './config'; -import { Highlighter } from './highlighting'; function expandPathResolving(path: string) { if (path.startsWith('~/')) { @@ -13,7 +12,6 @@ function expandPathResolving(path: string) { } export class Server { - public static highlighter = new Highlighter(); public static config = new Config(); public static client: lc.LanguageClient;