mirror of
https://github.com/microsoft/vscode-extension-samples.git
synced 2026-06-13 07:10:26 +08:00
121 lines
4.2 KiB
TypeScript
121 lines
4.2 KiB
TypeScript
/* --------------------------------------------------------------------------------------------
|
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
* ------------------------------------------------------------------------------------------ */
|
|
'use strict';
|
|
|
|
import {
|
|
createConnection, TextDocuments, TextDocument, Diagnostic, DiagnosticSeverity,
|
|
ProposedFeatures, InitializeParams
|
|
} from 'vscode-languageserver';
|
|
|
|
// Create a connection for the server. The connection uses Node's IPC as a transport
|
|
let connection = createConnection(ProposedFeatures.all);
|
|
|
|
// Create a simple text document manager. The text document manager
|
|
// supports full document sync only
|
|
let documents: TextDocuments = new TextDocuments();
|
|
|
|
let hasConfigurationCapability = false;
|
|
|
|
connection.onInitialize((params: InitializeParams) => {
|
|
function hasClientCapability(...keys: string[]) {
|
|
let c = <any>params.capabilities;
|
|
for (let i = 0; c && i < keys.length; i++) {
|
|
c = c[keys[i]];
|
|
}
|
|
return !!c;
|
|
}
|
|
// Does the client support the `workspace/configuration` request?
|
|
// If not, we will fall back using global settings
|
|
hasConfigurationCapability = hasClientCapability('workspace', 'configuration');
|
|
return {
|
|
capabilities: {
|
|
textDocumentSync: documents.syncKind
|
|
}
|
|
}
|
|
});
|
|
|
|
// The example settings
|
|
interface MultiRootExampleSettings {
|
|
maxNumberOfProblems: number;
|
|
}
|
|
|
|
// The global settings, used when the `workspace/configuration` request is not supported by the client.
|
|
// Please note that this is not the case when using this server with the client provided in this example
|
|
// but could happen with other clients.
|
|
const defaultSettings: MultiRootExampleSettings = { maxNumberOfProblems: 1000 };
|
|
let globalSettings: MultiRootExampleSettings = defaultSettings;
|
|
|
|
// Cache the settings of all open documents
|
|
let documentSettings: Map<string, Thenable<MultiRootExampleSettings>> = new Map();
|
|
|
|
connection.onDidChangeConfiguration(change => {
|
|
if (hasConfigurationCapability) {
|
|
// Reset all cached document settings
|
|
documentSettings.clear();
|
|
} else {
|
|
globalSettings = <MultiRootExampleSettings>(change.settings.lspMultiRootSample || defaultSettings);
|
|
}
|
|
|
|
// Revalidate all open text documents
|
|
documents.all().forEach(validateTextDocument);
|
|
});
|
|
|
|
function getDocumentSettings(resource: string): Thenable<MultiRootExampleSettings> {
|
|
if (!hasConfigurationCapability) {
|
|
return Promise.resolve(globalSettings);
|
|
}
|
|
let result = documentSettings.get(resource);
|
|
if (!result) {
|
|
result = connection.workspace.getConfiguration({ scopeUri: resource });
|
|
documentSettings.set(resource, result);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
// Only keep settings for open documents
|
|
documents.onDidClose(e => {
|
|
documentSettings.delete(e.document.uri);
|
|
});
|
|
|
|
// The content of a text document has changed. This event is emitted
|
|
// when the text document first opened or when its content has changed.
|
|
documents.onDidChangeContent((change) => {
|
|
validateTextDocument(change.document);
|
|
});
|
|
|
|
async function validateTextDocument(textDocument: TextDocument): Promise<void> {
|
|
// In this simple example we get the settings for every validate run.
|
|
let settings = await getDocumentSettings(textDocument.uri);
|
|
|
|
// The validator creates diagnostics for all uppercase words length 2 and more
|
|
let text = textDocument.getText();
|
|
let pattern = /\b[A-Z]{2,}\b/g;
|
|
let m: RegExpExecArray;
|
|
|
|
let problems = 0;
|
|
let diagnostics: Diagnostic[] = [];
|
|
while ((m = pattern.exec(text)) && problems < settings.maxNumberOfProblems) {
|
|
problems++;
|
|
diagnostics.push({
|
|
severity: DiagnosticSeverity.Warning,
|
|
range: {
|
|
start: textDocument.positionAt(m.index),
|
|
end: textDocument.positionAt(m.index + m[0].length)
|
|
},
|
|
message: `${m[0].length} is all uppercase.`,
|
|
source: 'ex'
|
|
});
|
|
}
|
|
|
|
// Send the computed diagnostics to VSCode.
|
|
connection.sendDiagnostics({ uri: textDocument.uri, diagnostics });
|
|
}
|
|
|
|
// Make the text document manager listen on the connection
|
|
// for open, change and close text document events
|
|
documents.listen(connection);
|
|
|
|
// Listen on the connection
|
|
connection.listen(); |