Teascade.net/terminal/js/jsxcommands.js

417 lines
14 KiB
JavaScript

var JSXCommands;
(function (JSXCommands) {
/**
* Echoes the given arguments
*/
class Echo {
create(terminal, stdio, args) {
if (args.filter((a) => { return a != ""; }).length == 0) {
stdio.println("Nothing echoes... nothing");
terminal.closeProgram(this);
return;
}
stdio.println(args.join(" "));
terminal.closeProgram(this);
}
enable() { }
disable() { }
onClose() { return true; }
getManual() {
return "Echoes the given arguments" +
"\n\nUsage: echo [anything to echo]";
}
}
JSXCommands.Echo = Echo;
/**
* Lists all files in the given directory or this directory, if path not specified.
*/
class List {
constructor(jsx) {
this.jsx = jsx;
}
create(terminal, stdio, args) {
let folder = this.jsx.currentFolder;
if (args.length > 0) {
let pathStr = args.slice(-1)[0];
let path = this.jsx.findPath(pathStr);
if (path instanceof JavaScriptX.Folder) {
args.splice(-1);
folder = path;
}
}
let argObj = parseArgsToObject(args);
let a = "a" in argObj;
if (a) {
stdio.println(".", "blue");
if (folder.parentFolder != null) {
stdio.println("..", "blue");
}
}
let files = folder.files.filter(f => (!f.hidden || a));
for (let i = 0; i < files.length; i++) {
let f = files[i];
stdio.println(JavaScriptX.formatToLength(f.name, 20), ((f.hidden) ? "blue" : (f instanceof JavaScriptX.Folder) ? "red" : "yellow"));
stdio.print(" " +
((f instanceof JavaScriptX.Folder) ? "DIR" : ((f instanceof JavaScriptX.BinaryFile) ? "BIN" : "TXT")));
stdio.print(" " + new Date(f.created).toLocaleString());
}
terminal.closeProgram(this);
}
enable() { }
disable() { }
onClose() { return true; }
getManual() {
return "Lists all files in the given directory\nor this directory, if path not specified." +
"\n\nUsage: ls [options] [path]" +
"\n\nOptions:\n " + JavaScriptX.formatToLength("-a", 10) + "List all files (incl. hidden)";
}
}
JSXCommands.List = List;
/**
* Changes directory to the specified directory.
*/
class ChangeDirectory {
constructor(jsx) {
this.jsx = jsx;
}
create(terminal, stdio, args) {
if (args.length == 0) {
stdio.println("Insufficent parameters, usage:");
stdio.println("cd [path]");
terminal.closeProgram(this);
return;
}
let path = this.jsx.findPath(args[0]);
let folder = false;
if (path) {
if (path instanceof JavaScriptX.Folder) {
folder = true;
}
else {
stdio.println(`'${args[0]}' is not a folder.`);
}
}
else {
stdio.println(`'${args[0]}' not found.`);
}
if (folder && path instanceof JavaScriptX.Folder) {
this.jsx.currentFolder = path;
}
terminal.closeProgram(this);
}
enable() { }
disable() { }
onClose() { return true; }
getManual() {
return "Changes directory to the specified directory." +
"\n\nUsage: cd [path]";
}
}
JSXCommands.ChangeDirectory = ChangeDirectory;
/**
* Creates a directory at specified location.
*/
class MakeDirectory {
constructor(jsx) {
this.jsx = jsx;
}
create(terminal, stdio, args) {
if (args.length == 0) {
stdio.println("Insufficent parameters, usage:");
stdio.println("mkdir [path]");
terminal.closeProgram(this);
return;
}
let pathArg = args.splice(-1)[0];
let argObj = parseArgsToObject(args);
let h = "h" in argObj;
let origPathpieces = pathArg.split("/");
let curr = [origPathpieces[0]];
let i = 0;
let createFolder = false;
do {
let path = this.jsx.findPath(curr.join("/"));
if (!path) {
if (origPathpieces.length == curr.length) {
createFolder = true;
}
else {
stdio.println(`${curr.join("/")} not found!`);
}
break;
}
else if (path && origPathpieces.length == curr.length) {
stdio.println(`${curr.join("/")} already exists!`);
}
else if (!(path instanceof JavaScriptX.Folder)) {
stdio.println(`${curr.join("/")} is not a folder!`);
}
if (i < origPathpieces.length) {
i += 1;
curr.push(origPathpieces[i]);
}
} while (curr.length < origPathpieces.length + 1);
if (createFolder) {
let path = origPathpieces.slice(0, -1).join("/");
let name = origPathpieces.slice(-1)[0];
let relative = this.jsx.findPath(path);
if (relative instanceof JavaScriptX.Folder) {
relative.addFile(new JavaScriptX.Folder(name, h));
}
else {
stdio.println("An error occoured creating the folder.");
}
}
terminal.closeProgram(this);
}
enable() { }
disable() { }
onClose() { return true; }
getManual() {
return "Creates a directory at specified location." +
"\n\nUsage: mkdir [options] [path]" +
"\n\nOptions:\n " + JavaScriptX.formatToLength("-h", 10) + "Makes the folder hidden.";
}
}
JSXCommands.MakeDirectory = MakeDirectory;
/**
* The Woman in the JSX equivalent to the UNIX Man.
* It's called Woman (not Man) because of the funny wording,
* where 'man' sounds like the gender 'man'
*/
class Woman {
constructor(jsx) {
this.jsx = jsx;
}
create(terminal, stdio, args) {
if (args.length == 0) {
this.readManual(stdio, this);
terminal.closeProgram(this);
return;
}
let filePath = args.slice(-1)[0];
for (let env in this.jsx.environmentVariables) {
if (filePath == env) {
filePath = env;
break;
}
let envFolder = this.jsx.findPath(this.jsx.environmentVariables[env]);
if (envFolder instanceof JavaScriptX.Folder) {
for (let i = 0; i < envFolder.files.length; i++) {
if (envFolder.files[i].name == filePath) {
filePath = envFolder.files[i].getPath();
break;
}
}
}
}
let f = this.jsx.findPath(filePath);
if (f && f instanceof JavaScriptX.BinaryFile && manualGuard(f.program)) {
this.readManual(stdio, f.program);
}
else {
stdio.println("Nothing to womansplain.");
}
terminal.closeProgram(this);
}
enable() { }
disable() { }
onClose() { return true; }
getManual() {
return "The Woman in the JSX equivalent to the UNIX Man. " +
"It's called Woman (not Man) because of the funny wording, " +
"where 'man' sounds like the gender 'man'" +
"\n\nUsage: woman [path]";
}
readManual(stdio, manual) {
stdio.println(manual.getManual());
}
}
JSXCommands.Woman = Woman;
class Caternate {
constructor(jsx) {
this.jsx = jsx;
}
create(terminal, stdio, args) {
if (args.length == 0) {
stdio.println("Insufficent arguments.");
stdio.println("\nUsage: cat [path]");
terminal.closeProgram(this);
return;
}
let path = args.splice(-1)[0];
let file = this.jsx.findPath(path);
if (file instanceof JavaScriptX.BinaryFile) {
stdio.println("Unable to read binary files (yet).");
}
else if (file instanceof JavaScriptX.Folder) {
stdio.println(file.name, "blue");
stdio.print(" is a DIRectory containing ");
stdio.print(file.files.length + "", "red");
stdio.print(" files.");
}
else if (file instanceof JavaScriptX.TextFile) {
let contents = file.readContent();
stdio.println(contents);
}
terminal.closeProgram(this);
}
enable() { }
disable() { }
onClose() { return true; }
getManual() {
return "[cat]ernate reads data from given file and outputs it." +
"\n\nUsage: cat [path]";
}
readManual(stdio, manual) {
stdio.println(manual.getManual());
}
}
JSXCommands.Caternate = Caternate;
class Touch {
constructor(jsx) {
this.jsx = jsx;
}
create(terminal, stdio, args) {
if (args.length == 0) {
stdio.println("Insufficent arguments.");
stdio.println("\nUsage: touch [path]");
terminal.closeProgram(this);
return;
}
let path = args.splice(-1)[0];
let file = this.jsx.findPath(path);
if (file) {
file.created = new Date().getTime();
}
else {
let origPathparts = path.split("/");
let curr = [origPathparts[0]];
for (let i = 1; i < origPathparts.length; i++) {
let currFile = this.jsx.findPath(curr.join("/"));
if (!currFile) {
stdio.println(`${curr.join("/")} not found.`);
terminal.closeProgram(this);
return;
}
curr.push(origPathparts[i]);
}
let filename = curr.splice(-1);
let folder = this.jsx.findPath(curr.join("/"));
if (folder instanceof JavaScriptX.Folder) {
folder.addFile(new JavaScriptX.TextFile(filename[0]));
}
else {
stdio.println(`${curr.join("/")} is not a folder.`);
}
}
terminal.closeProgram(this);
}
enable() { }
disable() { }
onClose() { return true; }
getManual() {
return "Touch touches the file specified updating it's timestamp. If the file doesn't exist, it's created." +
"\n\nUsage: touch [path]";
}
readManual(stdio, manual) {
stdio.println(manual.getManual());
}
}
JSXCommands.Touch = Touch;
class JEdi {
constructor(jsx) {
this.text = [""];
this.row = 0;
this.jsx = jsx;
}
create(terminal, stdio, args) {
this.stdio = stdio;
this.terminal = terminal;
this.doCommand();
}
enable() { }
disable() { }
onClose() { return true; }
getManual() {
return "(J)avascript (Edi)tor is a custom version of the UNIX editor 'ed'." +
"\nIt's quite simpler in the way that all of it's commands are whole words" +
"\n\nUsage: jedi [(optional) path]";
}
readManual(stdio, manual) {
stdio.println(manual.getManual());
}
doCommand() {
let readline = this.stdio.readline({
callback: c => this.exec(c),
prefix: "\n> ",
printAfterDone: true
});
}
exec(command) {
if (command == "exit" || command == "quit") {
this.terminal.closeProgram(this);
return;
}
else if (command.split(" ")[0] == "append") {
let appended = command.split(" ").slice(1).join(" ");
debugger;
console.log(appended);
let rows = appended.split("\n");
console.log(rows);
for (let i = 0; i < rows.length; i++) {
if (this.text.length <= (this.row + i)) {
this.text.push("");
}
this.text[this.row + i] += rows[i];
}
this.row += rows.length - 1;
this.stdio.println(`${this.text[this.row]}`);
}
this.doCommand();
}
}
JSXCommands.JEdi = JEdi;
/**
* Parses all given args from '--arg val' into format {arg: val}
*/
function parseArgsToObject(args, defaults = {}) {
let returned = {};
for (let key in defaults) {
returned[key] = defaults[key];
}
let currArg = null;
args.forEach(arg => {
if (arg.startsWith("-")) {
if (arg.startsWith("--")) {
if (currArg) {
returned[currArg] = null;
}
;
currArg = arg.substr(2);
return;
}
if (currArg) {
returned[currArg] = null;
}
;
currArg = arg.substr(1);
}
else {
if (currArg) {
returned[currArg] = arg;
currArg = null;
}
}
});
if (currArg) {
returned[currArg] = null;
}
;
return returned;
}
function manualGuard(arg) {
return arg.getManual !== undefined;
}
})(JSXCommands || (JSXCommands = {}));