mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-28 21:05:02 +00:00
Privatize highlighting
This commit is contained in:
parent
cdd7118cbf
commit
233f1dd2a8
8 changed files with 54 additions and 48 deletions
|
@ -1,7 +1,6 @@
|
||||||
import * as vscode from 'vscode';
|
import * as vscode from 'vscode';
|
||||||
import * as scopes from './scopes';
|
import * as scopes from './scopes';
|
||||||
import * as scopesMapper from './scopes_mapper';
|
import * as scopesMapper from './scopes_mapper';
|
||||||
import { Server } from './server';
|
|
||||||
|
|
||||||
const RA_LSP_DEBUG = process.env.__RA_LSP_SERVER_DEBUG;
|
const RA_LSP_DEBUG = process.env.__RA_LSP_SERVER_DEBUG;
|
||||||
|
|
||||||
|
@ -56,8 +55,6 @@ export class Config {
|
||||||
public userConfigChanged() {
|
public userConfigChanged() {
|
||||||
const config = vscode.workspace.getConfiguration('rust-analyzer');
|
const config = vscode.workspace.getConfiguration('rust-analyzer');
|
||||||
|
|
||||||
Server.highlighter.removeHighlights();
|
|
||||||
|
|
||||||
let requireReloadMessage = null;
|
let requireReloadMessage = null;
|
||||||
|
|
||||||
if (config.has('highlightingOn')) {
|
if (config.has('highlightingOn')) {
|
||||||
|
|
|
@ -62,23 +62,30 @@ export class Ctx {
|
||||||
this.extCtx.subscriptions.push(d);
|
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();
|
await this.client.onReady();
|
||||||
for (const delay of [2, 4, 6, 8, 10, null]) {
|
for (const delay of [2, 4, 6, 8, 10, null]) {
|
||||||
try {
|
try {
|
||||||
return await this.client.sendRequest(method, param, token);
|
return await this.client.sendRequest(method, param, token);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (e.code === lc.ErrorCodes.ContentModified && delay !== null) {
|
if (
|
||||||
await sleep(10 * (1 << delay))
|
e.code === lc.ErrorCodes.ContentModified &&
|
||||||
|
delay !== null
|
||||||
|
) {
|
||||||
|
await sleep(10 * (1 << delay));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw 'unreachable'
|
throw 'unreachable';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export type Cmd = (...args: any[]) => any;
|
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));
|
||||||
|
|
|
@ -10,6 +10,36 @@ import { Server } from './server';
|
||||||
import { Ctx } from './ctx';
|
import { Ctx } from './ctx';
|
||||||
|
|
||||||
export function activateHighlighting(ctx: 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(
|
vscode.window.onDidChangeActiveTextEditor(
|
||||||
async (editor: vscode.TextEditor | undefined) => {
|
async (editor: vscode.TextEditor | undefined) => {
|
||||||
if (!editor || editor.document.languageId !== 'rust') return;
|
if (!editor || editor.document.languageId !== 'rust') return;
|
||||||
|
@ -22,11 +52,17 @@ export function activateHighlighting(ctx: Ctx) {
|
||||||
'rust-analyzer/decorationsRequest',
|
'rust-analyzer/decorationsRequest',
|
||||||
params,
|
params,
|
||||||
);
|
);
|
||||||
Server.highlighter.setHighlights(editor, decorations);
|
highlighter.setHighlights(editor, decorations);
|
||||||
},
|
},
|
||||||
|
ctx.subscriptions,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface PublishDecorationsParams {
|
||||||
|
uri: string;
|
||||||
|
decorations: Decoration[];
|
||||||
|
}
|
||||||
|
|
||||||
export interface Decoration {
|
export interface Decoration {
|
||||||
range: lc.Range;
|
range: lc.Range;
|
||||||
tag: string;
|
tag: string;
|
||||||
|
@ -81,7 +117,7 @@ function createDecorationFromTextmate(
|
||||||
return vscode.window.createTextEditorDecorationType(decorationOptions);
|
return vscode.window.createTextEditorDecorationType(decorationOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Highlighter {
|
class Highlighter {
|
||||||
private static initDecorations(): Map<
|
private static initDecorations(): Map<
|
||||||
string,
|
string,
|
||||||
vscode.TextEditorDecorationType
|
vscode.TextEditorDecorationType
|
||||||
|
|
|
@ -102,7 +102,7 @@ class HintsUpdater {
|
||||||
};
|
};
|
||||||
let tokenSource = new vscode.CancellationTokenSource();
|
let tokenSource = new vscode.CancellationTokenSource();
|
||||||
let prev = this.pending.get(documentUri);
|
let prev = this.pending.get(documentUri);
|
||||||
if (prev) prev.cancel()
|
if (prev) prev.cancel();
|
||||||
this.pending.set(documentUri, tokenSource);
|
this.pending.set(documentUri, tokenSource);
|
||||||
try {
|
try {
|
||||||
return await this.ctx.sendRequestWithRetry<InlayHint[] | null>(
|
return await this.ctx.sendRequestWithRetry<InlayHint[] | null>(
|
||||||
|
@ -112,7 +112,7 @@ class HintsUpdater {
|
||||||
);
|
);
|
||||||
} finally {
|
} finally {
|
||||||
if (!tokenSource.token.isCancellationRequested) {
|
if (!tokenSource.token.isCancellationRequested) {
|
||||||
this.pending.delete(documentUri)
|
this.pending.delete(documentUri);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,6 @@ import * as lc from 'vscode-languageclient';
|
||||||
import * as commands from './commands';
|
import * as commands from './commands';
|
||||||
import { activateInlayHints } from './inlay_hints';
|
import { activateInlayHints } from './inlay_hints';
|
||||||
import { StatusDisplay } from './status_display';
|
import { StatusDisplay } from './status_display';
|
||||||
import * as notifications from './notifications';
|
|
||||||
import { Server } from './server';
|
import { Server } from './server';
|
||||||
import { Ctx } from './ctx';
|
import { Ctx } from './ctx';
|
||||||
import { activateHighlighting } from './highlighting';
|
import { activateHighlighting } from './highlighting';
|
||||||
|
@ -35,14 +34,8 @@ export async function activate(context: vscode.ExtensionContext) {
|
||||||
const watchStatus = new StatusDisplay(ctx.config.cargoWatchOptions.command);
|
const watchStatus = new StatusDisplay(ctx.config.cargoWatchOptions.command);
|
||||||
ctx.pushCleanup(watchStatus);
|
ctx.pushCleanup(watchStatus);
|
||||||
|
|
||||||
activateHighlighting(ctx);
|
|
||||||
|
|
||||||
// Notifications are events triggered by the language server
|
// Notifications are events triggered by the language server
|
||||||
const allNotifications: [string, lc.GenericNotificationHandler][] = [
|
const allNotifications: [string, lc.GenericNotificationHandler][] = [
|
||||||
[
|
|
||||||
'rust-analyzer/publishDecorations',
|
|
||||||
notifications.publishDecorations.handle,
|
|
||||||
],
|
|
||||||
[
|
[
|
||||||
'$/progress',
|
'$/progress',
|
||||||
params => watchStatus.handleProgressNotification(params),
|
params => watchStatus.handleProgressNotification(params),
|
||||||
|
@ -61,6 +54,8 @@ export async function activate(context: vscode.ExtensionContext) {
|
||||||
vscode.window.showErrorMessage(e.message);
|
vscode.window.showErrorMessage(e.message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
activateHighlighting(ctx);
|
||||||
|
|
||||||
if (ctx.config.displayInlayHints) {
|
if (ctx.config.displayInlayHints) {
|
||||||
activateInlayHints(ctx);
|
activateInlayHints(ctx);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
import * as publishDecorations from './publish_decorations';
|
|
||||||
|
|
||||||
export { publishDecorations };
|
|
|
@ -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);
|
|
||||||
}
|
|
|
@ -3,7 +3,6 @@ import * as lc from 'vscode-languageclient';
|
||||||
|
|
||||||
import { window, workspace } from 'vscode';
|
import { window, workspace } from 'vscode';
|
||||||
import { Config } from './config';
|
import { Config } from './config';
|
||||||
import { Highlighter } from './highlighting';
|
|
||||||
|
|
||||||
function expandPathResolving(path: string) {
|
function expandPathResolving(path: string) {
|
||||||
if (path.startsWith('~/')) {
|
if (path.startsWith('~/')) {
|
||||||
|
@ -13,7 +12,6 @@ function expandPathResolving(path: string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Server {
|
export class Server {
|
||||||
public static highlighter = new Highlighter();
|
|
||||||
public static config = new Config();
|
public static config = new Config();
|
||||||
public static client: lc.LanguageClient;
|
public static client: lc.LanguageClient;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue