UNPKG

coc.nvim

Version:

LSP based intellisense engine for neovim & vim8.

423 lines 17.9 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const tslib_1 = require("tslib"); const events_1 = require("events"); const vscode_languageserver_types_1 = require("vscode-languageserver-types"); const commands_1 = tslib_1.__importDefault(require("./commands")); const completion_1 = tslib_1.__importDefault(require("./completion")); const manager_1 = tslib_1.__importDefault(require("./diagnostic/manager")); const extensions_1 = tslib_1.__importDefault(require("./extensions")); const handler_1 = tslib_1.__importDefault(require("./handler")); const manager_2 = tslib_1.__importDefault(require("./list/manager")); const services_1 = tslib_1.__importDefault(require("./services")); const manager_3 = tslib_1.__importDefault(require("./snippets/manager")); const sources_1 = tslib_1.__importDefault(require("./sources")); const types_1 = require("./types"); const clean_1 = tslib_1.__importDefault(require("./util/clean")); const workspace_1 = tslib_1.__importDefault(require("./workspace")); const logger = require('./util/logger')('plugin'); class Plugin extends events_1.EventEmitter { constructor(nvim) { super(); this.nvim = nvim; this._ready = false; Object.defineProperty(workspace_1.default, 'nvim', { get: () => this.nvim }); this.addMethod('hasSelected', () => { return completion_1.default.hasSelected(); }); this.addMethod('listNames', () => { return manager_2.default.names; }); this.addMethod('codeActionRange', (start, end, only) => { return this.handler.codeActionRange(start, end, only); }); this.addMethod('rootPatterns', bufnr => { let doc = workspace_1.default.getDocument(bufnr); if (!doc) return null; return { buffer: workspace_1.default.getRootPatterns(doc, types_1.PatternType.Buffer), server: workspace_1.default.getRootPatterns(doc, types_1.PatternType.LanguageServer), global: workspace_1.default.getRootPatterns(doc, types_1.PatternType.Global) }; }); this.addMethod('installExtensions', async (...list) => { await extensions_1.default.installExtensions(list); }); this.addMethod('saveRefactor', async (bufnr) => { await this.handler.saveRefactor(bufnr); }); this.addMethod('updateExtensions', async () => { await extensions_1.default.updateExtensions(); }); this.addMethod('commandList', () => { return commands_1.default.commandList.map(o => o.id); }); this.addMethod('openList', async (...args) => { await this.ready; await manager_2.default.start(args); }); this.addMethod('runCommand', async (...args) => { await this.ready; return await this.handler.runCommand(...args); }); this.addMethod('selectFunction', async (inner, visualmode) => { return await this.handler.selectFunction(inner, visualmode); }); this.addMethod('listResume', () => { return manager_2.default.resume(); }); this.addMethod('listPrev', () => { return manager_2.default.previous(); }); this.addMethod('listNext', () => { return manager_2.default.next(); }); this.addMethod('detach', () => { return workspace_1.default.detach(); }); this.addMethod('sendRequest', (id, method, params) => { return services_1.default.sendRequest(id, method, params); }); this.addMethod('registNotification', async (id, method) => { await services_1.default.registNotification(id, method); }); this.addMethod('doAutocmd', async (id, ...args) => { let autocmd = workspace_1.default.autocmds.get(id); if (autocmd) await Promise.resolve(autocmd.callback.apply(autocmd.thisArg, args)); }); this.addMethod('updateConfig', (section, val) => { workspace_1.default.configurations.updateUserConfig({ [section]: val }); }); this.addMethod('snippetNext', async () => { await manager_3.default.nextPlaceholder(); return ''; }); this.addMethod('snippetPrev', async () => { await manager_3.default.previousPlaceholder(); return ''; }); this.addMethod('snippetCancel', () => { manager_3.default.cancel(); }); this.addMethod('openLog', () => { let file = logger.getLogFile(); nvim.call(`coc#util#open_file`, ['edit', file], true); }); this.addMethod('doKeymap', async (key, defaultReturn = '') => { let [fn, repeat] = workspace_1.default.keymaps.get(key); if (!fn) { logger.error(`keymap for ${key} not found`); return defaultReturn; } let res = await Promise.resolve(fn()); if (repeat) await nvim.command(`silent! call repeat#set("\\<Plug>(coc-${key})", -1)`); return res || defaultReturn; }); this.addMethod('registExtensions', async (...folders) => { for (let folder of folders) { await extensions_1.default.loadExtension(folder); } }); workspace_1.default.onDidChangeWorkspaceFolders(() => { nvim.setVar('WorkspaceFolders', workspace_1.default.folderPaths, true); }); commands_1.default.init(nvim, this); clean_1.default(); // tslint:disable-line } addMethod(name, fn) { Object.defineProperty(this, name, { value: fn }); } addCommand(cmd) { let id = `vim.${cmd.id}`; commands_1.default.registerCommand(id, async () => { await this.nvim.command(cmd.cmd); }); if (cmd.title) commands_1.default.titles.set(id, cmd.title); } async init() { let { nvim } = this; try { await extensions_1.default.init(nvim); await workspace_1.default.init(); manager_1.default.init(); manager_2.default.init(nvim); nvim.setVar('coc_workspace_initialized', 1, true); nvim.setVar('coc_process_pid', process.pid, true); nvim.setVar('WorkspaceFolders', workspace_1.default.folderPaths, true); completion_1.default.init(nvim); sources_1.default.init(); this.handler = new handler_1.default(nvim); services_1.default.init(); await extensions_1.default.activateExtensions(); nvim.setVar('coc_service_initialized', 1, true); nvim.call('coc#_init', [], true); this._ready = true; let cmds = await nvim.getVar('coc_vim_commands'); if (cmds && cmds.length) { for (let cmd of cmds) { this.addCommand(cmd); } } logger.info(`coc ${this.version} initialized with node: ${process.version}`); this.emit('ready'); } catch (e) { this._ready = false; console.error(`Error on initialize: ${e.stack}`); // tslint:disable-line logger.error(e.stack); } workspace_1.default.onDidOpenTextDocument(async (doc) => { if (!doc.uri.endsWith('coc-settings.json')) return; if (extensions_1.default.has('coc-json') || extensions_1.default.isDisabled('coc-json')) return; workspace_1.default.showMessage(`Run :CocInstall coc-json for json intellisense`, 'more'); }); } get isReady() { return this._ready; } get ready() { if (this._ready) return Promise.resolve(); return new Promise(resolve => { this.once('ready', () => { resolve(); }); }); } async findLocations(id, method, params, openCommand) { let { document, position } = await workspace_1.default.getCurrentState(); params = params || {}; Object.assign(params, { textDocument: { uri: document.uri }, position }); let res = await services_1.default.sendRequest(id, method, params); if (!res) { workspace_1.default.showMessage(`Locations of "${method}" not found!`, 'warning'); return; } let locations = []; if (Array.isArray(res)) { locations = res; } else if (res.hasOwnProperty('location') && res.hasOwnProperty('children')) { function getLocation(item) { locations.push(item.location); if (item.children && item.children.length) { for (let loc of item.children) { getLocation(loc); } } } getLocation(res); } await this.handler.handleLocations(locations, openCommand); } async snippetCheck(checkExpand, checkJump) { if (checkExpand && !extensions_1.default.has('coc-snippets')) { // tslint:disable-next-line: no-console console.error('coc-snippets required for check expand status!'); return false; } if (checkJump) { let jumpable = manager_3.default.jumpable(); if (jumpable) return true; } if (checkExpand) { let api = extensions_1.default.getExtensionApi('coc-snippets'); if (api && api.hasOwnProperty('expandable')) { let expandable = await Promise.resolve(api.expandable()); if (expandable) return true; } } return false; } get version() { return workspace_1.default.version + (process.env.REVISION ? '-' + process.env.REVISION : ''); } async showInfo() { if (!this.infoChannel) { this.infoChannel = workspace_1.default.createOutputChannel('info'); } else { this.infoChannel.clear(); } let channel = this.infoChannel; channel.appendLine('## versions'); channel.appendLine(''); let out = await this.nvim.call('execute', ['version']); channel.appendLine('vim version: ' + out.trim().split('\n', 2)[0]); channel.appendLine('node version: ' + process.version); channel.appendLine('coc.nvim version: ' + this.version); channel.appendLine('term: ' + (process.env.TERM_PROGRAM || process.env.TERM)); channel.appendLine('platform: ' + process.platform); channel.appendLine(''); channel.appendLine('## Messages'); let msgs = await this.nvim.call('coc#rpc#get_errors'); channel.append(msgs.join('\n')); channel.appendLine(''); for (let ch of workspace_1.default.outputChannels.values()) { if (ch.name !== 'info') { channel.appendLine(`## Output channel: ${ch.name}\n`); channel.append(ch.content); channel.appendLine(''); } } channel.show(); } async cocAction(...args) { if (!this._ready) return; let { handler } = this; try { switch (args[0]) { case 'links': { return await handler.links(); } case 'openLink': { return await handler.openLink(); } case 'pickColor': { return await handler.pickColor(); } case 'colorPresentation': { return await handler.pickPresentation(); } case 'highlight': { await handler.highlight(); break; } case 'fold': { return await handler.fold(args[1]); } case 'startCompletion': await completion_1.default.startCompletion(args[1]); break; case 'sourceStat': return sources_1.default.sourceStats(); case 'refreshSource': await sources_1.default.refresh(args[1]); break; case 'toggleSource': sources_1.default.toggleSource(args[1]); break; case 'diagnosticInfo': await manager_1.default.echoMessage(); break; case 'diagnosticNext': await manager_1.default.jumpNext(args[1]); break; case 'diagnosticPrevious': await manager_1.default.jumpPrevious(args[1]); break; case 'diagnosticList': return manager_1.default.getDiagnosticList(); case 'jumpDefinition': return await handler.gotoDefinition(args[1]); case 'jumpDeclaration': return await handler.gotoDeclaration(args[1]); case 'jumpImplementation': return await handler.gotoImplementation(args[1]); case 'jumpTypeDefinition': return await handler.gotoTypeDefinition(args[1]); case 'jumpReferences': return await handler.gotoReferences(args[1]); case 'doHover': return await handler.onHover(); case 'showSignatureHelp': return await handler.showSignatureHelp(); case 'documentSymbols': return await handler.getDocumentSymbols(); case 'selectionRanges': return await handler.getSelectionRanges(); case 'rangeSelect': return await handler.selectRange(args[1], args[2]); case 'rename': await handler.rename(args[1]); return; case 'workspaceSymbols': this.nvim.command('CocList -I symbols', true); return; case 'formatSelected': return await handler.documentRangeFormatting(args[1]); case 'format': return await handler.documentFormatting(); case 'commands': return await handler.getCommands(); case 'services': return services_1.default.getServiceStats(); case 'toggleService': return services_1.default.toggle(args[1]); case 'codeAction': return handler.doCodeAction(args[1], args[2]); case 'doCodeAction': return await handler.applyCodeAction(args[1]); case 'codeActions': return await handler.getCurrentCodeActions(args[1], args[2]); case 'quickfixes': return await handler.getCurrentCodeActions(args[1], [vscode_languageserver_types_1.CodeActionKind.QuickFix]); case 'codeLensAction': return handler.doCodeLensAction(); case 'runCommand': return await handler.runCommand(...args.slice(1)); case 'doQuickfix': return await handler.doQuickfix(); case 'refactor': return await handler.doRefactor(); case 'repeatCommand': return await commands_1.default.repeatCommand(); case 'extensionStats': return await extensions_1.default.getExtensionStates(); case 'activeExtension': return extensions_1.default.activate(args[1], false); case 'deactivateExtension': return extensions_1.default.deactivate(args[1]); case 'reloadExtension': return await extensions_1.default.reloadExtension(args[1]); case 'toggleExtension': return await extensions_1.default.toggleExtension(args[1]); case 'uninstallExtension': return await extensions_1.default.uninstallExtension(args.slice(1)); case 'getCurrentFunctionSymbol': return await handler.getCurrentFunctionSymbol(); default: workspace_1.default.showMessage(`unknown action ${args[0]}`, 'error'); } } catch (e) { let message = e.hasOwnProperty('message') ? e.message : e.toString(); if (!/\btimeout\b/.test(message)) { workspace_1.default.showMessage(`Error on '${args[0]}': ${message}`, 'error'); } if (e.stack) logger.error(e.stack); } } async dispose() { this.removeAllListeners(); manager_2.default.dispose(); workspace_1.default.dispose(); sources_1.default.dispose(); await services_1.default.stopAll(); services_1.default.dispose(); if (this.handler) { this.handler.dispose(); } manager_3.default.dispose(); commands_1.default.dispose(); completion_1.default.dispose(); manager_1.default.dispose(); } } exports.default = Plugin; //# sourceMappingURL=plugin.js.map