mirror of
https://github.com/microsoft/vscode.git
synced 2025-12-24 12:19:20 +00:00
css/html/json update to lsp 8 (#148715)
This commit is contained in:
committed by
GitHub
parent
14925e336d
commit
e783fdc25e
@@ -4,7 +4,7 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Disposable, ExtensionContext, Uri } from 'vscode';
|
||||
import { LanguageClientOptions } from 'vscode-languageclient';
|
||||
import { BaseLanguageClient, LanguageClientOptions } from 'vscode-languageclient';
|
||||
import { startClient, LanguageClientConstructor } from '../htmlClient';
|
||||
import { LanguageClient } from 'vscode-languageclient/browser';
|
||||
|
||||
@@ -15,8 +15,10 @@ declare const TextDecoder: {
|
||||
new(encoding?: string): { decode(buffer: ArrayBuffer): string };
|
||||
};
|
||||
|
||||
let client: BaseLanguageClient | undefined;
|
||||
|
||||
// this method is called when vs code is activated
|
||||
export function activate(context: ExtensionContext) {
|
||||
export async function activate(context: ExtensionContext) {
|
||||
const serverMain = Uri.joinPath(context.extensionUri, 'server/dist/browser/htmlServerMain.js');
|
||||
try {
|
||||
const worker = new Worker(serverMain.toString());
|
||||
@@ -31,9 +33,17 @@ export function activate(context: ExtensionContext) {
|
||||
}
|
||||
};
|
||||
|
||||
startClient(context, newLanguageClient, { TextDecoder, timer });
|
||||
client = await startClient(context, newLanguageClient, { TextDecoder, timer });
|
||||
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
|
||||
export async function deactivate(): Promise<void> {
|
||||
if (client) {
|
||||
await client.stop();
|
||||
client = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ import {
|
||||
} from 'vscode';
|
||||
import {
|
||||
LanguageClientOptions, RequestType, DocumentRangeFormattingParams,
|
||||
DocumentRangeFormattingRequest, ProvideCompletionItemsSignature, TextDocumentIdentifier, RequestType0, Range as LspRange, Position as LspPosition, NotificationType, CommonLanguageClient
|
||||
DocumentRangeFormattingRequest, ProvideCompletionItemsSignature, TextDocumentIdentifier, RequestType0, Range as LspRange, Position as LspPosition, NotificationType, BaseLanguageClient
|
||||
} from 'vscode-languageclient';
|
||||
import { FileSystemProvider, serveFileSystemRequests } from './requests';
|
||||
import { getCustomDataSource } from './customData';
|
||||
@@ -72,7 +72,7 @@ export interface TelemetryReporter {
|
||||
}): void;
|
||||
}
|
||||
|
||||
export type LanguageClientConstructor = (name: string, description: string, clientOptions: LanguageClientOptions) => CommonLanguageClient;
|
||||
export type LanguageClientConstructor = (name: string, description: string, clientOptions: LanguageClientOptions) => BaseLanguageClient;
|
||||
|
||||
export interface Runtime {
|
||||
TextDecoder: { new(encoding?: string): { decode(buffer: ArrayBuffer): string } };
|
||||
@@ -83,18 +83,17 @@ export interface Runtime {
|
||||
};
|
||||
}
|
||||
|
||||
export function startClient(context: ExtensionContext, newLanguageClient: LanguageClientConstructor, runtime: Runtime) {
|
||||
export async function startClient(context: ExtensionContext, newLanguageClient: LanguageClientConstructor, runtime: Runtime): Promise<BaseLanguageClient> {
|
||||
|
||||
let toDispose = context.subscriptions;
|
||||
const toDispose = context.subscriptions;
|
||||
|
||||
|
||||
let documentSelector = ['html', 'handlebars'];
|
||||
let embeddedLanguages = { css: true, javascript: true };
|
||||
const documentSelector = ['html', 'handlebars'];
|
||||
const embeddedLanguages = { css: true, javascript: true };
|
||||
|
||||
let rangeFormatting: Disposable | undefined = undefined;
|
||||
|
||||
// Options to control the language client
|
||||
let clientOptions: LanguageClientOptions = {
|
||||
const clientOptions: LanguageClientOptions = {
|
||||
documentSelector,
|
||||
synchronize: {
|
||||
configurationSection: ['html', 'css', 'javascript'], // the settings to synchronize
|
||||
@@ -135,67 +134,65 @@ export function startClient(context: ExtensionContext, newLanguageClient: Langua
|
||||
let client = newLanguageClient('html', localize('htmlserver.name', 'HTML Language Server'), clientOptions);
|
||||
client.registerProposedFeatures();
|
||||
|
||||
let disposable = client.start();
|
||||
toDispose.push(disposable);
|
||||
client.onReady().then(() => {
|
||||
await client.start();
|
||||
|
||||
toDispose.push(serveFileSystemRequests(client, runtime));
|
||||
toDispose.push(serveFileSystemRequests(client, runtime));
|
||||
|
||||
const customDataSource = getCustomDataSource(runtime, context.subscriptions);
|
||||
const customDataSource = getCustomDataSource(runtime, context.subscriptions);
|
||||
|
||||
client.sendNotification(CustomDataChangedNotification.type, customDataSource.uris);
|
||||
customDataSource.onDidChange(() => {
|
||||
client.sendNotification(CustomDataChangedNotification.type, customDataSource.uris);
|
||||
customDataSource.onDidChange(() => {
|
||||
client.sendNotification(CustomDataChangedNotification.type, customDataSource.uris);
|
||||
});
|
||||
client.onRequest(CustomDataContent.type, customDataSource.getContent);
|
||||
|
||||
|
||||
const insertRequestor = (kind: 'autoQuote' | 'autoClose', document: TextDocument, position: Position): Promise<string> => {
|
||||
let param: AutoInsertParams = {
|
||||
kind,
|
||||
textDocument: client.code2ProtocolConverter.asTextDocumentIdentifier(document),
|
||||
position: client.code2ProtocolConverter.asPosition(position)
|
||||
};
|
||||
return client.sendRequest(AutoInsertRequest.type, param);
|
||||
};
|
||||
let disposable = activateAutoInsertion(insertRequestor, { html: true, handlebars: true }, runtime);
|
||||
toDispose.push(disposable);
|
||||
|
||||
disposable = client.onTelemetry(e => {
|
||||
runtime.telemetry?.sendTelemetryEvent(e.key, e.data);
|
||||
});
|
||||
toDispose.push(disposable);
|
||||
|
||||
// manually register / deregister format provider based on the `html.format.enable` setting avoiding issues with late registration. See #71652.
|
||||
updateFormatterRegistration();
|
||||
toDispose.push({ dispose: () => rangeFormatting && rangeFormatting.dispose() });
|
||||
toDispose.push(workspace.onDidChangeConfiguration(e => e.affectsConfiguration(SettingIds.formatEnable) && updateFormatterRegistration()));
|
||||
|
||||
client.sendRequest(SemanticTokenLegendRequest.type).then(legend => {
|
||||
if (legend) {
|
||||
const provider: DocumentSemanticTokensProvider & DocumentRangeSemanticTokensProvider = {
|
||||
provideDocumentSemanticTokens(doc) {
|
||||
const params: SemanticTokenParams = {
|
||||
textDocument: client.code2ProtocolConverter.asTextDocumentIdentifier(doc),
|
||||
};
|
||||
return client.sendRequest(SemanticTokenRequest.type, params).then(data => {
|
||||
return data && new SemanticTokens(new Uint32Array(data));
|
||||
});
|
||||
},
|
||||
provideDocumentRangeSemanticTokens(doc, range) {
|
||||
const params: SemanticTokenParams = {
|
||||
textDocument: client.code2ProtocolConverter.asTextDocumentIdentifier(doc),
|
||||
ranges: [client.code2ProtocolConverter.asRange(range)]
|
||||
};
|
||||
return client.sendRequest(SemanticTokenRequest.type, params).then(data => {
|
||||
return data && new SemanticTokens(new Uint32Array(data));
|
||||
});
|
||||
}
|
||||
};
|
||||
toDispose.push(languages.registerDocumentSemanticTokensProvider(documentSelector, provider, new SemanticTokensLegend(legend.types, legend.modifiers)));
|
||||
}
|
||||
});
|
||||
});
|
||||
client.onRequest(CustomDataContent.type, customDataSource.getContent);
|
||||
|
||||
|
||||
const insertRequestor = (kind: 'autoQuote' | 'autoClose', document: TextDocument, position: Position): Promise<string> => {
|
||||
const param: AutoInsertParams = {
|
||||
kind,
|
||||
textDocument: client.code2ProtocolConverter.asTextDocumentIdentifier(document),
|
||||
position: client.code2ProtocolConverter.asPosition(position)
|
||||
};
|
||||
return client.sendRequest(AutoInsertRequest.type, param);
|
||||
};
|
||||
const disposable = activateAutoInsertion(insertRequestor, { html: true, handlebars: true }, runtime);
|
||||
toDispose.push(disposable);
|
||||
|
||||
const disposable2 = client.onTelemetry(e => {
|
||||
runtime.telemetry?.sendTelemetryEvent(e.key, e.data);
|
||||
});
|
||||
toDispose.push(disposable2);
|
||||
|
||||
// manually register / deregister format provider based on the `html.format.enable` setting avoiding issues with late registration. See #71652.
|
||||
updateFormatterRegistration();
|
||||
toDispose.push({ dispose: () => rangeFormatting && rangeFormatting.dispose() });
|
||||
toDispose.push(workspace.onDidChangeConfiguration(e => e.affectsConfiguration(SettingIds.formatEnable) && updateFormatterRegistration()));
|
||||
|
||||
client.sendRequest(SemanticTokenLegendRequest.type).then(legend => {
|
||||
if (legend) {
|
||||
const provider: DocumentSemanticTokensProvider & DocumentRangeSemanticTokensProvider = {
|
||||
provideDocumentSemanticTokens(doc) {
|
||||
const params: SemanticTokenParams = {
|
||||
textDocument: client.code2ProtocolConverter.asTextDocumentIdentifier(doc),
|
||||
};
|
||||
return client.sendRequest(SemanticTokenRequest.type, params).then(data => {
|
||||
return data && new SemanticTokens(new Uint32Array(data));
|
||||
});
|
||||
},
|
||||
provideDocumentRangeSemanticTokens(doc, range) {
|
||||
const params: SemanticTokenParams = {
|
||||
textDocument: client.code2ProtocolConverter.asTextDocumentIdentifier(doc),
|
||||
ranges: [client.code2ProtocolConverter.asRange(range)]
|
||||
};
|
||||
return client.sendRequest(SemanticTokenRequest.type, params).then(data => {
|
||||
return data && new SemanticTokens(new Uint32Array(data));
|
||||
});
|
||||
}
|
||||
};
|
||||
toDispose.push(languages.registerDocumentSemanticTokensProvider(documentSelector, provider, new SemanticTokensLegend(legend.types, legend.modifiers)));
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
function updateFormatterRegistration() {
|
||||
const formatEnabled = workspace.getConfiguration().get(SettingIds.formatEnable);
|
||||
@@ -219,7 +216,7 @@ export function startClient(context: ExtensionContext, newLanguageClient: Langua
|
||||
return client.sendRequest(DocumentRangeFormattingRequest.type, params, token).then(
|
||||
client.protocol2CodeConverter.asTextEdits,
|
||||
(error) => {
|
||||
client.handleFailedRequest(DocumentRangeFormattingRequest.type, error, []);
|
||||
client.handleFailedRequest(DocumentRangeFormattingRequest.type, undefined, error, []);
|
||||
return Promise.resolve([]);
|
||||
}
|
||||
);
|
||||
@@ -300,4 +297,6 @@ export function startClient(context: ExtensionContext, newLanguageClient: Langua
|
||||
}
|
||||
}
|
||||
|
||||
return client;
|
||||
|
||||
}
|
||||
|
||||
@@ -6,16 +6,17 @@
|
||||
import { getNodeFileFS } from './nodeFs';
|
||||
import { Disposable, ExtensionContext } from 'vscode';
|
||||
import { startClient, LanguageClientConstructor } from '../htmlClient';
|
||||
import { ServerOptions, TransportKind, LanguageClientOptions, LanguageClient } from 'vscode-languageclient/node';
|
||||
import { ServerOptions, TransportKind, LanguageClientOptions, LanguageClient, BaseLanguageClient } from 'vscode-languageclient/node';
|
||||
import { TextDecoder } from 'util';
|
||||
import * as fs from 'fs';
|
||||
import TelemetryReporter from '@vscode/extension-telemetry';
|
||||
|
||||
|
||||
let telemetry: TelemetryReporter | undefined;
|
||||
let client: BaseLanguageClient | undefined;
|
||||
|
||||
// this method is called when vs code is activated
|
||||
export function activate(context: ExtensionContext) {
|
||||
export async function activate(context: ExtensionContext) {
|
||||
|
||||
let clientPackageJSON = getPackageInfo(context);
|
||||
telemetry = new TelemetryReporter(clientPackageJSON.name, clientPackageJSON.version, clientPackageJSON.aiKey);
|
||||
@@ -44,7 +45,14 @@ export function activate(context: ExtensionContext) {
|
||||
}
|
||||
};
|
||||
|
||||
startClient(context, newLanguageClient, { fileFs: getNodeFileFS(), TextDecoder, telemetry, timer });
|
||||
client = await startClient(context, newLanguageClient, { fileFs: getNodeFileFS(), TextDecoder, telemetry, timer });
|
||||
}
|
||||
|
||||
export async function deactivate(): Promise<void> {
|
||||
if (client) {
|
||||
await client.stop();
|
||||
client = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
interface IPackageInfo {
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Uri, workspace, Disposable } from 'vscode';
|
||||
import { RequestType, CommonLanguageClient } from 'vscode-languageclient';
|
||||
import { RequestType, BaseLanguageClient } from 'vscode-languageclient';
|
||||
import { Runtime } from './htmlClient';
|
||||
|
||||
export namespace FsStatRequest {
|
||||
@@ -15,7 +15,7 @@ export namespace FsReadDirRequest {
|
||||
export const type: RequestType<string, [string, FileType][], any> = new RequestType('fs/readDir');
|
||||
}
|
||||
|
||||
export function serveFileSystemRequests(client: CommonLanguageClient, runtime: Runtime): Disposable {
|
||||
export function serveFileSystemRequests(client: BaseLanguageClient, runtime: Runtime): Disposable {
|
||||
const disposables = [];
|
||||
disposables.push(client.onRequest(FsReadDirRequest.type, (uriString: string) => {
|
||||
const uri = Uri.parse(uriString);
|
||||
|
||||
Reference in New Issue
Block a user