coc.nvim
Version:
LSP based intellisense engine for neovim & vim8.
1,139 lines • 103 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
/*tslint:disable*/
const path_1 = tslib_1.__importDefault(require("path"));
const vscode_languageserver_protocol_1 = require("vscode-languageserver-protocol");
const vscode_uri_1 = require("vscode-uri");
const commands_1 = tslib_1.__importDefault(require("../commands"));
const languages_1 = tslib_1.__importDefault(require("../languages"));
const fs_1 = require("../util/fs");
const Is = tslib_1.__importStar(require("../util/is"));
const workspace_1 = tslib_1.__importDefault(require("../workspace"));
const async_1 = require("./utils/async");
const cv = tslib_1.__importStar(require("./utils/converter"));
const UUID = tslib_1.__importStar(require("./utils/uuid"));
const logger = require('../util/logger')('language-client-client');
class ConsoleLogger {
error(message) {
logger.error(message);
}
warn(message) {
logger.warn(message);
}
info(message) {
logger.info(message);
}
log(message) {
logger.log(message);
}
}
function createConnection(input, output, errorHandler, closeHandler) {
let logger = new ConsoleLogger();
let connection = vscode_languageserver_protocol_1.createProtocolConnection(input, output, logger);
connection.onError(data => {
errorHandler(data[0], data[1], data[2]);
});
connection.onClose(closeHandler);
let result = {
listen: () => connection.listen(),
sendRequest: (type, ...params) => connection.sendRequest(Is.string(type) ? type : type.method, ...params),
onRequest: (type, handler) => connection.onRequest(Is.string(type) ? type : type.method, handler),
sendNotification: (type, params) => connection.sendNotification(Is.string(type) ? type : type.method, params),
onNotification: (type, handler) => connection.onNotification(Is.string(type) ? type : type.method, handler),
trace: (value, tracer, sendNotificationOrTraceOptions) => {
const defaultTraceOptions = {
sendNotification: false,
traceFormat: vscode_languageserver_protocol_1.TraceFormat.Text
};
if (sendNotificationOrTraceOptions === void 0) {
connection.trace(value, tracer, defaultTraceOptions);
}
else if (Is.boolean(sendNotificationOrTraceOptions)) {
connection.trace(value, tracer, sendNotificationOrTraceOptions);
}
else {
connection.trace(value, tracer, sendNotificationOrTraceOptions);
}
},
initialize: (params) => connection.sendRequest(vscode_languageserver_protocol_1.InitializeRequest.type, params),
shutdown: () => connection.sendRequest(vscode_languageserver_protocol_1.ShutdownRequest.type, undefined),
exit: () => connection.sendNotification(vscode_languageserver_protocol_1.ExitNotification.type),
onLogMessage: (handler) => connection.onNotification(vscode_languageserver_protocol_1.LogMessageNotification.type, handler),
onShowMessage: (handler) => connection.onNotification(vscode_languageserver_protocol_1.ShowMessageNotification.type, handler),
onTelemetry: (handler) => connection.onNotification(vscode_languageserver_protocol_1.TelemetryEventNotification.type, handler),
didChangeConfiguration: (params) => connection.sendNotification(vscode_languageserver_protocol_1.DidChangeConfigurationNotification.type, params),
didChangeWatchedFiles: (params) => connection.sendNotification(vscode_languageserver_protocol_1.DidChangeWatchedFilesNotification.type, params),
didOpenTextDocument: (params) => connection.sendNotification(vscode_languageserver_protocol_1.DidOpenTextDocumentNotification.type, params),
didChangeTextDocument: (params) => connection.sendNotification(vscode_languageserver_protocol_1.DidChangeTextDocumentNotification.type, params),
didCloseTextDocument: (params) => connection.sendNotification(vscode_languageserver_protocol_1.DidCloseTextDocumentNotification.type, params),
didSaveTextDocument: (params) => connection.sendNotification(vscode_languageserver_protocol_1.DidSaveTextDocumentNotification.type, params),
onDiagnostics: (handler) => connection.onNotification(vscode_languageserver_protocol_1.PublishDiagnosticsNotification.type, handler),
dispose: () => connection.dispose()
};
return result;
}
/**
* An action to be performed when the connection is producing errors.
*/
var ErrorAction;
(function (ErrorAction) {
/**
* Continue running the server.
*/
ErrorAction[ErrorAction["Continue"] = 1] = "Continue";
/**
* Shutdown the server.
*/
ErrorAction[ErrorAction["Shutdown"] = 2] = "Shutdown";
})(ErrorAction = exports.ErrorAction || (exports.ErrorAction = {}));
/**
* An action to be performed when the connection to a server got closed.
*/
var CloseAction;
(function (CloseAction) {
/**
* Don't restart the server. The connection stays closed.
*/
CloseAction[CloseAction["DoNotRestart"] = 1] = "DoNotRestart";
/**
* Restart the server.
*/
CloseAction[CloseAction["Restart"] = 2] = "Restart";
})(CloseAction = exports.CloseAction || (exports.CloseAction = {}));
class DefaultErrorHandler {
constructor(name) {
this.name = name;
this.restarts = [];
}
error(_error, _message, count) {
if (count && count <= 3) {
return ErrorAction.Continue;
}
return ErrorAction.Shutdown;
}
closed() {
this.restarts.push(Date.now());
if (this.restarts.length < 5) {
return CloseAction.Restart;
}
else {
let diff = this.restarts[this.restarts.length - 1] - this.restarts[0];
if (diff <= 3 * 60 * 1000) {
logger.error(`The ${this.name} server crashed 5 times in the last 3 minutes. The server will not be restarted.`);
return CloseAction.DoNotRestart;
}
else {
this.restarts.shift();
return CloseAction.Restart;
}
}
}
}
var RevealOutputChannelOn;
(function (RevealOutputChannelOn) {
RevealOutputChannelOn[RevealOutputChannelOn["Info"] = 1] = "Info";
RevealOutputChannelOn[RevealOutputChannelOn["Warn"] = 2] = "Warn";
RevealOutputChannelOn[RevealOutputChannelOn["Error"] = 3] = "Error";
RevealOutputChannelOn[RevealOutputChannelOn["Never"] = 4] = "Never";
})(RevealOutputChannelOn = exports.RevealOutputChannelOn || (exports.RevealOutputChannelOn = {}));
var State;
(function (State) {
State[State["Stopped"] = 1] = "Stopped";
State[State["Running"] = 2] = "Running";
State[State["Starting"] = 3] = "Starting";
})(State = exports.State || (exports.State = {}));
var ClientState;
(function (ClientState) {
ClientState[ClientState["Initial"] = 0] = "Initial";
ClientState[ClientState["Starting"] = 1] = "Starting";
ClientState[ClientState["StartFailed"] = 2] = "StartFailed";
ClientState[ClientState["Running"] = 3] = "Running";
ClientState[ClientState["Stopping"] = 4] = "Stopping";
ClientState[ClientState["Stopped"] = 5] = "Stopped";
})(ClientState = exports.ClientState || (exports.ClientState = {}));
const SupporedSymbolKinds = [
vscode_languageserver_protocol_1.SymbolKind.File,
vscode_languageserver_protocol_1.SymbolKind.Module,
vscode_languageserver_protocol_1.SymbolKind.Namespace,
vscode_languageserver_protocol_1.SymbolKind.Package,
vscode_languageserver_protocol_1.SymbolKind.Class,
vscode_languageserver_protocol_1.SymbolKind.Method,
vscode_languageserver_protocol_1.SymbolKind.Property,
vscode_languageserver_protocol_1.SymbolKind.Field,
vscode_languageserver_protocol_1.SymbolKind.Constructor,
vscode_languageserver_protocol_1.SymbolKind.Enum,
vscode_languageserver_protocol_1.SymbolKind.Interface,
vscode_languageserver_protocol_1.SymbolKind.Function,
vscode_languageserver_protocol_1.SymbolKind.Variable,
vscode_languageserver_protocol_1.SymbolKind.Constant,
vscode_languageserver_protocol_1.SymbolKind.String,
vscode_languageserver_protocol_1.SymbolKind.Number,
vscode_languageserver_protocol_1.SymbolKind.Boolean,
vscode_languageserver_protocol_1.SymbolKind.Array,
vscode_languageserver_protocol_1.SymbolKind.Object,
vscode_languageserver_protocol_1.SymbolKind.Key,
vscode_languageserver_protocol_1.SymbolKind.Null,
vscode_languageserver_protocol_1.SymbolKind.EnumMember,
vscode_languageserver_protocol_1.SymbolKind.Struct,
vscode_languageserver_protocol_1.SymbolKind.Event,
vscode_languageserver_protocol_1.SymbolKind.Operator,
vscode_languageserver_protocol_1.SymbolKind.TypeParameter
];
const SupportedCompletionItemKinds = [
vscode_languageserver_protocol_1.CompletionItemKind.Text,
vscode_languageserver_protocol_1.CompletionItemKind.Method,
vscode_languageserver_protocol_1.CompletionItemKind.Function,
vscode_languageserver_protocol_1.CompletionItemKind.Constructor,
vscode_languageserver_protocol_1.CompletionItemKind.Field,
vscode_languageserver_protocol_1.CompletionItemKind.Variable,
vscode_languageserver_protocol_1.CompletionItemKind.Class,
vscode_languageserver_protocol_1.CompletionItemKind.Interface,
vscode_languageserver_protocol_1.CompletionItemKind.Module,
vscode_languageserver_protocol_1.CompletionItemKind.Property,
vscode_languageserver_protocol_1.CompletionItemKind.Unit,
vscode_languageserver_protocol_1.CompletionItemKind.Value,
vscode_languageserver_protocol_1.CompletionItemKind.Enum,
vscode_languageserver_protocol_1.CompletionItemKind.Keyword,
vscode_languageserver_protocol_1.CompletionItemKind.Snippet,
vscode_languageserver_protocol_1.CompletionItemKind.Color,
vscode_languageserver_protocol_1.CompletionItemKind.File,
vscode_languageserver_protocol_1.CompletionItemKind.Reference,
vscode_languageserver_protocol_1.CompletionItemKind.Folder,
vscode_languageserver_protocol_1.CompletionItemKind.EnumMember,
vscode_languageserver_protocol_1.CompletionItemKind.Constant,
vscode_languageserver_protocol_1.CompletionItemKind.Struct,
vscode_languageserver_protocol_1.CompletionItemKind.Event,
vscode_languageserver_protocol_1.CompletionItemKind.Operator,
vscode_languageserver_protocol_1.CompletionItemKind.TypeParameter
];
function ensure(target, key) {
if (target[key] == null) {
target[key] = {};
}
return target[key];
}
var DynamicFeature;
(function (DynamicFeature) {
function is(value) {
let candidate = value;
return (candidate &&
Is.func(candidate.register) &&
Is.func(candidate.unregister) &&
Is.func(candidate.dispose) &&
candidate.messages != null);
}
DynamicFeature.is = is;
})(DynamicFeature || (DynamicFeature = {}));
class OnReady {
constructor(_resolve, _reject) {
this._resolve = _resolve;
this._reject = _reject;
this._used = false;
}
get isUsed() {
return this._used;
}
resolve() {
this._used = true;
this._resolve();
}
reject(error) {
this._used = true;
this._reject(error);
}
}
class DocumentNotifiactions {
constructor(_client, _event, _type, _middleware, _createParams, _selectorFilter) {
this._client = _client;
this._event = _event;
this._type = _type;
this._middleware = _middleware;
this._createParams = _createParams;
this._selectorFilter = _selectorFilter;
this._selectors = new Map();
}
static textDocumentFilter(selectors, textDocument) {
for (const selector of selectors) {
if (workspace_1.default.match(selector, textDocument) > 0) {
return true;
}
}
return false;
}
register(_message, data) {
if (!data.registerOptions.documentSelector) {
return;
}
if (!this._listener) {
this._listener = this._event(this.callback, this);
}
this._selectors.set(data.id, data.registerOptions.documentSelector);
}
callback(data) {
if (!this._selectorFilter ||
this._selectorFilter(this._selectors.values(), data)) {
if (this._middleware) {
this._middleware(data, data => this._client.sendNotification(this._type, this._createParams(data)));
}
else {
this._client.sendNotification(this._type, this._createParams(data));
}
this.notificationSent(data);
}
}
notificationSent(_data) { }
unregister(id) {
this._selectors.delete(id);
if (this._selectors.size === 0 && this._listener) {
this._listener.dispose();
this._listener = undefined;
}
}
dispose() {
this._selectors.clear();
if (this._listener) {
this._listener.dispose();
this._listener = undefined;
}
}
}
class DidOpenTextDocumentFeature extends DocumentNotifiactions {
constructor(client, _syncedDocuments) {
super(client, workspace_1.default.onDidOpenTextDocument, vscode_languageserver_protocol_1.DidOpenTextDocumentNotification.type, client.clientOptions.middleware.didOpen, (textDocument) => {
return { textDocument: cv.convertToTextDocumentItem(textDocument) };
}, DocumentNotifiactions.textDocumentFilter);
this._syncedDocuments = _syncedDocuments;
}
get messages() {
return vscode_languageserver_protocol_1.DidOpenTextDocumentNotification.type;
}
fillClientCapabilities(capabilities) {
ensure(ensure(capabilities, 'textDocument'), 'synchronization').dynamicRegistration = true;
}
initialize(capabilities, documentSelector) {
let textDocumentSyncOptions = capabilities.resolvedTextDocumentSync;
if (documentSelector &&
textDocumentSyncOptions &&
textDocumentSyncOptions.openClose) {
this.register(this.messages, {
id: UUID.generateUuid(),
registerOptions: { documentSelector: documentSelector }
});
}
}
register(message, data) {
super.register(message, data);
if (!data.registerOptions.documentSelector) {
return;
}
let documentSelector = data.registerOptions.documentSelector;
workspace_1.default.textDocuments.forEach(textDocument => {
let uri = textDocument.uri.toString();
if (this._syncedDocuments.has(uri)) {
return;
}
if (workspace_1.default.match(documentSelector, textDocument) > 0) {
let middleware = this._client.clientOptions.middleware;
let didOpen = (textDocument) => {
this._client.sendNotification(this._type, this._createParams(textDocument));
};
if (middleware.didOpen) {
middleware.didOpen(textDocument, didOpen);
}
else {
didOpen(textDocument);
}
this._syncedDocuments.set(uri, textDocument);
}
});
}
notificationSent(textDocument) {
super.notificationSent(textDocument);
this._syncedDocuments.set(textDocument.uri.toString(), textDocument);
}
}
class DidCloseTextDocumentFeature extends DocumentNotifiactions {
constructor(client, _syncedDocuments) {
super(client, workspace_1.default.onDidCloseTextDocument, vscode_languageserver_protocol_1.DidCloseTextDocumentNotification.type, client.clientOptions.middleware.didClose, (textDocument) => cv.asCloseTextDocumentParams(textDocument), DocumentNotifiactions.textDocumentFilter);
this._syncedDocuments = _syncedDocuments;
}
get messages() {
return vscode_languageserver_protocol_1.DidCloseTextDocumentNotification.type;
}
fillClientCapabilities(capabilities) {
ensure(ensure(capabilities, 'textDocument'), 'synchronization').dynamicRegistration = true;
}
initialize(capabilities, documentSelector) {
let textDocumentSyncOptions = capabilities.resolvedTextDocumentSync;
if (documentSelector &&
textDocumentSyncOptions &&
textDocumentSyncOptions.openClose) {
this.register(this.messages, {
id: UUID.generateUuid(),
registerOptions: { documentSelector: documentSelector }
});
}
}
notificationSent(textDocument) {
super.notificationSent(textDocument);
this._syncedDocuments.delete(textDocument.uri.toString());
}
unregister(id) {
let selector = this._selectors.get(id);
// The super call removed the selector from the map
// of selectors.
super.unregister(id);
let selectors = this._selectors.values();
this._syncedDocuments.forEach(textDocument => {
if (workspace_1.default.match(selector, textDocument) > 0 &&
!this._selectorFilter(selectors, textDocument)) {
let middleware = this._client.clientOptions.middleware;
let didClose = (textDocument) => {
this._client.sendNotification(this._type, this._createParams(textDocument));
};
this._syncedDocuments.delete(textDocument.uri.toString());
if (middleware.didClose) {
middleware.didClose(textDocument, didClose);
}
else {
didClose(textDocument);
}
}
});
}
}
class DidChangeTextDocumentFeature {
constructor(_client) {
this._client = _client;
this._changeData = new Map();
}
get messages() {
return vscode_languageserver_protocol_1.DidChangeTextDocumentNotification.type;
}
fillClientCapabilities(capabilities) {
ensure(ensure(capabilities, 'textDocument'), 'synchronization').dynamicRegistration = true;
}
initialize(capabilities, documentSelector) {
let textDocumentSyncOptions = capabilities.resolvedTextDocumentSync;
if (documentSelector &&
textDocumentSyncOptions &&
textDocumentSyncOptions.change != null &&
textDocumentSyncOptions.change !== vscode_languageserver_protocol_1.TextDocumentSyncKind.None) {
this.register(this.messages, {
id: UUID.generateUuid(),
registerOptions: Object.assign({}, { documentSelector: documentSelector }, { syncKind: textDocumentSyncOptions.change })
});
}
}
register(_message, data) {
if (!data.registerOptions.documentSelector) {
return;
}
if (!this._listener) {
this._listener = workspace_1.default.onDidChangeTextDocument(this.callback, this);
}
this._changeData.set(data.id, {
documentSelector: data.registerOptions.documentSelector,
syncKind: data.registerOptions.syncKind
});
}
callback(event) {
// Text document changes are send for dirty changes as well. We don't
// have dirty / undirty events in the LSP so we ignore content changes
// with length zero.
if (event.contentChanges.length === 0) {
return;
}
let doc = workspace_1.default.getDocument(event.textDocument.uri);
if (!doc)
return;
let { textDocument } = doc;
for (const changeData of this._changeData.values()) {
if (workspace_1.default.match(changeData.documentSelector, textDocument) > 0) {
let middleware = this._client.clientOptions.middleware;
if (changeData.syncKind === vscode_languageserver_protocol_1.TextDocumentSyncKind.Incremental) {
if (middleware.didChange) {
middleware.didChange(event, () => this._client.sendNotification(vscode_languageserver_protocol_1.DidChangeTextDocumentNotification.type, event));
}
else {
this._client.sendNotification(vscode_languageserver_protocol_1.DidChangeTextDocumentNotification.type, event);
}
}
else if (changeData.syncKind === vscode_languageserver_protocol_1.TextDocumentSyncKind.Full) {
let didChange = event => {
let { textDocument } = workspace_1.default.getDocument(event.textDocument.uri);
this._client.sendNotification(vscode_languageserver_protocol_1.DidChangeTextDocumentNotification.type, cv.asChangeTextDocumentParams(textDocument));
};
if (middleware.didChange) {
middleware.didChange(event, didChange);
}
else {
didChange(event);
}
}
}
}
}
unregister(id) {
this._changeData.delete(id);
if (this._changeData.size === 0 && this._listener) {
this._listener.dispose();
this._listener = undefined;
}
}
dispose() {
this._changeData.clear();
if (this._listener) {
this._listener.dispose();
this._listener = undefined;
}
}
}
class WillSaveFeature extends DocumentNotifiactions {
constructor(client) {
super(client, workspace_1.default.onWillSaveTextDocument, vscode_languageserver_protocol_1.WillSaveTextDocumentNotification.type, client.clientOptions.middleware.willSave, willSaveEvent => cv.asWillSaveTextDocumentParams(willSaveEvent), (selectors, willSaveEvent) => DocumentNotifiactions.textDocumentFilter(selectors, willSaveEvent.document));
}
get messages() {
return vscode_languageserver_protocol_1.WillSaveTextDocumentNotification.type;
}
fillClientCapabilities(capabilities) {
let value = ensure(ensure(capabilities, 'textDocument'), 'synchronization');
value.willSave = true;
}
initialize(capabilities, documentSelector) {
let textDocumentSyncOptions = capabilities.resolvedTextDocumentSync;
if (documentSelector &&
textDocumentSyncOptions &&
textDocumentSyncOptions.willSave) {
this.register(this.messages, {
id: UUID.generateUuid(),
registerOptions: { documentSelector: documentSelector }
});
}
}
}
class WillSaveWaitUntilFeature {
constructor(_client) {
this._client = _client;
this._selectors = new Map();
}
get messages() {
return vscode_languageserver_protocol_1.WillSaveTextDocumentWaitUntilRequest.type;
}
fillClientCapabilities(capabilities) {
let value = ensure(ensure(capabilities, 'textDocument'), 'synchronization');
value.willSaveWaitUntil = true;
}
initialize(capabilities, documentSelector) {
let textDocumentSyncOptions = capabilities.resolvedTextDocumentSync;
if (documentSelector &&
textDocumentSyncOptions &&
textDocumentSyncOptions.willSaveWaitUntil) {
this.register(this.messages, {
id: UUID.generateUuid(),
registerOptions: { documentSelector: documentSelector }
});
}
}
register(_message, data) {
if (!data.registerOptions.documentSelector) {
return;
}
if (!this._listener) {
this._listener = workspace_1.default.onWillSaveUntil(this.callback, this, this._client.id);
}
this._selectors.set(data.id, data.registerOptions.documentSelector);
}
callback(event) {
if (DocumentNotifiactions.textDocumentFilter(this._selectors.values(), event.document)) {
let middleware = this._client.clientOptions.middleware;
let willSaveWaitUntil = (event) => {
return this._client
.sendRequest(vscode_languageserver_protocol_1.WillSaveTextDocumentWaitUntilRequest.type, cv.asWillSaveTextDocumentParams(event))
.then(edits => {
return edits ? edits : [];
}, e => {
workspace_1.default.showMessage(`Error on willSaveWaitUntil: ${e}`, 'error');
logger.error(e);
return [];
});
};
event.waitUntil(middleware.willSaveWaitUntil
? middleware.willSaveWaitUntil(event, willSaveWaitUntil)
: willSaveWaitUntil(event));
}
}
unregister(id) {
this._selectors.delete(id);
if (this._selectors.size === 0 && this._listener) {
this._listener.dispose();
this._listener = undefined;
}
}
dispose() {
this._selectors.clear();
if (this._listener) {
this._listener.dispose();
this._listener = undefined;
}
}
}
class DidSaveTextDocumentFeature extends DocumentNotifiactions {
constructor(client) {
super(client, workspace_1.default.onDidSaveTextDocument, vscode_languageserver_protocol_1.DidSaveTextDocumentNotification.type, client.clientOptions.middleware.didSave, textDocument => cv.asSaveTextDocumentParams(textDocument, this._includeText), DocumentNotifiactions.textDocumentFilter);
}
get messages() {
return vscode_languageserver_protocol_1.DidSaveTextDocumentNotification.type;
}
fillClientCapabilities(capabilities) {
ensure(ensure(capabilities, 'textDocument'), 'synchronization').didSave = true;
}
initialize(capabilities, documentSelector) {
let textDocumentSyncOptions = capabilities.resolvedTextDocumentSync;
if (documentSelector &&
textDocumentSyncOptions &&
textDocumentSyncOptions.save) {
this.register(this.messages, {
id: UUID.generateUuid(),
registerOptions: Object.assign({}, { documentSelector: documentSelector }, { includeText: !!textDocumentSyncOptions.save.includeText })
});
}
}
register(method, data) {
this._includeText = !!data.registerOptions.includeText;
super.register(method, data);
}
}
class FileSystemWatcherFeature {
constructor(_client, _notifyFileEvent) {
this._notifyFileEvent = _notifyFileEvent;
this._watchers = new Map();
}
get messages() {
return vscode_languageserver_protocol_1.DidChangeWatchedFilesNotification.type;
}
fillClientCapabilities(capabilities) {
ensure(ensure(capabilities, 'workspace'), 'didChangeWatchedFiles').dynamicRegistration = true;
}
initialize(_capabilities, _documentSelector) { }
register(_method, data) {
if (!Array.isArray(data.registerOptions.watchers)) {
return;
}
let disposables = [];
for (let watcher of data.registerOptions.watchers) {
if (!Is.string(watcher.globPattern)) {
continue;
}
let watchCreate = true, watchChange = true, watchDelete = true;
if (watcher.kind != null) {
watchCreate = (watcher.kind & vscode_languageserver_protocol_1.WatchKind.Create) !== 0;
watchChange = (watcher.kind & vscode_languageserver_protocol_1.WatchKind.Change) != 0;
watchDelete = (watcher.kind & vscode_languageserver_protocol_1.WatchKind.Delete) != 0;
}
let fileSystemWatcher = workspace_1.default.createFileSystemWatcher(watcher.globPattern, !watchCreate, !watchChange, !watchDelete);
this.hookListeners(fileSystemWatcher, watchCreate, watchChange, watchDelete, disposables);
disposables.push(fileSystemWatcher);
}
this._watchers.set(data.id, disposables);
}
registerRaw(id, fileSystemWatchers) {
let disposables = [];
for (let fileSystemWatcher of fileSystemWatchers) {
disposables.push(fileSystemWatcher);
this.hookListeners(fileSystemWatcher, true, true, true, disposables);
}
this._watchers.set(id, disposables);
}
hookListeners(fileSystemWatcher, watchCreate, watchChange, watchDelete, listeners) {
if (watchCreate) {
fileSystemWatcher.onDidCreate(resource => this._notifyFileEvent({
uri: cv.asUri(resource),
type: vscode_languageserver_protocol_1.FileChangeType.Created
}), null, listeners);
}
if (watchChange) {
fileSystemWatcher.onDidChange(resource => this._notifyFileEvent({
uri: cv.asUri(resource),
type: vscode_languageserver_protocol_1.FileChangeType.Changed
}), null, listeners);
}
if (watchDelete) {
fileSystemWatcher.onDidDelete(resource => this._notifyFileEvent({
uri: cv.asUri(resource),
type: vscode_languageserver_protocol_1.FileChangeType.Deleted
}), null, listeners);
}
}
unregister(id) {
let disposables = this._watchers.get(id);
if (disposables) {
for (let disposable of disposables) {
disposable.dispose();
}
}
}
dispose() {
this._watchers.forEach(disposables => {
for (let disposable of disposables) {
disposable.dispose();
}
});
this._watchers.clear();
}
}
class TextDocumentFeature {
constructor(_client, _message) {
this._client = _client;
this._message = _message;
this._providers = new Map();
}
get messages() {
return this._message;
}
register(message, data) {
if (message.method !== this.messages.method) {
throw new Error(`Register called on wrong feature. Requested ${message.method} but reached feature ${this.messages.method}`);
}
if (!data.registerOptions.documentSelector) {
return;
}
let provider = this.registerLanguageProvider(data.registerOptions);
if (provider) {
this._providers.set(data.id, provider);
}
}
unregister(id) {
let provider = this._providers.get(id);
if (provider) {
provider.dispose();
}
}
dispose() {
this._providers.forEach(value => {
value.dispose();
});
this._providers.clear();
}
}
exports.TextDocumentFeature = TextDocumentFeature;
class WorkspaceFeature {
constructor(_client, _message) {
this._client = _client;
this._message = _message;
this._providers = new Map();
}
get messages() {
return this._message;
}
register(message, data) {
if (message.method !== this.messages.method) {
throw new Error(`Register called on wrong feature. Requested ${message.method} but reached feature ${this.messages.method}`);
}
let provider = this.registerLanguageProvider(data.registerOptions);
if (provider) {
this._providers.set(data.id, provider);
}
}
unregister(id) {
let provider = this._providers.get(id);
if (provider) {
provider.dispose();
}
}
dispose() {
this._providers.forEach(value => {
value.dispose();
});
this._providers.clear();
}
}
class CompletionItemFeature extends TextDocumentFeature {
constructor(client) {
super(client, vscode_languageserver_protocol_1.CompletionRequest.type);
}
fillClientCapabilities(capabilites) {
let completion = ensure(ensure(capabilites, 'textDocument'), 'completion');
completion.dynamicRegistration = true;
completion.contextSupport = true;
completion.completionItem = {
snippetSupport: true,
commitCharactersSupport: true,
documentationFormat: [vscode_languageserver_protocol_1.MarkupKind.Markdown, vscode_languageserver_protocol_1.MarkupKind.PlainText],
deprecatedSupport: true,
preselectSupport: true
};
completion.completionItemKind = { valueSet: SupportedCompletionItemKinds };
}
initialize(capabilities, documentSelector) {
if (!capabilities.completionProvider || !documentSelector) {
return;
}
this.register(this.messages, {
id: UUID.generateUuid(),
registerOptions: Object.assign({}, { documentSelector: documentSelector }, capabilities.completionProvider)
});
}
registerLanguageProvider(options) {
let triggerCharacters = options.triggerCharacters || [];
let client = this._client;
let provideCompletionItems = (document, position, context, token) => {
return client
.sendRequest(vscode_languageserver_protocol_1.CompletionRequest.type, cv.asCompletionParams(document, position, context), token)
.then(result => {
// logger.debug('result', result)
return result;
}, error => {
client.logFailedRequest(vscode_languageserver_protocol_1.CompletionRequest.type, error);
return Promise.resolve([]);
});
};
let resolveCompletionItem = (item, token) => {
return client
.sendRequest(vscode_languageserver_protocol_1.CompletionResolveRequest.type, item, token)
.then(res => res, error => {
client.logFailedRequest(vscode_languageserver_protocol_1.CompletionResolveRequest.type, error);
return Promise.resolve(item);
});
};
let middleware = this._client.clientOptions.middleware;
let languageIds = cv.asLanguageIds(options.documentSelector);
return languages_1.default.registerCompletionItemProvider(this._client.id, 'LS', languageIds, {
provideCompletionItems: (document, position, token, context) => {
return middleware.provideCompletionItem
? middleware.provideCompletionItem(document, position, context, token, provideCompletionItems)
: provideCompletionItems(document, position, context, token);
},
resolveCompletionItem: options.resolveProvider
? (item, token) => {
return middleware.resolveCompletionItem
? middleware.resolveCompletionItem(item, token, resolveCompletionItem)
: resolveCompletionItem(item, token);
}
: undefined
}, triggerCharacters);
}
}
class HoverFeature extends TextDocumentFeature {
constructor(client) {
super(client, vscode_languageserver_protocol_1.HoverRequest.type);
}
fillClientCapabilities(capabilites) {
const hoverCapability = ensure(ensure(capabilites, 'textDocument'), 'hover');
hoverCapability.dynamicRegistration = true;
hoverCapability.contentFormat = [vscode_languageserver_protocol_1.MarkupKind.Markdown, vscode_languageserver_protocol_1.MarkupKind.PlainText];
}
initialize(capabilities, documentSelector) {
if (!capabilities.hoverProvider || !documentSelector) {
return;
}
this.register(this.messages, {
id: UUID.generateUuid(),
registerOptions: Object.assign({}, { documentSelector: documentSelector })
});
}
registerLanguageProvider(options) {
let client = this._client;
let provideHover = (document, position, token) => {
return client
.sendRequest(vscode_languageserver_protocol_1.HoverRequest.type, cv.asTextDocumentPositionParams(document, position), token)
.then(res => res, error => {
client.logFailedRequest(vscode_languageserver_protocol_1.HoverRequest.type, error);
return Promise.resolve(null);
});
};
let middleware = client.clientOptions.middleware;
return languages_1.default.registerHoverProvider(options.documentSelector, {
provideHover: (document, position, token) => {
return middleware.provideHover
? middleware.provideHover(document, position, token, provideHover)
: provideHover(document, position, token);
}
});
}
}
class SignatureHelpFeature extends TextDocumentFeature {
constructor(client) {
super(client, vscode_languageserver_protocol_1.SignatureHelpRequest.type);
}
fillClientCapabilities(capabilites) {
let config = ensure(ensure(capabilites, 'textDocument'), 'signatureHelp');
config.dynamicRegistration = true;
config.signatureInformation = {
documentationFormat: [vscode_languageserver_protocol_1.MarkupKind.Markdown, vscode_languageserver_protocol_1.MarkupKind.PlainText],
parameterInformation: {
labelOffsetSupport: true
}
};
}
initialize(capabilities, documentSelector) {
if (!capabilities.signatureHelpProvider || !documentSelector) {
return;
}
this.register(this.messages, {
id: UUID.generateUuid(),
registerOptions: Object.assign({}, { documentSelector: documentSelector }, capabilities.signatureHelpProvider)
});
}
registerLanguageProvider(options) {
let client = this._client;
let providerSignatureHelp = (document, position, token) => {
return client
.sendRequest(vscode_languageserver_protocol_1.SignatureHelpRequest.type, cv.asTextDocumentPositionParams(document, position), token)
.then(res => res, error => {
client.logFailedRequest(vscode_languageserver_protocol_1.SignatureHelpRequest.type, error);
return Promise.resolve(null);
});
};
let middleware = client.clientOptions.middleware;
let triggerCharacters = options.triggerCharacters || [];
return languages_1.default.registerSignatureHelpProvider(options.documentSelector, {
provideSignatureHelp: (document, position, token) => {
return middleware.provideSignatureHelp
? middleware.provideSignatureHelp(document, position, token, providerSignatureHelp)
: providerSignatureHelp(document, position, token);
}
}, triggerCharacters);
}
}
class DefinitionFeature extends TextDocumentFeature {
constructor(client) {
super(client, vscode_languageserver_protocol_1.DefinitionRequest.type);
}
fillClientCapabilities(capabilites) {
let definitionSupport = ensure(ensure(capabilites, 'textDocument'), 'definition');
definitionSupport.dynamicRegistration = true;
// definitionSupport.linkSupport = true
}
initialize(capabilities, documentSelector) {
if (!capabilities.definitionProvider || !documentSelector) {
return;
}
this.register(this.messages, {
id: UUID.generateUuid(),
registerOptions: Object.assign({}, { documentSelector: documentSelector })
});
}
registerLanguageProvider(options) {
let client = this._client;
let provideDefinition = (document, position, token) => {
return client
.sendRequest(vscode_languageserver_protocol_1.DefinitionRequest.type, cv.asTextDocumentPositionParams(document, position), token)
.then(res => res, error => {
client.logFailedRequest(vscode_languageserver_protocol_1.DefinitionRequest.type, error);
return Promise.resolve(null);
});
};
let middleware = client.clientOptions.middleware;
return languages_1.default.registerDefinitionProvider(options.documentSelector, {
provideDefinition: (document, position, token) => {
return middleware.provideDefinition
? middleware.provideDefinition(document, position, token, provideDefinition)
: provideDefinition(document, position, token);
}
});
}
}
class ReferencesFeature extends TextDocumentFeature {
constructor(client) {
super(client, vscode_languageserver_protocol_1.ReferencesRequest.type);
}
fillClientCapabilities(capabilites) {
ensure(ensure(capabilites, 'textDocument'), 'references').dynamicRegistration = true;
}
initialize(capabilities, documentSelector) {
if (!capabilities.referencesProvider || !documentSelector) {
return;
}
this.register(this.messages, {
id: UUID.generateUuid(),
registerOptions: Object.assign({}, { documentSelector: documentSelector })
});
}
registerLanguageProvider(options) {
let client = this._client;
let providerReferences = (document, position, options, token) => {
return client
.sendRequest(vscode_languageserver_protocol_1.ReferencesRequest.type, cv.asReferenceParams(document, position, options), token)
.then(res => res, error => {
client.logFailedRequest(vscode_languageserver_protocol_1.ReferencesRequest.type, error);
return Promise.resolve([]);
});
};
let middleware = client.clientOptions.middleware;
return languages_1.default.registerReferencesProvider(options.documentSelector, {
provideReferences: (document, position, options, token) => {
return middleware.provideReferences
? middleware.provideReferences(document, position, options, token, providerReferences)
: providerReferences(document, position, options, token);
}
});
}
}
class DocumentHighlightFeature extends TextDocumentFeature {
constructor(client) {
super(client, vscode_languageserver_protocol_1.DocumentHighlightRequest.type);
}
fillClientCapabilities(capabilites) {
ensure(ensure(capabilites, 'textDocument'), 'documentHighlight').dynamicRegistration = true;
}
initialize(capabilities, documentSelector) {
if (!capabilities.documentHighlightProvider || !documentSelector) {
return;
}
this.register(this.messages, {
id: UUID.generateUuid(),
registerOptions: Object.assign({}, { documentSelector: documentSelector })
});
}
registerLanguageProvider(options) {
let client = this._client;
let provideDocumentHighlights = (document, position, token) => {
return client
.sendRequest(vscode_languageserver_protocol_1.DocumentHighlightRequest.type, cv.asTextDocumentPositionParams(document, position), token)
.then(res => res, error => {
client.logFailedRequest(vscode_languageserver_protocol_1.DocumentHighlightRequest.type, error);
return Promise.resolve([]);
});
};
let middleware = client.clientOptions.middleware;
return languages_1.default.registerDocumentHighlightProvider(options.documentSelector, {
provideDocumentHighlights: (document, position, token) => {
return middleware.provideDocumentHighlights
? middleware.provideDocumentHighlights(document, position, token, provideDocumentHighlights)
: provideDocumentHighlights(document, position, token);
}
});
}
}
class DocumentSymbolFeature extends TextDocumentFeature {
constructor(client) {
super(client, vscode_languageserver_protocol_1.DocumentSymbolRequest.type);
}
fillClientCapabilities(capabilites) {
let symbolCapabilities = ensure(ensure(capabilites, 'textDocument'), 'documentSymbol');
symbolCapabilities.dynamicRegistration = true;
symbolCapabilities.symbolKind = {
valueSet: SupporedSymbolKinds
};
}
initialize(capabilities, documentSelector) {
if (!capabilities.documentSymbolProvider || !documentSelector) {
return;
}
this.register(this.messages, {
id: UUID.generateUuid(),
registerOptions: Object.assign({}, { documentSelector: documentSelector })
});
}
registerLanguageProvider(options) {
let client = this._client;
let provideDocumentSymbols = (document, token) => {
return client
.sendRequest(vscode_languageserver_protocol_1.DocumentSymbolRequest.type, cv.asDocumentSymbolParams(document), token)
.then(res => res, error => {
client.logFailedRequest(vscode_languageserver_protocol_1.DocumentSymbolRequest.type, error);
return Promise.resolve([]);
});
};
let middleware = client.clientOptions.middleware;
return languages_1.default.registerDocumentSymbolProvider(options.documentSelector, {
provideDocumentSymbols: (document, token) => {
return middleware.provideDocumentSymbols
? middleware.provideDocumentSymbols(document, token, provideDocumentSymbols)
: provideDocumentSymbols(document, token);
}
});
}
}
class WorkspaceSymbolFeature extends WorkspaceFeature {
constructor(client) {
super(client, vscode_languageserver_protocol_1.WorkspaceSymbolRequest.type);
}
fillClientCapabilities(capabilites) {
let symbolCapabilities = ensure(ensure(capabilites, 'workspace'), 'symbol');
symbolCapabilities.dynamicRegistration = true;
symbolCapabilities.symbolKind = {
valueSet: SupporedSymbolKinds
};
}
initialize(capabilities, documentSelector) {
if (!capabilities.workspaceSymbolProvider) {
return;
}
this.register(this.messages, {
id: UUID.generateUuid(),
registerOptions: Object.assign({}, { documentSelector: documentSelector })
});
}
registerLanguageProvider(options) {
let client = this._client;
let provideWorkspaceSymbols = (query, token) => {
return client
.sendRequest(vscode_languageserver_protocol_1.WorkspaceSymbolRequest.type, { query }, token)
.then(res => res, error => {
client.logFailedRequest(vscode_languageserver_protocol_1.WorkspaceSymbolRequest.type, error);
return Promise.resolve([]);
});
};
let middleware = client.clientOptions.middleware;
return languages_1.default.registerWorkspaceSymbolProvider(options.documentSelector, {
provideWorkspaceSymbols: (query, token) => {
return middleware.provideWorkspaceSymbols
? middleware.provideWorkspaceSymbols(query, token, provideWorkspaceSymbols)
: provideWorkspaceSymbols(query, token);
}
});
}
}
class CodeActionFeature extends TextDocumentFeature {
constructor(client) {
super(client, vscode_languageserver_protocol_1.CodeActionRequest.type);
}
fillClientCapabilities(capabilites) {
const cap = ensure(ensure(capabilites, 'textDocument'), 'codeAction');
cap.dynamicRegistration = true;
cap.codeActionLiteralSupport = {
codeActionKind: {
valueSet: [
'',
vscode_languageserver_protocol_1.CodeActionKind.QuickFix,
vscode_languageserver_protocol_1.CodeActionKind.Refactor,
vscode_languageserver_protocol_1.CodeActionKind.RefactorExtract,
vscode_languageserver_protocol_1.CodeActionKind.RefactorInline,
vscode_languageserver_protocol_1.CodeActionKind.RefactorRewrite,
vscode_languageserver_protocol_1.CodeActionKind.Source,
vscode_languageserver_protocol_1.CodeActionKind.SourceOrganizeImports
]
}
};
}
initialize(capabilities, documentSelector) {
if (!capabilities.codeActionProvider || !documentSelector) {
return;
}
let codeActionKinds;
if (!Is.boolean(capabilities.codeActionProvider)) {
codeActionKinds = capabilities.codeActionProvider.codeActionKinds;
}
this.register(this.messages, {
id: UUID.generateUuid(),
registerOptions: Object.assign({}, { documentSelector: documentSelector, codeActionKinds })
});
}
registerLanguageProvider(options) {
let client = this._client;
let provideCodeActions = (document, range, context, token) => {
let params = {
textDocument: {
uri: document.uri
},
range,
context,
};
return