@eagleoutice/flowr
Version:
Static Dataflow Analyzer and Program Slicer for the R Programming Language
187 lines (184 loc) • 7.59 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.helpCommand = void 0;
exports.getReplCommands = getReplCommands;
exports.getCommandNames = getCommandNames;
exports.getCommand = getCommand;
exports.asOptionName = asOptionName;
exports.longestCommandName = longestCommandName;
exports.padCmd = padCmd;
const repl_quit_1 = require("./repl-quit");
const execute_1 = require("../execute");
const prompt_1 = require("../prompt");
const repl_version_1 = require("./repl-version");
const repl_parse_1 = require("./repl-parse");
const repl_execute_1 = require("./repl-execute");
const repl_normalize_1 = require("./repl-normalize");
const repl_dataflow_1 = require("./repl-dataflow");
const repl_cfg_1 = require("./repl-cfg");
const ansi_1 = require("../../../util/text/ansi");
const args_1 = require("../../../util/text/args");
const assert_1 = require("../../../util/assert");
const scripts_info_1 = require("../../common/scripts-info");
const repl_lineage_1 = require("./repl-lineage");
const repl_query_1 = require("./repl-query");
function printHelpForScript(script, f, starredVersion) {
let base = ` ${(0, ansi_1.bold)(padCmd(':' + script[0] + (starredVersion ? '[*]' : '')), f)}${script[1].description}`;
if (starredVersion) {
base += ` (star: ${starredVersion.description})`;
}
if (script[1].aliases.length === 0) {
return base;
}
const aliases = script[1].aliases;
return `${base} (alias${aliases.length > 1 ? 'es' : ''}: ${aliases.map(a => (0, ansi_1.bold)(':' + a, f)).join(', ')})`;
}
function printCommandHelp(formatter) {
const scriptHelp = [];
const cmds = getReplCommands();
for (const c of Object.entries(cmds)) {
if (c[1].script || c[0].endsWith('*')) {
continue;
}
const starred = cmds[c[0] + '*'];
scriptHelp.push(printHelpForScript(c, formatter, starred));
}
return scriptHelp.sort().join('\n');
}
exports.helpCommand = {
description: 'Show help information',
script: false,
usageExample: ':help',
aliases: ['h', '?'],
fn: output => {
initCommandMapping();
output.stdout(`
If enabled ('--r-session-access' and if using the 'r-shell' engine), you can just enter R expressions which get evaluated right away:
${prompt_1.rawPrompt} ${(0, ansi_1.bold)('1 + 1', output.formatter)}
${(0, ansi_1.italic)('[1] 2', output.formatter)}
Besides that, you can use the following commands. The scripts ${(0, ansi_1.italic)('can', output.formatter)} accept further arguments. In general, those ending with [*] may be called with and without the star.
There are the following basic commands:
${printCommandHelp(output.formatter)}
Furthermore, you can directly call the following scripts which accept arguments. If you are unsure, try to add ${(0, ansi_1.italic)('--help', output.formatter)} after the command.
${Array.from(Object.entries(getReplCommands())).filter(([, { script }]) => script).map(([command, { description }]) => ` ${(0, ansi_1.bold)(padCmd(':' + command), output.formatter)}${description}`).sort().join('\n')}
You can combine commands by separating them with a semicolon ${(0, ansi_1.bold)(';', output.formatter)}.
`);
}
};
/**
* All commands that should be available in the REPL.
*/
const _commands = {
'help': exports.helpCommand,
'quit': repl_quit_1.quitCommand,
'version': repl_version_1.versionCommand,
'execute': repl_execute_1.executeCommand,
'parse': repl_parse_1.parseCommand,
'normalize': repl_normalize_1.normalizeCommand,
'normalize*': repl_normalize_1.normalizeStarCommand,
'dataflow': repl_dataflow_1.dataflowCommand,
'dataflow*': repl_dataflow_1.dataflowStarCommand,
'dataflowsimple': repl_dataflow_1.dataflowSimplifiedCommand,
'dataflowsimple*': repl_dataflow_1.dataflowSimpleStarCommand,
'controlflow': repl_cfg_1.controlflowCommand,
'controlflow*': repl_cfg_1.controlflowStarCommand,
'controlflowbb': repl_cfg_1.controlflowBbCommand,
'controlflowbb*': repl_cfg_1.controlflowBbStarCommand,
'lineage': repl_lineage_1.lineageCommand,
'query': repl_query_1.queryCommand,
'query*': repl_query_1.queryStarCommand
};
let commandsInitialized = false;
function hasModule(path) {
try {
require.resolve(path);
return true;
}
catch {
return false;
}
}
function getReplCommands() {
if (commandsInitialized) {
return _commands;
}
commandsInitialized = true;
for (const [script, { target, description, type }] of Object.entries(scripts_info_1.scripts)) {
if (type === 'master script') {
_commands[script] = {
description,
aliases: [],
script: true,
usageExample: `:${script} --help`,
fn: async (output, _s, remainingLine) => {
// check if the target *module* exists in the current directory, else try two dirs up, otherwise, fail with a message
let path = `${__dirname}/${target}`;
if (!hasModule(path)) {
path = `${__dirname}/../../${target}`;
if (!hasModule(path)) {
output.stderr(`Could not find the target script ${target} in the current directory or two directories up.`);
return;
}
}
await (0, execute_1.waitOnScript)(path, (0, args_1.splitAtEscapeSensitive)(remainingLine), stdio => (0, execute_1.stdioCaptureProcessor)(stdio, msg => output.stdout(msg), msg => output.stderr(msg)));
}
};
}
}
return _commands;
}
/**
* The names of all commands including their aliases (but without the leading `:`)
*/
function getCommandNames() {
if (commandNames === undefined) {
initCommandMapping();
}
return commandNames;
}
let commandNames = undefined;
// maps command names or aliases to the actual command name
let commandMapping = undefined;
function initCommandMapping() {
commandMapping = {};
commandNames = [];
for (const [command, { aliases }] of Object.entries(getReplCommands())) {
(0, assert_1.guard)(commandMapping[command] === undefined, `Command ${command} is already registered!`);
commandMapping[command] = command;
for (const alias of aliases) {
(0, assert_1.guard)(commandMapping[alias] === undefined, `Command (alias) ${alias} is already registered!`);
commandMapping[alias] = command;
}
commandNames.push(command);
commandNames.push(...aliases);
}
}
/**
* Get the command for a given command name or alias.
* @param command - The name of the command (without the leading `:`)
*/
function getCommand(command) {
if (commandMapping === undefined) {
initCommandMapping();
}
return getReplCommands()[commandMapping[command]];
}
function asOptionName(argument) {
if (argument.length == 1) {
return `-${argument}`;
}
else {
return `--${argument}`;
}
}
let _longestCommandName = undefined;
function longestCommandName() {
if (_longestCommandName === undefined) {
_longestCommandName = Array.from(Object.keys(getReplCommands()), k => k.endsWith('*') ? k.length + 3 : k.length).reduce((p, n) => Math.max(p, n), 0);
}
return _longestCommandName;
}
function padCmd(string) {
return String(string).padEnd(longestCommandName() + 2, ' ');
}
//# sourceMappingURL=repl-commands.js.map