Privatize highlighting

This commit is contained in:
Aleksey Kladov 2019-12-30 23:12:33 +01:00
parent cdd7118cbf
commit 233f1dd2a8
8 changed files with 54 additions and 48 deletions

View file

@ -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')) {

View file

@ -62,23 +62,30 @@ export class Ctx {
this.extCtx.subscriptions.push(d);
}
async sendRequestWithRetry<R>(method: string, param: any, token: vscode.CancellationToken): Promise<R> {
async sendRequestWithRetry<R>(
method: string,
param: any,
token: vscode.CancellationToken,
): Promise<R> {
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));

View file

@ -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

View file

@ -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<InlayHint[] | null>(
@ -112,7 +112,7 @@ class HintsUpdater {
);
} finally {
if (!tokenSource.token.isCancellationRequested) {
this.pending.delete(documentUri)
this.pending.delete(documentUri);
}
}
}

View file

@ -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);
}

View file

@ -1,3 +0,0 @@
import * as publishDecorations from './publish_decorations';
export { publishDecorations };

View file

@ -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);
}

View file

@ -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;