UNPKG

coc.nvim

Version:

LSP based intellisense engine for neovim & vim8.

272 lines 10 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const tslib_1 = require("tslib"); const vscode_languageserver_protocol_1 = require("vscode-languageserver-protocol"); const util_1 = require("./util"); const workspace_1 = tslib_1.__importDefault(require("./workspace")); const manager_1 = tslib_1.__importDefault(require("./snippets/manager")); const manager_2 = tslib_1.__importDefault(require("./diagnostic/manager")); const vscode_uri_1 = require("vscode-uri"); const logger = require('./util/logger')('commands'); class CommandItem { constructor(id, impl, thisArg, internal = false) { this.id = id; this.impl = impl; this.thisArg = thisArg; this.internal = internal; } execute(...args) { let { impl, thisArg } = this; return impl.apply(thisArg, args || []); } dispose() { this.thisArg = null; this.impl = null; } } class CommandManager { constructor() { this.commands = new Map(); this.titles = new Map(); } init(nvim, plugin) { this.register({ id: 'vscode.open', execute: async (url) => { nvim.call('coc#util#open_url', url.toString(), true); } }, true); this.register({ id: 'workbench.action.reloadWindow', execute: () => { nvim.command('CocRestart', true); } }, true); this.register({ id: 'editor.action.insertSnippet', execute: async (edit) => { let doc = workspace_1.default.getDocument(workspace_1.default.bufnr); if (!doc) return; await nvim.call('coc#_cancel', []); if (doc.dirty) doc.forceSync(); await manager_1.default.insertSnippet(edit.newText, true, edit.range); } }, true); this.register({ id: 'editor.action.doCodeAction', execute: async (action) => { await plugin.cocAction('doCodeAction', action); } }, true); this.register({ id: 'editor.action.triggerSuggest', execute: async () => { await util_1.wait(100); nvim.call('coc#start', [], true); } }, true); this.register({ id: 'editor.action.triggerParameterHints', execute: async () => { await util_1.wait(60); await plugin.cocAction('showSignatureHelp'); } }, true); this.register({ id: 'editor.action.restart', execute: async () => { await util_1.wait(30); nvim.command('CocRestart', true); } }, true); this.register({ id: 'editor.action.showReferences', execute: async (_filepath, _position, references) => { await workspace_1.default.showLocations(references); } }, true); this.register({ id: 'editor.action.rename', execute: async (uri, position) => { await workspace_1.default.jumpTo(uri, position); await plugin.cocAction('rename'); } }, true); this.register({ id: 'editor.action.format', execute: async () => { await plugin.cocAction('format'); } }, true); this.register({ id: 'workspace.diffDocument', execute: async () => { let document = await workspace_1.default.document; if (!document) return; let lines = document.content.split('\n'); await nvim.call('coc#util#diff_content', [lines]); } }, true); this.register({ id: 'workspace.clearWatchman', execute: async () => { await workspace_1.default.runCommand('watchman watch-del-all'); } }); this.register({ id: 'workspace.workspaceFolders', execute: async () => { let folders = workspace_1.default.workspaceFolders; let lines = folders.map(folder => vscode_uri_1.URI.parse(folder.uri).fsPath); await workspace_1.default.echoLines(lines); } }); this.register({ id: 'workspace.renameCurrentFile', execute: async () => { await workspace_1.default.renameCurrent(); } }); this.register({ id: 'extensions.toggleAutoUpdate', execute: async () => { let config = workspace_1.default.getConfiguration('coc.preferences'); let interval = config.get('extensionUpdateCheck', 'daily'); if (interval == 'never') { config.update('extensionUpdateCheck', 'daily', true); workspace_1.default.showMessage('Extension auto update enabled.', 'more'); } else { config.update('extensionUpdateCheck', 'never', true); workspace_1.default.showMessage('Extension auto update disabled.', 'more'); } } }); this.register({ id: 'workspace.diagnosticRelated', execute: () => { return manager_2.default.jumpRelated(); } }); this.register({ id: 'workspace.showOutput', execute: async (name) => { if (name) { workspace_1.default.showOutputChannel(name); } else { let names = workspace_1.default.channelNames; if (names.length == 0) return; if (names.length == 1) { workspace_1.default.showOutputChannel(names[0]); } else { let idx = await workspace_1.default.showQuickpick(names); if (idx == -1) return; let name = names[idx]; workspace_1.default.showOutputChannel(name); } } } }); } get commandList() { let res = []; for (let item of this.commands.values()) { if (!item.internal) res.push(item); } return res; } dispose() { for (const registration of this.commands.values()) { registration.dispose(); } this.commands.clear(); } execute(command) { let args = [command.command]; let arr = command.arguments; if (arr) args.push(...arr); this.executeCommand.apply(this, args); } register(command, internal = false) { for (const id of Array.isArray(command.id) ? command.id : [command.id]) { this.registerCommand(id, command.execute, command, internal); } return command; } has(id) { return this.commands.has(id); } unregister(id) { let item = this.commands.get(id); if (!item) return; item.dispose(); this.commands.delete(id); } /** * Registers a command that can be invoked via a keyboard shortcut, * a menu item, an action, or directly. * * Registering a command with an existing command identifier twice * will cause an error. * * @param command A unique identifier for the command. * @param impl A command handler function. * @param thisArg The `this` context used when invoking the handler function. * @return Disposable which unregisters this command on disposal. */ registerCommand(id, impl, thisArg, internal = false) { if (/^_/.test(id)) internal = true; this.commands.set(id, new CommandItem(id, impl, thisArg, internal)); return vscode_languageserver_protocol_1.Disposable.create(() => { this.commands.delete(id); }); } /** * Executes the command denoted by the given command identifier. * * * *Note 1:* When executing an editor command not all types are allowed to * be passed as arguments. Allowed are the primitive types `string`, `boolean`, * `number`, `undefined`, and `null`, as well as [`Position`](#Position), [`Range`](#Range), [`URI`](#URI) and [`Location`](#Location). * * *Note 2:* There are no restrictions when executing commands that have been contributed * by extensions. * * @param command Identifier of the command to execute. * @param rest Parameters passed to the command function. * @return A promise that resolves to the returned value of the given command. `undefined` when * the command handler function doesn't return anything. */ executeCommand(command, ...rest) { let cmd = this.commands.get(command); if (!cmd) { workspace_1.default.showMessage(`Command: ${command} not found`, 'error'); return; } return Promise.resolve(cmd.execute.apply(cmd, rest)).catch(e => { workspace_1.default.showMessage(`Command error: ${e.message}`, 'error'); logger.error(e.stack); }); } async repeatCommand() { let mru = workspace_1.default.createMru('commands'); let mruList = await mru.load(); let first = mruList[0]; if (first) { await this.executeCommand(first); await workspace_1.default.nvim.command(`silent! call repeat#set("\\<Plug>(coc-command-repeat)", -1)`); } } } exports.CommandManager = CommandManager; exports.default = new CommandManager(); //# sourceMappingURL=commands.js.map