lib/repl/extensions.js
const process = require("process");
const fs = require("fs");
const { SpecialForms } = require("../interp/registry.js");
const { TopEnv } = require("../interp/environment.js");
const { Eggvm } = require("../interp/eggvm.js");
const colors = require("./colors.js");
// PROMPT
TopEnv["__PROMPT__"] = "> ";
const getPromptLine = () => {
return `${colors.YELLOW} ${TopEnv["__PROMPT__"]} ${colors.DEFAULT}`;
};
// Extra methods
const eggExit = (TopEnv["exit"] = () => {
console.log(colors.BLUE + "Closing the REPL... Bye!" + colors.DEFAULT);
process.exit(0);
});
const HELP = [
`${colors.BLUE} help() ${colors.DEFAULT} show this help menu`,
`${colors.RED} exit() | Ctrl-D ${colors.DEFAULT} close the REPL`,
`${colors.GREEN} run() ${colors.DEFAULT} execute a .egg file`,
`${colors.YELLOW} clear() ${colors.DEFAULT} clear the console`
];
const eggHelp = (TopEnv["help"] = () => {
console.log(" Egg help menu:");
HELP.forEach(line => {
console.log(line);
});
return "-".repeat(HELP[0].length - 10);
});
const eggInfo = (TopEnv["info"] = () => {
console.log(
colors.BLUE +
`
_ _ _
| | | | | |
___ __ _ __ _| |_ ___ _ __ __| | ___ __| |
/ _ \\/ _\` |/ _\` | __/ _ \\ '_ \\ / _\` |/ _ \\/ _\` |
| __/ (_| | (_| | || __/ | | | (_| | __/ (_| |
\\___|\\__, |\\__, |\\__\\___|_| |_|\\__,_|\\___|\\__,_|
__/ | __/ |
|___/ |___/
` +
colors.DEFAULT
);
console.log(`Version ${TopEnv["__VERSION__"]}`);
console.log(`Created by David Afonso Dorta. License: ${TopEnv["__LICENSE__"]}`);
});
const eggClear = (TopEnv["clear"] = () => {
console.log("\u001B[2J\u001B[0;0f");
eggInfo();
});
const eggVersion = (TopEnv[
"__VERSION__"
] = require("../../package.json").version);
const eggLicense = (TopEnv["__LICENSE__"] = require("../../package.json").license);
const eggRun = (TopEnv["run"] = (file, debug) => {
if (debug) {
console.log(fs.readFileSync(file, "utf8"));
}
Eggvm.runFromFile(file);
});
const eggCompleter = (line, env) => {
// Test if get hits from current directory
let hits = dirHits(line);
// Show hits from the REPL variables
if (hits.length === 0) {
const word = line.split(/[\s(),"]+/).slice(-1)[0];
hits = _filter(Object.keys(SpecialForms).concat(_allProperties(env)), word);
}
return [hits, line];
};
const _allProperties = obj => {
let keys = [];
let proto = obj;
while (proto) {
keys = keys.concat(Object.keys(proto));
proto = Object.getPrototypeOf(proto);
}
return keys;
};
const dirHits = line => {
const match = line.match(/(?:run)\((.*)/);
if (match) {
const path = match[1]
.replace(/["'`]/, "")
.trim()
.split("/");
const dirPath = path.slice(0, -1);
const filePath = path.slice(-1);
try {
return _filter(fs.readdirSync(`./${dirPath}`), filePath);
} catch (err) {
return [];
}
}
return [];
};
const _filter = (hits, word) => {
return hits.filter(hit => {
return hit.indexOf(word) === 0;
});
};
module.exports = {
getPromptLine,
eggExit,
eggHelp,
eggInfo,
eggClear,
eggVersion,
eggLicense,
eggRun,
eggCompleter
};