neovim
Version:
Nvim msgpack API client and remote plugin provider
174 lines (173 loc) • 6.51 kB
JavaScript
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.NvimPlugin = void 0;
exports.callable = callable;
function callable(fn) {
if (typeof fn === 'function') {
return fn;
}
if (Array.isArray(fn) && fn.length === 2) {
return function (...args) {
return fn[1].apply(fn[0], args);
};
}
throw new Error();
}
class NvimPlugin {
constructor(filename, plugin, nvim) {
this.filename = filename;
this.nvim = nvim;
this.dev = false;
this.alwaysInit = false;
this.autocmds = {};
this.commands = {};
this.functions = {};
// Simplifies class and decorator style plugins
try {
// eslint-disable-next-line new-cap
this.instance = new plugin(this);
}
catch (err) {
if (err instanceof TypeError) {
this.instance = plugin(this);
}
else {
throw err;
}
}
}
setOptions(options) {
this.dev = options.dev === undefined ? this.dev : options.dev;
this.alwaysInit = !!options.alwaysInit;
}
// Cache module (in dev mode will clear the require module cache)
get shouldCacheModule() {
return !this.dev;
}
registerAutocmd(name, fn, options) {
if (!(options === null || options === void 0 ? void 0 : options.pattern)) {
this.nvim.logger.error(`registerAutocmd expected pattern option for ${name}`);
return;
}
const spec = {
type: 'autocmd',
name,
sync: !!(options === null || options === void 0 ? void 0 : options.sync),
opts: {},
};
// @ts-expect-error changing `option: keyof …` to `option: string` causes other errors.
['pattern', 'eval'].forEach((option) => {
if (options && typeof options[option] !== 'undefined') {
spec.opts[option] = options[option];
}
});
try {
this.autocmds[`${name} ${options.pattern}`] = {
fn: callable(fn),
spec,
};
}
catch (err) {
this.nvim.logger.error(`registerAutocmd expected callable argument for ${name}`);
}
}
registerCommand(name, fn, options) {
const spec = {
type: 'command',
name,
sync: !!(options === null || options === void 0 ? void 0 : options.sync),
opts: {},
};
// @ts-expect-error changing `option: keyof …` to `option: string` causes other errors.
['range', 'nargs', 'complete'].forEach((option) => {
if (options && typeof options[option] !== 'undefined') {
spec.opts[option] = options[option];
}
});
try {
this.commands[name] = {
fn: callable(fn),
spec,
};
}
catch (err) {
this.nvim.logger.error(`registerCommand expected callable argument for ${name}`);
}
}
registerFunction(name, fn, options) {
const spec = {
type: 'function',
name,
sync: !!(options === null || options === void 0 ? void 0 : options.sync),
opts: {},
};
// @ts-expect-error changing `option: keyof …` to `option: string` causes other errors.
['range', 'eval'].forEach((option) => {
if (options && typeof options[option] !== 'undefined') {
spec.opts[option] = options[option];
}
});
try {
this.functions[name] = {
fn: callable(fn),
spec,
};
}
catch (err) {
this.nvim.logger.error(`registerFunction expected callable argument for ${name}`);
}
}
get specs() {
const autocmds = Object.keys(this.autocmds).map(key => this.autocmds[key].spec);
const commands = Object.keys(this.commands).map(key => this.commands[key].spec);
const functions = Object.keys(this.functions).map(key => this.functions[key].spec);
return autocmds.concat(commands).concat(functions);
}
handleRequest(name, type, args) {
return __awaiter(this, void 0, void 0, function* () {
let handlers;
switch (type) {
case 'autocmd':
handlers = this.autocmds;
break;
case 'command':
handlers = this.commands;
break;
case 'function':
handlers = this.functions;
break;
default:
const errMsg = `No handler for unknown type ${type}: "${name}" in ${this.filename}`;
this.nvim.logger.error(errMsg);
throw new Error(errMsg);
}
if (handlers.hasOwnProperty(name)) {
const handler = handlers[name];
try {
return handler.spec.sync ? handler.fn(...args) : yield handler.fn(...args);
}
catch (e) {
const err = e;
const msg = `Error in plugin for ${type}:${name}: ${err.message}`;
this.nvim.logger.error(`${msg} (file: ${this.filename}, stack: ${err.stack})`);
throw new Error(msg, { cause: err });
}
}
else {
const errMsg = `Missing handler for ${type}: "${name}" in ${this.filename}`;
this.nvim.logger.error(errMsg);
throw new Error(errMsg);
}
});
}
}
exports.NvimPlugin = NvimPlugin;
;