UNPKG

neovim

Version:

Nvim msgpack API client and remote plugin provider

126 lines (125 loc) 5.88 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.Host = void 0; const attach_1 = require("../attach/attach"); const factory_1 = require("./factory"); class Host { constructor() { // Map for loaded plugins this.loaded = {}; this.handler = this.handler.bind(this); this.handlePlugin = this.handlePlugin.bind(this); } getPlugin(filename, options = {}) { var _a; let plugin = this.loaded[filename]; const shouldUseCachedPlugin = plugin && plugin.shouldCacheModule && !plugin.alwaysInit; if (shouldUseCachedPlugin) { (_a = this.nvim) === null || _a === void 0 ? void 0 : _a.logger.debug('getPlugin.useCachedPlugin'); return plugin; } if (!this.nvim) { throw Error(); } plugin = (0, factory_1.loadPlugin)(filename, this.nvim, Object.assign(Object.assign({}, options), { cache: plugin && plugin.shouldCacheModule })); this.nvim.logger.debug('getPlugin.alwaysInit', plugin && !plugin.alwaysInit); if (plugin) { this.loaded[filename] = plugin; } return plugin; } // Route incoming request to a plugin handlePlugin(method, args) { return __awaiter(this, void 0, void 0, function* () { var _a, _b; // ignore methods that start with nvim_ prefix (e.g. when attaching to buffer and listening for notifications) if (method.startsWith('nvim_')) return null; (_a = this.nvim) === null || _a === void 0 ? void 0 : _a.logger.debug('host.handlePlugin: %s', method); // Parse method name const procInfo = method.split(':'); if (process.platform === 'win32') { // Windows-style absolute paths is formatted as [A-Z]:\path\to\file. // Forward slash as path separator is ok // so Neovim uses it to avoid escaping backslashes. // // For absolute path of cmd.exe with forward slash as path separator, // method.split(':') returns ['C', '/Windows/System32/cmd.exe', ...]. // procInfo should be ['C:/Windows/System32/cmd.exe', ...]. const networkDrive = procInfo.shift(); procInfo[0] = `${networkDrive}:${procInfo[0]}`; } const filename = procInfo[0]; const type = procInfo[1]; const procName = `${procInfo.slice(2).join(' ')}`; const plugin = this.getPlugin(filename); if (!plugin) { const msg = `Could not load plugin: ${filename}`; (_b = this.nvim) === null || _b === void 0 ? void 0 : _b.logger.error(msg); throw new Error(msg); } return plugin.handleRequest(procName, type, args); }); } handleRequestSpecs(_method, args, res) { var _a, _b, _c; const filename = args[0]; (_a = this.nvim) === null || _a === void 0 ? void 0 : _a.logger.debug(`requested specs for ${filename}`); // Can return null if there is nothing defined in plugin const plugin = this.getPlugin(filename); const specs = (plugin && plugin.specs) || []; (_b = this.nvim) === null || _b === void 0 ? void 0 : _b.logger.debug(JSON.stringify(specs)); res.send(specs); (_c = this.nvim) === null || _c === void 0 ? void 0 : _c.logger.debug('specs: %O', specs); } handler(method, args, res) { return __awaiter(this, void 0, void 0, function* () { var _a; (_a = this.nvim) === null || _a === void 0 ? void 0 : _a.logger.debug('request received: %s', method); // 'poll' and 'specs' are requests by neovim, // otherwise it will if (method === 'poll') { // Handshake for neovim res.send('ok'); } else if (method === 'specs') { // Return plugin specs this.handleRequestSpecs(method, args, res); } else { try { const plugResult = yield this.handlePlugin(method, args); res.send(!plugResult || typeof plugResult === 'undefined' ? null : plugResult); } catch (e) { const err = e; res.send(err.toString(), true); } } }); } start(_a) { return __awaiter(this, arguments, void 0, function* ({ proc }) { // stdio is reversed since it's from the perspective of Neovim const nvim = (0, attach_1.attach)({ reader: proc.stdin, writer: proc.stdout }); this.nvim = nvim; this.nvim.logger.debug('host.start'); nvim.on('request', this.handler); nvim.on('notification', this.handlePlugin); nvim.on('disconnect', () => { var _a; (_a = this.nvim) === null || _a === void 0 ? void 0 : _a.logger.debug('host.disconnected'); }); }); } } exports.Host = Host;