mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-08-22 11:24:24 +00:00
Merge #3820
3820: Remove old syntax highlighting r=matklad a=matklad
bors r+
🤖
Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
This commit is contained in:
commit
98f7842e40
9 changed files with 3 additions and 359 deletions
|
@ -7,7 +7,6 @@ import { SemanticTokensFeature, DocumentSemanticsTokensSignature } from 'vscode-
|
|||
|
||||
export function configToServerOptions(config: Config) {
|
||||
return {
|
||||
publishDecorations: !config.highlightingSemanticTokens,
|
||||
lruCapacity: config.lruCapacity,
|
||||
|
||||
inlayHintsType: config.inlayHints.typeHints,
|
||||
|
|
|
@ -71,8 +71,6 @@ export class Config {
|
|||
get channel() { return this.cfg.get<UpdatesChannel>("updates.channel")!; }
|
||||
get askBeforeDownload() { return this.cfg.get<boolean>("updates.askBeforeDownload")!; }
|
||||
get highlightingSemanticTokens() { return this.cfg.get<boolean>("highlighting.semanticTokens")!; }
|
||||
get highlightingOn() { return this.cfg.get<boolean>("highlightingOn")!; }
|
||||
get rainbowHighlightingOn() { return this.cfg.get<boolean>("rainbowHighlightingOn")!; }
|
||||
get lruCapacity() { return this.cfg.get<null | number>("lruCapacity")!; }
|
||||
get excludeGlobs() { return this.cfg.get<string[]>("excludeGlobs")!; }
|
||||
get useClientWatching() { return this.cfg.get<boolean>("useClientWatching")!; }
|
||||
|
|
|
@ -1,255 +0,0 @@
|
|||
import * as vscode from 'vscode';
|
||||
import * as ra from './rust-analyzer-api';
|
||||
|
||||
import { ColorTheme, TextMateRuleSettings } from './color_theme';
|
||||
|
||||
import { Ctx } from './ctx';
|
||||
import { sendRequestWithRetry, isRustDocument } from './util';
|
||||
|
||||
export function activateHighlighting(ctx: Ctx) {
|
||||
const highlighter = new Highlighter(ctx);
|
||||
|
||||
ctx.client.onNotification(ra.publishDecorations, params => {
|
||||
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(),
|
||||
null,
|
||||
ctx.subscriptions,
|
||||
);
|
||||
|
||||
vscode.window.onDidChangeActiveTextEditor(
|
||||
async (editor: vscode.TextEditor | undefined) => {
|
||||
if (!editor || !isRustDocument(editor.document)) return;
|
||||
if (!ctx.config.highlightingOn) return;
|
||||
const client = ctx.client;
|
||||
if (!client) return;
|
||||
|
||||
const decorations = await sendRequestWithRetry(
|
||||
client,
|
||||
ra.decorationsRequest,
|
||||
{ uri: editor.document.uri.toString() },
|
||||
);
|
||||
highlighter.setHighlights(editor, decorations);
|
||||
},
|
||||
null,
|
||||
ctx.subscriptions,
|
||||
);
|
||||
}
|
||||
|
||||
// Based on this HSL-based color generator: https://gist.github.com/bendc/76c48ce53299e6078a76
|
||||
function fancify(seed: string, shade: 'light' | 'dark') {
|
||||
const random = randomU32Numbers(hashString(seed));
|
||||
const randomInt = (min: number, max: number) => {
|
||||
return Math.abs(random()) % (max - min + 1) + min;
|
||||
};
|
||||
|
||||
const h = randomInt(0, 360);
|
||||
const s = randomInt(42, 98);
|
||||
const l = shade === 'light' ? randomInt(15, 40) : randomInt(40, 90);
|
||||
return `hsl(${h},${s}%,${l}%)`;
|
||||
}
|
||||
|
||||
class Highlighter {
|
||||
private ctx: Ctx;
|
||||
private decorations: Map<
|
||||
string,
|
||||
vscode.TextEditorDecorationType
|
||||
> | null = null;
|
||||
|
||||
constructor(ctx: Ctx) {
|
||||
this.ctx = ctx;
|
||||
}
|
||||
|
||||
public removeHighlights() {
|
||||
if (this.decorations == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Decorations are removed when the object is disposed
|
||||
for (const decoration of this.decorations.values()) {
|
||||
decoration.dispose();
|
||||
}
|
||||
|
||||
this.decorations = null;
|
||||
}
|
||||
|
||||
public setHighlights(editor: vscode.TextEditor, highlights: ra.Decoration[]) {
|
||||
const client = this.ctx.client;
|
||||
if (!client) return;
|
||||
// Initialize decorations if necessary
|
||||
//
|
||||
// Note: decoration objects need to be kept around so we can dispose them
|
||||
// if the user disables syntax highlighting
|
||||
if (this.decorations == null) {
|
||||
this.decorations = initDecorations();
|
||||
}
|
||||
|
||||
const byTag: Map<string, vscode.Range[]> = new Map();
|
||||
const colorfulIdents: Map<
|
||||
string,
|
||||
[vscode.Range[], boolean]
|
||||
> = new Map();
|
||||
const rainbowTime = this.ctx.config.rainbowHighlightingOn;
|
||||
|
||||
for (const tag of this.decorations.keys()) {
|
||||
byTag.set(tag, []);
|
||||
}
|
||||
|
||||
for (const d of highlights) {
|
||||
if (!byTag.get(d.tag)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (rainbowTime && d.bindingHash) {
|
||||
if (!colorfulIdents.has(d.bindingHash)) {
|
||||
const mut = d.tag.endsWith('.mut');
|
||||
colorfulIdents.set(d.bindingHash, [[], mut]);
|
||||
}
|
||||
colorfulIdents
|
||||
.get(d.bindingHash)![0]
|
||||
.push(
|
||||
client.protocol2CodeConverter.asRange(d.range),
|
||||
);
|
||||
} else {
|
||||
byTag
|
||||
.get(d.tag)!
|
||||
.push(
|
||||
client.protocol2CodeConverter.asRange(d.range),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
for (const tag of byTag.keys()) {
|
||||
const dec = this.decorations.get(
|
||||
tag,
|
||||
) as vscode.TextEditorDecorationType;
|
||||
const ranges = byTag.get(tag)!;
|
||||
editor.setDecorations(dec, ranges);
|
||||
}
|
||||
|
||||
for (const [hash, [ranges, mut]] of colorfulIdents.entries()) {
|
||||
const textDecoration = mut ? 'underline' : undefined;
|
||||
const dec = vscode.window.createTextEditorDecorationType({
|
||||
light: { color: fancify(hash, 'light'), textDecoration },
|
||||
dark: { color: fancify(hash, 'dark'), textDecoration },
|
||||
});
|
||||
editor.setDecorations(dec, ranges);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function initDecorations(): Map<string, vscode.TextEditorDecorationType> {
|
||||
const theme = ColorTheme.load();
|
||||
const res = new Map();
|
||||
TAG_TO_SCOPES.forEach((scopes, tag) => {
|
||||
// We are going to axe this soon, so don't try to detect unknown tags.
|
||||
// Users should switch to the new semantic tokens implementation.
|
||||
if (!scopes) return;
|
||||
const rule = theme.lookup(scopes);
|
||||
const decor = createDecorationFromTextmate(rule);
|
||||
res.set(tag, decor);
|
||||
});
|
||||
return res;
|
||||
}
|
||||
|
||||
function createDecorationFromTextmate(
|
||||
themeStyle: TextMateRuleSettings,
|
||||
): vscode.TextEditorDecorationType {
|
||||
const decorationOptions: vscode.DecorationRenderOptions = {};
|
||||
decorationOptions.rangeBehavior = vscode.DecorationRangeBehavior.OpenOpen;
|
||||
|
||||
if (themeStyle.foreground) {
|
||||
decorationOptions.color = themeStyle.foreground;
|
||||
}
|
||||
|
||||
if (themeStyle.background) {
|
||||
decorationOptions.backgroundColor = themeStyle.background;
|
||||
}
|
||||
|
||||
if (themeStyle.fontStyle) {
|
||||
const parts: string[] = themeStyle.fontStyle.split(' ');
|
||||
parts.forEach(part => {
|
||||
switch (part) {
|
||||
case 'italic':
|
||||
decorationOptions.fontStyle = 'italic';
|
||||
break;
|
||||
case 'bold':
|
||||
decorationOptions.fontWeight = 'bold';
|
||||
break;
|
||||
case 'underline':
|
||||
decorationOptions.textDecoration = 'underline';
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
return vscode.window.createTextEditorDecorationType(decorationOptions);
|
||||
}
|
||||
|
||||
// sync with tags from `syntax_highlighting.rs`.
|
||||
const TAG_TO_SCOPES = new Map<string, string[]>([
|
||||
["field", ["entity.name.field"]],
|
||||
["function", ["entity.name.function"]],
|
||||
["module", ["entity.name.module"]],
|
||||
["constant", ["entity.name.constant"]],
|
||||
["macro", ["entity.name.macro"]],
|
||||
|
||||
["variable", ["variable"]],
|
||||
["variable.mutable", ["variable", "meta.mutable"]],
|
||||
|
||||
["type", ["entity.name.type"]],
|
||||
["type.builtin", ["entity.name.type", "support.type.primitive"]],
|
||||
["type.self", ["entity.name.type.parameter.self"]],
|
||||
["type.param", ["entity.name.type.parameter", "entity.name.type.param.rust"]],
|
||||
["type.lifetime", ["entity.name.type.lifetime", "entity.name.lifetime.rust"]],
|
||||
|
||||
["literal.byte", ["constant.character.byte"]],
|
||||
["literal.char", ["constant.character.rust"]],
|
||||
["numeric_literal", ["constant.numeric"]],
|
||||
|
||||
["comment", ["comment"]],
|
||||
["string_literal", ["string.quoted"]],
|
||||
["attribute", ["meta.attribute.rust"]],
|
||||
|
||||
["keyword", ["keyword"]],
|
||||
["keyword.unsafe", ["keyword.other.unsafe"]],
|
||||
["keyword.control", ["keyword.control"]],
|
||||
]);
|
||||
|
||||
function randomU32Numbers(seed: number) {
|
||||
let random = seed | 0;
|
||||
return () => {
|
||||
random ^= random << 13;
|
||||
random ^= random >> 17;
|
||||
random ^= random << 5;
|
||||
random |= 0;
|
||||
return random;
|
||||
};
|
||||
}
|
||||
|
||||
function hashString(str: string): number {
|
||||
let res = 0;
|
||||
for (let i = 0; i < str.length; ++i) {
|
||||
const c = str.codePointAt(i)!;
|
||||
res = (res * 31 + c) & ~0;
|
||||
}
|
||||
return res;
|
||||
}
|
|
@ -7,7 +7,6 @@ import * as commands from './commands';
|
|||
import { activateInlayHints } from './inlay_hints';
|
||||
import { activateStatusDisplay } from './status_display';
|
||||
import { Ctx } from './ctx';
|
||||
import { activateHighlighting } from './highlighting';
|
||||
import { Config, NIGHTLY_TAG } from './config';
|
||||
import { log, assert } from './util';
|
||||
import { PersistentState } from './persistent_state';
|
||||
|
@ -97,9 +96,6 @@ export async function activate(context: vscode.ExtensionContext) {
|
|||
|
||||
activateStatusDisplay(ctx);
|
||||
|
||||
if (!ctx.config.highlightingSemanticTokens) {
|
||||
activateHighlighting(ctx);
|
||||
}
|
||||
activateInlayHints(ctx);
|
||||
|
||||
vscode.workspace.onDidChangeConfiguration(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue