2021-07-21 18:13:58 +02:00
|
|
|
/*---------------------------------------------------------------------------------------------
|
|
|
|
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
|
|
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
|
|
|
*--------------------------------------------------------------------------------------------*/
|
2021-08-19 12:37:42 +02:00
|
|
|
import { createConnection, BrowserMessageReader, BrowserMessageWriter } from 'vscode-languageserver/browser';
|
2021-07-21 18:13:58 +02:00
|
|
|
|
|
|
|
|
import { Color, ColorInformation, Range, InitializeParams, InitializeResult, ServerCapabilities, TextDocuments, ColorPresentation, TextEdit, TextDocumentIdentifier } from 'vscode-languageserver';
|
|
|
|
|
import { TextDocument } from 'vscode-languageserver-textdocument';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
console.log('running server lsp-web-extension-sample');
|
|
|
|
|
|
|
|
|
|
/* browser specific setup code */
|
|
|
|
|
|
|
|
|
|
const messageReader = new BrowserMessageReader(self);
|
|
|
|
|
const messageWriter = new BrowserMessageWriter(self);
|
|
|
|
|
|
|
|
|
|
const connection = createConnection(messageReader, messageWriter);
|
|
|
|
|
|
2021-08-20 12:04:40 +02:00
|
|
|
/* from here on, all code is non-browser specific and could be shared with a regular extension */
|
2021-07-21 18:13:58 +02:00
|
|
|
|
2024-10-26 17:44:03 -07:00
|
|
|
connection.onInitialize((_params: InitializeParams): InitializeResult => {
|
2021-07-21 18:13:58 +02:00
|
|
|
const capabilities: ServerCapabilities = {
|
2022-07-26 11:17:22 +08:00
|
|
|
colorProvider: {} // provide a color provider
|
2021-07-21 18:13:58 +02:00
|
|
|
};
|
|
|
|
|
return { capabilities };
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Track open, change and close text document events
|
|
|
|
|
const documents = new TextDocuments(TextDocument);
|
|
|
|
|
documents.listen(connection);
|
|
|
|
|
|
|
|
|
|
// Register providers
|
|
|
|
|
connection.onDocumentColor(params => getColorInformation(params.textDocument));
|
|
|
|
|
connection.onColorPresentation(params => getColorPresentation(params.color, params.range));
|
|
|
|
|
|
|
|
|
|
// Listen on the connection
|
|
|
|
|
connection.listen();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const colorRegExp = /#([0-9A-Fa-f]{6})/g;
|
|
|
|
|
|
|
|
|
|
function getColorInformation(textDocument: TextDocumentIdentifier) {
|
|
|
|
|
const colorInfos: ColorInformation[] = [];
|
|
|
|
|
|
|
|
|
|
const document = documents.get(textDocument.uri);
|
|
|
|
|
if (document) {
|
|
|
|
|
const text = document.getText();
|
|
|
|
|
|
|
|
|
|
colorRegExp.lastIndex = 0;
|
|
|
|
|
let match;
|
|
|
|
|
while ((match = colorRegExp.exec(text)) != null) {
|
|
|
|
|
const offset = match.index;
|
|
|
|
|
const length = match[0].length;
|
|
|
|
|
|
|
|
|
|
const range = Range.create(document.positionAt(offset), document.positionAt(offset + length));
|
|
|
|
|
const color = parseColor(text, offset);
|
|
|
|
|
colorInfos.push({ color, range });
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return colorInfos;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function getColorPresentation(color: Color, range: Range) {
|
|
|
|
|
const result: ColorPresentation[] = [];
|
|
|
|
|
const red256 = Math.round(color.red * 255), green256 = Math.round(color.green * 255), blue256 = Math.round(color.blue * 255);
|
|
|
|
|
|
|
|
|
|
function toTwoDigitHex(n: number): string {
|
|
|
|
|
const r = n.toString(16);
|
|
|
|
|
return r.length !== 2 ? '0' + r : r;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const label = `#${toTwoDigitHex(red256)}${toTwoDigitHex(green256)}${toTwoDigitHex(blue256)}`;
|
|
|
|
|
result.push({ label: label, textEdit: TextEdit.replace(range, label) });
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const enum CharCode {
|
|
|
|
|
Digit0 = 48,
|
|
|
|
|
Digit9 = 57,
|
|
|
|
|
|
|
|
|
|
A = 65,
|
|
|
|
|
F = 70,
|
|
|
|
|
|
|
|
|
|
a = 97,
|
|
|
|
|
f = 102,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function parseHexDigit(charCode: CharCode): number {
|
|
|
|
|
if (charCode >= CharCode.Digit0 && charCode <= CharCode.Digit9) {
|
|
|
|
|
return charCode - CharCode.Digit0;
|
|
|
|
|
}
|
|
|
|
|
if (charCode >= CharCode.A && charCode <= CharCode.F) {
|
2021-09-15 23:30:24 +02:00
|
|
|
return charCode - CharCode.A + 10;
|
2021-07-21 18:13:58 +02:00
|
|
|
}
|
|
|
|
|
if (charCode >= CharCode.a && charCode <= CharCode.f) {
|
2021-09-15 23:30:24 +02:00
|
|
|
return charCode - CharCode.a + 10;
|
2021-07-21 18:13:58 +02:00
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function parseColor(content: string, offset: number): Color {
|
|
|
|
|
const r = (16 * parseHexDigit(content.charCodeAt(offset + 1)) + parseHexDigit(content.charCodeAt(offset + 2))) / 255;
|
|
|
|
|
const g = (16 * parseHexDigit(content.charCodeAt(offset + 3)) + parseHexDigit(content.charCodeAt(offset + 4))) / 255;
|
|
|
|
|
const b = (16 * parseHexDigit(content.charCodeAt(offset + 5)) + parseHexDigit(content.charCodeAt(offset + 6))) / 255;
|
|
|
|
|
return Color.create(r, g, b, 1);
|
|
|
|
|
}
|