File size: 4,627 Bytes
6202252 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 | /* --------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* ------------------------------------------------------------------------------------------ */
import * as path from 'path';
import {
workspace as Workspace, window as Window, ExtensionContext, TextDocument, OutputChannel, WorkspaceFolder, Uri
} from 'vscode';
import {
LanguageClient, LanguageClientOptions, TransportKind
} from 'vscode-languageclient/node';
let defaultClient: LanguageClient;
const clients = new Map<string, LanguageClient>();
let _sortedWorkspaceFolders: string[] | undefined;
function sortedWorkspaceFolders(): string[] {
if (_sortedWorkspaceFolders === void 0) {
_sortedWorkspaceFolders = Workspace.workspaceFolders ? Workspace.workspaceFolders.map(folder => {
let result = folder.uri.toString();
if (result.charAt(result.length - 1) !== '/') {
result = result + '/';
}
return result;
}).sort(
(a, b) => {
return a.length - b.length;
}
) : [];
}
return _sortedWorkspaceFolders;
}
Workspace.onDidChangeWorkspaceFolders(() => _sortedWorkspaceFolders = undefined);
function getOuterMostWorkspaceFolder(folder: WorkspaceFolder): WorkspaceFolder {
const sorted = sortedWorkspaceFolders();
for (const element of sorted) {
let uri = folder.uri.toString();
if (uri.charAt(uri.length - 1) !== '/') {
uri = uri + '/';
}
if (uri.startsWith(element)) {
return Workspace.getWorkspaceFolder(Uri.parse(element))!;
}
}
return folder;
}
export function activate(context: ExtensionContext) {
const module = context.asAbsolutePath(path.join('server', 'out', 'server.js'));
const outputChannel: OutputChannel = Window.createOutputChannel('lsp-multi-server-example');
function didOpenTextDocument(document: TextDocument): void {
// We are only interested in language mode text
if (document.languageId !== 'plaintext' || (document.uri.scheme !== 'file' && document.uri.scheme !== 'untitled')) {
return;
}
const uri = document.uri;
// Untitled files go to a default client.
if (uri.scheme === 'untitled' && !defaultClient) {
const serverOptions = {
run: { module, transport: TransportKind.ipc },
debug: { module, transport: TransportKind.ipc }
};
const clientOptions: LanguageClientOptions = {
documentSelector: [
{ scheme: 'untitled', language: 'plaintext' }
],
diagnosticCollectionName: 'lsp-multi-server-example',
outputChannel: outputChannel
};
defaultClient = new LanguageClient('lsp-multi-server-example', 'LSP Multi Server Example', serverOptions, clientOptions);
defaultClient.start();
return;
}
let folder = Workspace.getWorkspaceFolder(uri);
// Files outside a folder can't be handled. This might depend on the language.
// Single file languages like JSON might handle files outside the workspace folders.
if (!folder) {
return;
}
// If we have nested workspace folders we only start a server on the outer most workspace folder.
folder = getOuterMostWorkspaceFolder(folder);
if (!clients.has(folder.uri.toString())) {
const serverOptions = {
run: { module, transport: TransportKind.ipc },
debug: { module, transport: TransportKind.ipc }
};
const clientOptions: LanguageClientOptions = {
documentSelector: [
{ scheme: 'file', language: 'plaintext', pattern: `${folder.uri.fsPath}/**/*` }
],
diagnosticCollectionName: 'lsp-multi-server-example',
workspaceFolder: folder,
outputChannel: outputChannel
};
const client = new LanguageClient('lsp-multi-server-example', 'LSP Multi Server Example', serverOptions, clientOptions);
client.start();
clients.set(folder.uri.toString(), client);
}
}
Workspace.onDidOpenTextDocument(didOpenTextDocument);
Workspace.textDocuments.forEach(didOpenTextDocument);
Workspace.onDidChangeWorkspaceFolders((event) => {
for (const folder of event.removed) {
const client = clients.get(folder.uri.toString());
if (client) {
clients.delete(folder.uri.toString());
client.stop();
}
}
});
}
export function deactivate(): Thenable<void> {
const promises: Thenable<void>[] = [];
if (defaultClient) {
promises.push(defaultClient.stop());
}
for (const client of clients.values()) {
promises.push(client.stop());
}
return Promise.all(promises).then(() => undefined);
}
|