UNPKG

semo-plugin-shell

Version:

A semo plugin to provide a quick shell.

125 lines (124 loc) 4.87 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()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.handler = exports.builder = exports.aliases = exports.desc = exports.command = exports.plugin = void 0; const repl_1 = __importDefault(require("repl")); const fs_extra_1 = __importDefault(require("fs-extra")); const core_1 = require("@semo/core"); let r; // repl instance exports.plugin = 'shell'; exports.command = 'shell'; exports.desc = 'Quick shell'; exports.aliases = 'sh'; function corepl(cli) { // @ts-ignore cli.eval = function coEval(cmd, context, filename, callback) { const { argv } = context; cmd = cmd.trim(); if (!cmd) { return callback(); } if (cmd.match(/^prefix[\s|=]+/) || cmd.trim() === 'prefix') { let prefix = core_1.Utils.splitByChar(cmd, '='); prefix.shift(); argv.prefix = prefix.join(' ').trim(); core_1.Utils.success(`Prefix has been changed to: ${argv.prefix || '[empty], so you can run any shell commands now.'}`); if (argv.prefix) { r._initialPrompt = `${argv.prefix}:${argv.prompt}`; } else { r._initialPrompt = `${argv.prompt}`; } return callback(); } const patternScriptShell = new RegExp(`^${argv.scriptName}\\s+(shell|sh)\\s+`); if (`${argv.prefix} ${cmd}`.match(patternScriptShell)) { core_1.Utils.warn('Recursive call shell not allowed!'); return callback(); } const patternScript = new RegExp(`^${argv.scriptName}\\s+`); if (`${argv.prefix} ${cmd}`.match(patternScript)) { cmd = `${argv.prefix} ${cmd} --exec-mode`; } else { cmd = `${argv.prefix} ${cmd}`; } try { cmd && core_1.Utils.exec(cmd); } catch (e) { if (argv.debug) { core_1.Utils.error(e.stack, false); } else { core_1.Utils.error(e.message, false); } } return callback(); }; return cli; } function openRepl(context) { return __awaiter(this, void 0, void 0, function* () { const { argv } = context; const prefix = argv.prefix || ''; r = repl_1.default.start({ prompt: prefix ? `${prefix}:${argv.prompt}` : argv.prompt, completer: line => { const completions = '.break .clear .exit .save .load .editor prefix'.split(' '); const hits = completions.filter(c => c.startsWith(line)); // 如果没有匹配,则显示所有补全。 return [hits.length ? hits : completions, line]; }, }); const Home = process.env.HOME + `/.${argv.scriptName}`; fs_extra_1.default.ensureDirSync(Home); core_1.Utils.replHistory(r, `${Home}/.${argv.scriptName}_shell_history`); // @ts-ignore // context即为REPL中的上下文环境 r.context = Object.assign(r.context, context); corepl(r); }); } const builder = function (yargs) { yargs.option('prompt', { describe: 'Prompt for input.', }); yargs.option('prefix', { describe: 'Make input command a little bit faster.', }); yargs.option('debug', { describe: 'Debug mode, show error stack', }); }; exports.builder = builder; const handler = function (argv) { return __awaiter(this, void 0, void 0, function* () { const scriptName = argv.scriptName || 'semo'; const { Utils } = argv.$semo; argv.prefix = Utils.pluginConfig('prefix', scriptName); argv.prompt = Utils.pluginConfig('prompt', '$ '); argv.debug = Utils.pluginConfig('debug', false); try { let context = { argv }; yield openRepl(context); return false; } catch (e) { Utils.error(e.stack); } return true; }); }; exports.handler = handler;