Implemented command options with input values
This commit is contained in:
parent
96a77f6f2e
commit
357792ec7d
31 changed files with 246 additions and 210 deletions
|
|
@ -19,7 +19,7 @@ See [features/apps/terminal/commands.js](../../../../src/features/apps/terminal/
|
||||||
```js
|
```js
|
||||||
// features/apps/terminal/commands/touch.js
|
// features/apps/terminal/commands/touch.js
|
||||||
|
|
||||||
export const touch = new Command("touch")
|
export const touch = new Command()
|
||||||
.setRequireArgs(true)
|
.setRequireArgs(true)
|
||||||
.setManual({
|
.setManual({
|
||||||
purpose: "Change file timestamps",
|
purpose: "Change file timestamps",
|
||||||
|
|
|
||||||
25
package-lock.json
generated
25
package-lock.json
generated
|
|
@ -31,6 +31,7 @@
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/plugin-proposal-private-property-in-object": "^7.21.11",
|
"@babel/plugin-proposal-private-property-in-object": "^7.21.11",
|
||||||
|
"babel-plugin-wildcard": "^7.0.0",
|
||||||
"eslint-plugin-jsdoc": "^46.4.6",
|
"eslint-plugin-jsdoc": "^46.4.6",
|
||||||
"gh-pages": "^5.0.0"
|
"gh-pages": "^5.0.0"
|
||||||
}
|
}
|
||||||
|
|
@ -5636,6 +5637,30 @@
|
||||||
"resolved": "https://registry.npmjs.org/babel-plugin-transform-react-remove-prop-types/-/babel-plugin-transform-react-remove-prop-types-0.4.24.tgz",
|
"resolved": "https://registry.npmjs.org/babel-plugin-transform-react-remove-prop-types/-/babel-plugin-transform-react-remove-prop-types-0.4.24.tgz",
|
||||||
"integrity": "sha512-eqj0hVcJUR57/Ug2zE1Yswsw4LhuqqHhD+8v120T1cl3kjg76QwtyBrdIk4WVwK+lAhBJVYCd/v+4nc4y+8JsA=="
|
"integrity": "sha512-eqj0hVcJUR57/Ug2zE1Yswsw4LhuqqHhD+8v120T1cl3kjg76QwtyBrdIk4WVwK+lAhBJVYCd/v+4nc4y+8JsA=="
|
||||||
},
|
},
|
||||||
|
"node_modules/babel-plugin-wildcard": {
|
||||||
|
"version": "7.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/babel-plugin-wildcard/-/babel-plugin-wildcard-7.0.0.tgz",
|
||||||
|
"integrity": "sha512-3duaRaULzxmmgr+YO9EPEE3m/irVyOWKvXCOz2S41tlp0g2UarSEtpM++D3IS+asK205OOqW1ajnjFeoRRqfZg==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"rimraf": "^2.6.2"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"bpwc": "index.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/babel-plugin-wildcard/node_modules/rimraf": {
|
||||||
|
"version": "2.7.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
|
||||||
|
"integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"glob": "^7.1.3"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"rimraf": "bin.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/babel-preset-current-node-syntax": {
|
"node_modules/babel-preset-current-node-syntax": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz",
|
||||||
|
|
|
||||||
|
|
@ -106,16 +106,30 @@ export function Terminal({ startPath, setTitle, close: exit, active }) {
|
||||||
|
|
||||||
// Get options
|
// Get options
|
||||||
const options = [];
|
const options = [];
|
||||||
args.filter((arg) => arg.startsWith("-")).forEach((option) => {
|
const inputs = {};
|
||||||
|
args.filter((arg) => arg.startsWith("-")).forEach((option, index) => {
|
||||||
|
const addOption = (key) => {
|
||||||
|
if (options.includes(key))
|
||||||
|
return;
|
||||||
|
|
||||||
|
options.push(key);
|
||||||
|
|
||||||
|
const commandOption = command.getOption(options[options.length - 1]);
|
||||||
|
|
||||||
|
if (commandOption?.isInput) {
|
||||||
|
const optionInput = args[args.indexOf(option) + 1];
|
||||||
|
inputs[commandOption.short] = optionInput;
|
||||||
|
removeFromArray(optionInput, args);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
if (option.startsWith("--")) {
|
if (option.startsWith("--")) {
|
||||||
const longOption = option.substring(2).toLowerCase();
|
const longOption = option.substring(2).toLowerCase();
|
||||||
if (!options.includes(longOption))
|
addOption(longOption);
|
||||||
options.push(longOption);
|
|
||||||
} else {
|
} else {
|
||||||
const shortOptions = option.substring(1).split("");
|
const shortOptions = option.substring(1).split("");
|
||||||
shortOptions.forEach((shortOption) => {
|
shortOptions.forEach((shortOption) => {
|
||||||
if (!options.includes(shortOption))
|
addOption(shortOption);
|
||||||
options.push(shortOption);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -143,7 +157,8 @@ export function Terminal({ startPath, setTitle, close: exit, active }) {
|
||||||
hostname: HOSTNAME,
|
hostname: HOSTNAME,
|
||||||
rawInputValue,
|
rawInputValue,
|
||||||
options,
|
options,
|
||||||
exit
|
exit,
|
||||||
|
inputs
|
||||||
});
|
});
|
||||||
|
|
||||||
if (response == null)
|
if (response == null)
|
||||||
|
|
@ -214,8 +229,10 @@ export function Terminal({ startPath, setTitle, close: exit, active }) {
|
||||||
submitInput(value);
|
submitInput(value);
|
||||||
setInputKey((previousKey) => previousKey + 1);
|
setInputKey((previousKey) => previousKey + 1);
|
||||||
} else if (key === "ArrowUp") {
|
} else if (key === "ArrowUp") {
|
||||||
|
event.preventDefault();
|
||||||
updateHistoryIndex(1);
|
updateHistoryIndex(1);
|
||||||
} else if (key === "ArrowDown") {
|
} else if (key === "ArrowDown") {
|
||||||
|
event.preventDefault();
|
||||||
updateHistoryIndex(-1);
|
updateHistoryIndex(-1);
|
||||||
} else if (!stream && (event.ctrlKey || event.metaKey) && key === "c") {
|
} else if (!stream && (event.ctrlKey || event.metaKey) && key === "c") {
|
||||||
setInputValue((value) => value + "^C");
|
setInputValue((value) => value + "^C");
|
||||||
|
|
|
||||||
|
|
@ -15,25 +15,27 @@ import { VirtualRoot } from "../../virtual-drive/root/virtualRoot.js";
|
||||||
* @param {string} options.rawInputValue
|
* @param {string} options.rawInputValue
|
||||||
* @param {string[]} options.options
|
* @param {string[]} options.options
|
||||||
* @param {Function} options.exit
|
* @param {Function} options.exit
|
||||||
|
* @param {[]} options.inputs
|
||||||
* @returns {string|{ blank: boolean }}
|
* @returns {string|{ blank: boolean }}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {object} optionType
|
||||||
|
* @property {string} long
|
||||||
|
* @property {string} short
|
||||||
|
* @property {boolean} isInput
|
||||||
|
*/
|
||||||
|
|
||||||
export default class Command {
|
export default class Command {
|
||||||
/** @type {string} */
|
/** @type {string} */
|
||||||
name;
|
name;
|
||||||
|
|
||||||
|
/** @type {optionType[]} */
|
||||||
|
options = [];
|
||||||
|
|
||||||
/** @type {executeType} */
|
/** @type {executeType} */
|
||||||
execute = () => {};
|
execute = () => {};
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {string} name
|
|
||||||
* @param {executeType} execute
|
|
||||||
*/
|
|
||||||
constructor(name, execute) {
|
|
||||||
this.name = name;
|
|
||||||
this.execute = execute;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {string} name
|
* @param {string} name
|
||||||
* @returns {Command}
|
* @returns {Command}
|
||||||
|
|
@ -78,4 +80,28 @@ export default class Command {
|
||||||
this.manual = { purpose, usage, description, options };
|
this.manual = { purpose, usage, description, options };
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {optionType} option
|
||||||
|
* @returns {Command}
|
||||||
|
*/
|
||||||
|
addOption({ short, long, isInput }) {
|
||||||
|
this.options.push({ short, long, isInput });
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} key
|
||||||
|
* @returns {optionType}
|
||||||
|
*/
|
||||||
|
getOption(key) {
|
||||||
|
let matchingOption = null;
|
||||||
|
|
||||||
|
this.options.forEach((option) => {
|
||||||
|
if (option.short === key || option.long === key)
|
||||||
|
matchingOption = option;
|
||||||
|
});
|
||||||
|
|
||||||
|
return matchingOption;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,29 +1,15 @@
|
||||||
import Command from "./command.js";
|
import Command from "./command.js";
|
||||||
import { cat } from "./commands/cat.js";
|
|
||||||
import { cd } from "./commands/cd.js";
|
// Dynamically import commands
|
||||||
import { clear } from "./commands/clear.js";
|
const context = require.context("./commands", false, /\.js$/);
|
||||||
import { compgen } from "./commands/compgen.js";
|
const commands = [];
|
||||||
import { cowsay } from "./commands/cowsay.js";
|
context.keys().forEach((key) => {
|
||||||
import { dir } from "./commands/dir.js";
|
const commandModule = context(key);
|
||||||
import { echo } from "./commands/echo.js";
|
const commandName = Object.keys(commandModule)[0];
|
||||||
import { exit } from "./commands/exit.js";
|
const command = commandModule[commandName];
|
||||||
import { fortune } from "./commands/fortune.js";
|
command.setName(commandName.toLowerCase());
|
||||||
import { help } from "./commands/help.js";
|
commands.push(command);
|
||||||
import { hostname } from "./commands/hostname.js";
|
});
|
||||||
import { ls } from "./commands/ls.js";
|
|
||||||
import { make } from "./commands/make.js";
|
|
||||||
import { man } from "./commands/man.js";
|
|
||||||
import { mkdir } from "./commands/mkdir.js";
|
|
||||||
import { neofetch } from "./commands/neofetch.js";
|
|
||||||
import { pwd } from "./commands/pwd.js";
|
|
||||||
import { reboot } from "./commands/reboot.js";
|
|
||||||
import { rm } from "./commands/rm.js";
|
|
||||||
import { rmdir } from "./commands/rmdir.js";
|
|
||||||
import { sl } from "./commands/sl.js";
|
|
||||||
import { touch } from "./commands/touch.js";
|
|
||||||
import { uptime } from "./commands/uptime.js";
|
|
||||||
import { whatis } from "./commands/whatis.js";
|
|
||||||
import { whoami } from "./commands/whoami.js";
|
|
||||||
|
|
||||||
export default class CommandsManager {
|
export default class CommandsManager {
|
||||||
/**
|
/**
|
||||||
|
|
@ -52,31 +38,5 @@ export default class CommandsManager {
|
||||||
return matches;
|
return matches;
|
||||||
}
|
}
|
||||||
|
|
||||||
static COMMANDS = [
|
static COMMANDS = commands;
|
||||||
echo,
|
|
||||||
clear,
|
|
||||||
ls,
|
|
||||||
cd,
|
|
||||||
dir,
|
|
||||||
pwd,
|
|
||||||
touch,
|
|
||||||
mkdir,
|
|
||||||
rm,
|
|
||||||
rmdir,
|
|
||||||
hostname,
|
|
||||||
neofetch,
|
|
||||||
fortune,
|
|
||||||
cowsay,
|
|
||||||
make,
|
|
||||||
cat,
|
|
||||||
man,
|
|
||||||
reboot,
|
|
||||||
compgen,
|
|
||||||
whoami,
|
|
||||||
whatis,
|
|
||||||
exit,
|
|
||||||
help,
|
|
||||||
uptime,
|
|
||||||
sl,
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import { VirtualFile } from "../../../virtual-drive/file/virtualFile.js";
|
import { VirtualFile } from "../../../virtual-drive/file/virtualFile.js";
|
||||||
import Command from "../command.js";
|
import Command from "../command.js";
|
||||||
|
|
||||||
export const cat = new Command("cat")
|
export const cat = new Command()
|
||||||
.setRequireArgs(true)
|
.setRequireArgs(true)
|
||||||
.setManual({
|
.setManual({
|
||||||
purpose: "Concetenate files and display on the terminal screen",
|
purpose: "Concetenate files and display on the terminal screen",
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import Command from "../command.js";
|
import Command from "../command.js";
|
||||||
|
|
||||||
export const cd = new Command("cd")
|
export const cd = new Command()
|
||||||
.setManual({
|
.setManual({
|
||||||
purpose: "Change the current directory",
|
purpose: "Change the current directory",
|
||||||
usage: "cd path",
|
usage: "cd path",
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import Command from "../command.js";
|
import Command from "../command.js";
|
||||||
|
|
||||||
export const clear = new Command("clear")
|
export const clear = new Command()
|
||||||
.setManual({
|
.setManual({
|
||||||
purpose: "Clear terminal screen",
|
purpose: "Clear terminal screen",
|
||||||
usage: "clear",
|
usage: "clear",
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import Command from "../command.js";
|
import Command from "../command.js";
|
||||||
import CommandsManager from "../commands.js";
|
import CommandsManager from "../commands.js";
|
||||||
|
|
||||||
export const compgen = new Command("compgen")
|
export const compgen = new Command()
|
||||||
.setRequireOptions(true)
|
.setRequireOptions(true)
|
||||||
.setExecute(function(args, { options }) {
|
.setExecute(function(args, { options }) {
|
||||||
if (options.includes("c")) {
|
if (options.includes("c")) {
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ const COW = `
|
||||||
||----w |
|
||----w |
|
||||||
|| ||`;
|
|| ||`;
|
||||||
|
|
||||||
export const cowsay = new Command("cowsay")
|
export const cowsay = new Command()
|
||||||
.setRequireArgs(true)
|
.setRequireArgs(true)
|
||||||
.setManual({
|
.setManual({
|
||||||
purpose: "Show a cow saying something",
|
purpose: "Show a cow saying something",
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import Command from "../command.js";
|
import Command from "../command.js";
|
||||||
|
|
||||||
export const dir = new Command("dir")
|
export const dir = new Command()
|
||||||
.setManual({
|
.setManual({
|
||||||
purpose: "List all directories in the current directory"
|
purpose: "List all directories in the current directory"
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import Command from "../command.js";
|
import Command from "../command.js";
|
||||||
|
|
||||||
export const echo = new Command("echo")
|
export const echo = new Command()
|
||||||
.setManual({
|
.setManual({
|
||||||
purpose: "Display text on the terminal screen"
|
purpose: "Display text on the terminal screen"
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import Command from "../command.js";
|
import Command from "../command.js";
|
||||||
|
|
||||||
export const exit = new Command("exit")
|
export const exit = new Command()
|
||||||
.setManual({
|
.setManual({
|
||||||
purpose: "Quit terminal interface"
|
purpose: "Quit terminal interface"
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -5,96 +5,56 @@ import Command from "../command.js";
|
||||||
* Source: https://github.com/shlomif/fortune-mod/blob/master/fortune-mod/datfiles/fortunes
|
* Source: https://github.com/shlomif/fortune-mod/blob/master/fortune-mod/datfiles/fortunes
|
||||||
*/
|
*/
|
||||||
const FORTUNES = [
|
const FORTUNES = [
|
||||||
"A day for firm decisions!!!!! Or is it?",
|
"Do not be afraid of competition.",
|
||||||
"Just to have it is enough.",
|
"An exciting opportunity lies ahead of you.",
|
||||||
"Keep emotionally active. Cater to your favorite neurosis.",
|
"You love peace.",
|
||||||
"Keep it short for pithy sake.",
|
"Get your mind set…confidence will lead you on.",
|
||||||
"Lady Luck brings added income today. Lady friend takes it away tonight.",
|
"You will always be surrounded by true friends.",
|
||||||
"Learn to pause -- or nothing worthwhile can catch up to you.",
|
"Sell your ideas-they have exceptional merit.",
|
||||||
"Let me put it this way: today is going to be a learning experience.",
|
"You should be able to undertake and complete anything.",
|
||||||
"Life is to you a dashing and bold adventure.",
|
"You are kind and friendly.",
|
||||||
"\"Life, loathe it or ignore it, you can't like it.\"\n\n -- Marvin, \"Hitchhiker's Guide to the Galaxy\"",
|
"You are wise beyond your years.",
|
||||||
"Live in a world of your own, but always welcome visitors.",
|
"Your ability to juggle many tasks will take you far.",
|
||||||
"Living your life is a task so difficult, it has never been attempted before.",
|
"A routine task will turn into an enchanting adventure.",
|
||||||
"Long life is in store for you.",
|
"Beware of all enterprises that require new clothes.",
|
||||||
"Look afar and see the end from the beginning.",
|
"Be true to your work, your word, and your friend.",
|
||||||
"Love is in the offing. Be affectionate to one who adores you.",
|
"Goodness is the only investment that never fails.",
|
||||||
"Make a wish, it might come true.",
|
"A journey of a thousand miles begins with a single step.",
|
||||||
"Many changes of mind and mood; do not hesitate too long.",
|
"Forget injuries; never forget kindnesses.",
|
||||||
"Never be led astray onto the path of virtue.",
|
"Respect yourself and others will respect you.",
|
||||||
"Never commit yourself! Let someone else commit you.",
|
"A man cannot be comfortable without his own approval.",
|
||||||
"Never give an inch!",
|
"Always do right. This will gratify some people and astonish the rest.",
|
||||||
"Never look up when dragons fly overhead.",
|
"It is easier to stay out than to get out.",
|
||||||
"Never reveal your best argument.",
|
"Sing everyday and chase the mean blues away.",
|
||||||
"Next Friday will not be your lucky day. As a matter of fact, you don't have a lucky day this year.",
|
"You will receive money from an unexpected source.",
|
||||||
"Of course you have a purpose -- to find a purpose.",
|
"Attitude is a little thing that makes a big difference.",
|
||||||
"People are beginning to notice you. Try dressing before you leave the house.",
|
"Plan for many pleasures ahead.",
|
||||||
"Perfect day for scrubbing the floor and other exciting things.",
|
"Experience is the best teacher.",
|
||||||
"Questionable day.\n\nAsk somebody something.",
|
"You will be happy with your spouse.",
|
||||||
"Reply hazy, ask again later.",
|
"Expect the unexpected.",
|
||||||
"Save energy: be apathetic.",
|
"Stay healthy. Walk a mile.",
|
||||||
"Ships are safe in harbor, but they were never meant to stay there.",
|
"The family that plays together stays together.",
|
||||||
"Slow day. Practice crawling.",
|
"Eat chocolate to have a sweeter life.",
|
||||||
"Snow Day -- stay home.",
|
"Once you make a decision the universe conspires to make it happen.",
|
||||||
"So this is it. We're going to die.",
|
"Make yourself necessary to someone.",
|
||||||
"So you're back... about time...",
|
"The only way to have a friend is to be one.",
|
||||||
"Someone is speaking well of you.",
|
"Nothing great was ever achieved without enthusiasm.",
|
||||||
"Someone is speaking well of you.\n\nHow unusual!",
|
"Dance as if no one is watching.",
|
||||||
"Someone whom you reject today, will reject you tomorrow.",
|
"Live this day as if it were your last.",
|
||||||
"Stay away from flying saucers today.",
|
"Your life will be happy and peaceful.",
|
||||||
"Stay away from hurricanes for a while.",
|
"Reach for joy and all else will follow.",
|
||||||
"Stay the curse.",
|
"Move in the direction of your dreams.",
|
||||||
"That secret you've been guarding, isn't.",
|
"Bloom where you are planted.",
|
||||||
"The time is right to make new friends.",
|
"Appreciate. Appreciate. Appreciate.",
|
||||||
"The whole world is a tuxedo and you are a pair of brown shoes.\n\n -- George Gobel",
|
"Happy News is on its way.",
|
||||||
"There is a 20% chance of tomorrow.",
|
"A closed mouth gathers no feet.",
|
||||||
"There is a fly on your nose.",
|
"He who throws dirt is losing ground.",
|
||||||
"There was a phone call for you.",
|
"Borrow money from a pessimist. They don't expect it back.",
|
||||||
"You're not my type. For that matter, you're not even my species!!!",
|
"Life is what happens to you while you are busy making other plans.",
|
||||||
"You're ugly and your mother dresses you funny.",
|
"Help! I'm being held prisoner in a fortune cookie factory.",
|
||||||
"You're working under a slight handicap. You happen to be human.",
|
|
||||||
"You've been leading a dog's life. Stay off the furniture.",
|
|
||||||
"Your aim is high and to the right.",
|
|
||||||
"Your aims are high, and you are capable of much.",
|
|
||||||
"Your analyst has you mixed up with another patient. Don't believe a thing he tells you.",
|
|
||||||
"Your best consolation is the hope that the things you failed to get weren't really worth having.",
|
|
||||||
"Your boss climbed the corporate ladder, wrong by wrong.",
|
|
||||||
"Your boss is a few sandwiches short of a picnic.",
|
|
||||||
"Your boyfriend takes chocolate from strangers.",
|
|
||||||
"Your business will assume vast proportions.",
|
|
||||||
"Your business will go through a period of considerable expansion.",
|
|
||||||
"Your depth of comprehension may tend to make you lax in worldly ways.",
|
|
||||||
"Your domestic life may be harmonious.",
|
|
||||||
"Your fly might be open (but don't check it just now).",
|
|
||||||
"Your goose is cooked. (Your current chick is burned up too!)",
|
|
||||||
"Your heart is pure, and your mind clear, and your soul devout.",
|
|
||||||
"Your ignorance cramps my conversation.",
|
|
||||||
"Your life would be very empty if you had nothing to regret.",
|
|
||||||
"Your love life will be happy and harmonious.",
|
|
||||||
"Your love life will be... interesting.",
|
|
||||||
"Your lover will never wish to leave you.",
|
|
||||||
"Your lucky color has faded.",
|
|
||||||
"Your lucky number has been disconnected.",
|
|
||||||
"Your lucky number is 3552664958674928. Watch for it everywhere.",
|
|
||||||
"Your mode of life will be changed for the better because of good news soon.",
|
|
||||||
"Your mode of life will be changed for the better because of new developments.",
|
|
||||||
"Your motives for doing whatever good deed you may have in mind will be misinterpreted by somebody.",
|
|
||||||
"Your nature demands love and your happiness depends on it.",
|
|
||||||
"Your object is to save the world, while still leading a pleasant life.",
|
|
||||||
"Your own qualities will help prevent your advancement in the world.",
|
|
||||||
"Your present plans will be successful.",
|
|
||||||
"Your reasoning is excellent -- it's only your basic assumptions that are wrong.",
|
|
||||||
"Your reasoning powers are good, and you are a fairly good planner.",
|
|
||||||
"Your sister swims out to meet troop ships.",
|
|
||||||
"Your society will be sought by people of taste and refinement.",
|
|
||||||
"Your step will soil many countries.",
|
|
||||||
"Your supervisor is thinking about you.",
|
|
||||||
"Your talents will be recognized and suitably rewarded.",
|
|
||||||
"Your temporary financial embarrassment will be relieved in a surprising manner.",
|
|
||||||
"Your true value depends entirely on what you are compared with.",
|
|
||||||
];
|
];
|
||||||
|
|
||||||
export const fortune = new Command("fortune")
|
export const fortune = new Command()
|
||||||
.setManual({
|
.setManual({
|
||||||
purpose: "Tell fortune"
|
purpose: "Tell fortune"
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import Command from "../command.js";
|
import Command from "../command.js";
|
||||||
import CommandsManager from "../commands.js";
|
import CommandsManager from "../commands.js";
|
||||||
|
|
||||||
export const help = new Command("help")
|
export const help = new Command()
|
||||||
.setExecute((args) => {
|
.setExecute((args) => {
|
||||||
if (args.length === 0) {
|
if (args.length === 0) {
|
||||||
return CommandsManager.COMMANDS.map((command) => {
|
return CommandsManager.COMMANDS.map((command) => {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import Command from "../command.js";
|
import Command from "../command.js";
|
||||||
|
|
||||||
export const hostname = new Command("hostname")
|
export const hostname = new Command()
|
||||||
.setManual({
|
.setManual({
|
||||||
purpose: "Display the hostname"
|
purpose: "Display the hostname"
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import { ANSI } from "../../../../config/apps/terminal.config.js";
|
import { ANSI } from "../../../../config/apps/terminal.config.js";
|
||||||
import Command from "../command.js";
|
import Command from "../command.js";
|
||||||
|
|
||||||
export const ls = new Command("ls")
|
export const ls = new Command()
|
||||||
.setManual({
|
.setManual({
|
||||||
purpose: "List directory contents",
|
purpose: "List directory contents",
|
||||||
usage: "ls [OPTION]... [FILE]...",
|
usage: "ls [OPTION]... [FILE]...",
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import Command from "../command.js";
|
import Command from "../command.js";
|
||||||
|
|
||||||
export const make = new Command("make")
|
export const make = new Command()
|
||||||
.setRequireArgs(true)
|
.setRequireArgs(true)
|
||||||
.setExecute(function(args) {
|
.setExecute(function(args) {
|
||||||
if (args[0] === "love")
|
if (args[0] === "love")
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ import CommandsManager from "../commands.js";
|
||||||
|
|
||||||
const MARGIN = 5;
|
const MARGIN = 5;
|
||||||
|
|
||||||
export const man = new Command("man")
|
export const man = new Command()
|
||||||
.setRequireArgs(true)
|
.setRequireArgs(true)
|
||||||
.setManual({
|
.setManual({
|
||||||
purpose: "Show system reference manuals",
|
purpose: "Show system reference manuals",
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import Command from "../command.js";
|
import Command from "../command.js";
|
||||||
|
|
||||||
export const mkdir = new Command("mkdir")
|
export const mkdir = new Command()
|
||||||
.setManual({
|
.setManual({
|
||||||
purpose: "Create directory"
|
purpose: "Create directory"
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ import { formatRelativeTime } from "../../../_utils/date.utils.js";
|
||||||
import AppsManager from "../../appsManager.js";
|
import AppsManager from "../../appsManager.js";
|
||||||
import Command from "../command.js";
|
import Command from "../command.js";
|
||||||
|
|
||||||
export const neofetch = new Command("neofetch")
|
export const neofetch = new Command()
|
||||||
.setManual({
|
.setManual({
|
||||||
purpose: "Fetch system information"
|
purpose: "Fetch system information"
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import Command from "../command.js";
|
import Command from "../command.js";
|
||||||
|
|
||||||
export const pwd = new Command("pwd")
|
export const pwd = new Command()
|
||||||
.setManual({
|
.setManual({
|
||||||
purpose: "Display path of the current directory"
|
purpose: "Display path of the current directory"
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import { reloadViewport } from "../../../_utils/browser.utils.js";
|
import { reloadViewport } from "../../../_utils/browser.utils.js";
|
||||||
import Command from "../command.js";
|
import Command from "../command.js";
|
||||||
|
|
||||||
export const reboot = new Command("reboot")
|
export const reboot = new Command()
|
||||||
.setManual({
|
.setManual({
|
||||||
purpose: "Reboot the system"
|
purpose: "Reboot the system"
|
||||||
})
|
})
|
||||||
|
|
|
||||||
9
src/features/apps/terminal/commands/rev.js
Normal file
9
src/features/apps/terminal/commands/rev.js
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
import Command from "../command.js";
|
||||||
|
|
||||||
|
export const rev = new Command()
|
||||||
|
.setManual({
|
||||||
|
purpose: "Reverses text."
|
||||||
|
})
|
||||||
|
.setExecute((args, { rawInputValue }) => {
|
||||||
|
return rawInputValue.split("").reverse().join("");
|
||||||
|
});
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import { VirtualFile } from "../../../virtual-drive/file/virtualFile.js";
|
import { VirtualFile } from "../../../virtual-drive/file/virtualFile.js";
|
||||||
import Command from "../command.js";
|
import Command from "../command.js";
|
||||||
|
|
||||||
export const rm = new Command("rm")
|
export const rm = new Command()
|
||||||
.setRequireArgs(true)
|
.setRequireArgs(true)
|
||||||
.setManual({
|
.setManual({
|
||||||
purpose: "Remove a file"
|
purpose: "Remove a file"
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import Command from "../command.js";
|
import Command from "../command.js";
|
||||||
|
|
||||||
export const rmdir = new Command("rmdir")
|
export const rmdir = new Command()
|
||||||
.setRequireArgs(true)
|
.setRequireArgs(true)
|
||||||
.setManual({
|
.setManual({
|
||||||
purpose: "Remove a directory"
|
purpose: "Remove a directory"
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ const LOCOMOTIVE_SMOKE = [
|
||||||
" (@@@)",
|
" (@@@)",
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
" ( ) (@@) ( ) (@) () @@ o @ o",
|
" ( ) (@@) ( ) (@) () @@ o @ o @",
|
||||||
" (@@@)",
|
" (@@@)",
|
||||||
" ( )",
|
" ( )",
|
||||||
" (@@@@)",
|
" (@@@@)",
|
||||||
|
|
@ -21,55 +21,76 @@ const LOCOMOTIVE_SMOKE = [
|
||||||
];
|
];
|
||||||
|
|
||||||
const LOCOMOTIVE_TOP = [
|
const LOCOMOTIVE_TOP = [
|
||||||
" ==== ________ ___________ ",
|
" ==== ________ ___________",
|
||||||
" _D _| |_______/ \\__I_I_____===__|_________| ",
|
" _D _| |_______/ \\__I_I_____===__|_________|",
|
||||||
" |(_)--- | H\\________/ | | =|___ ___| ",
|
" |(_)--- | H\\________/ | | =|___ ___| ",
|
||||||
" / | | H | | | | ||_| |_|| ",
|
" / | | H | | | | ||_| |_|| ",
|
||||||
" | | | H |__--------------------| [___] | ",
|
" | | | H |__--------------------| [___] | ",
|
||||||
" | ________|___H__/__|_____/[][]~\\_______| | ",
|
" | ________|___H__/__|_____/[][]~\\_______| | ",
|
||||||
" |/ | |-----------I_____I [][] [] D |=======|__ ",
|
" |/ | |-----------I_____I [][] [] D |=======|__",
|
||||||
];
|
];
|
||||||
|
|
||||||
const LOCOMOTIVE_BOTTOM = [
|
const LOCOMOTIVE_BOTTOM = [
|
||||||
[
|
[
|
||||||
"__/ =| o |=-~~\\ /~~\\ /~~\\ /~~\\ ____Y___________|__ ",
|
"__/ =| o |=-~~\\ /~~\\ /~~\\ /~~\\ ____Y___________|__",
|
||||||
" |/-=|___|= || || || |_____/~\\___/ ",
|
" |/-=|___|= || || || |_____/~\\___/ ",
|
||||||
" \\_/ \\O=====O=====O=====O_/ \\_/ ",
|
" \\_/ \\O=====O=====O=====O_/ \\_/ ",
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
"__/ =| o |=-~~\\ /~~\\ /~~\\ /~~\\ ____Y___________|__ ",
|
"__/ =| o |=-~~\\ /~~\\ /~~\\ /~~\\ ____Y___________|__",
|
||||||
" |/-=|___|=O=====O=====O=====O |_____/~\\___/ ",
|
" |/-=|___|=O=====O=====O=====O |_____/~\\___/ ",
|
||||||
" \\_/ \\__/ \\__/ \\__/ \\__/ \\_/ ",
|
" \\_/ \\__/ \\__/ \\__/ \\__/ \\_/ ",
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
"__/ =| o |=-O=====O=====O=====O \\ ____Y___________|__ ",
|
"__/ =| o |=-O=====O=====O=====O \\ ____Y___________|__",
|
||||||
" |/-=|___|= || || || |_____/~\\___/ ",
|
" |/-=|___|= || || || |_____/~\\___/ ",
|
||||||
" \\_/ \\__/ \\__/ \\__/ \\__/ \\_/ ",
|
" \\_/ \\__/ \\__/ \\__/ \\__/ \\_/ ",
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
"__/ =| o |=-~O=====O=====O=====O\\ ____Y___________|__ ",
|
"__/ =| o |=-~O=====O=====O=====O\\ ____Y___________|__",
|
||||||
" |/-=|___|= || || || |_____/~\\___/ ",
|
" |/-=|___|= || || || |_____/~\\___/ ",
|
||||||
" \\_/ \\__/ \\__/ \\__/ \\__/ \\_/ ",
|
" \\_/ \\__/ \\__/ \\__/ \\__/ \\_/ ",
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
"__/ =| o |=-~~\\ /~~\\ /~~\\ /~~\\ ____Y___________|__ ",
|
"__/ =| o |=-~~\\ /~~\\ /~~\\ /~~\\ ____Y___________|__",
|
||||||
" |/-=|___|= O=====O=====O=====O|_____/~\\___/ ",
|
" |/-=|___|= O=====O=====O=====O|_____/~\\___/ ",
|
||||||
" \\_/ \\__/ \\__/ \\__/ \\__/ \\_/ ",
|
" \\_/ \\__/ \\__/ \\__/ \\__/ \\_/ ",
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
"__/ =| o |=-~~\\ /~~\\ /~~\\ /~~\\ ____Y___________|__ ",
|
"__/ =| o |=-~~\\ /~~\\ /~~\\ /~~\\ ____Y___________|__",
|
||||||
" |/-=|___|= || || || |_____/~\\___/ ",
|
" |/-=|___|= || || || |_____/~\\___/ ",
|
||||||
" \\_/ \\_O=====O=====O=====O/ \\_/ ",
|
" \\_/ \\_O=====O=====O=====O/ \\_/ ",
|
||||||
]
|
]
|
||||||
].reverse();
|
].reverse();
|
||||||
|
|
||||||
function getLocomotive(frame) {
|
const WAGON = [
|
||||||
|
" _________________ ",
|
||||||
|
" _| \\_____A ",
|
||||||
|
" =| | ",
|
||||||
|
" -| | ",
|
||||||
|
"__|________________________|_",
|
||||||
|
"|__________________________|_",
|
||||||
|
" |_D__D__D_| |_D__D__D_| ",
|
||||||
|
" \\_/ \\_/ \\_/ \\_/ ",
|
||||||
|
];
|
||||||
|
|
||||||
|
function getLocomotive(frame, wagonCount = 1) {
|
||||||
|
const smokeHeight = LOCOMOTIVE_SMOKE[0].length;
|
||||||
|
const locomotiveHeight = LOCOMOTIVE_TOP.length + LOCOMOTIVE_BOTTOM[0].length;
|
||||||
|
const wagonHeight = WAGON.length;
|
||||||
|
|
||||||
|
const wagonStart = smokeHeight + locomotiveHeight - wagonHeight;
|
||||||
|
|
||||||
const smoke = LOCOMOTIVE_SMOKE[Math.round(frame / 6) % LOCOMOTIVE_SMOKE.length];
|
const smoke = LOCOMOTIVE_SMOKE[Math.round(frame / 6) % LOCOMOTIVE_SMOKE.length];
|
||||||
const top = LOCOMOTIVE_TOP;
|
const top = LOCOMOTIVE_TOP;
|
||||||
const bottom = LOCOMOTIVE_BOTTOM[frame % LOCOMOTIVE_BOTTOM.length];
|
const bottom = LOCOMOTIVE_BOTTOM[frame % LOCOMOTIVE_BOTTOM.length];
|
||||||
|
|
||||||
const distance = 50 - frame;
|
const distance = 50 - frame;
|
||||||
const locomotive = smoke.concat(top, bottom).map((line) => {
|
const locomotive = smoke.concat(top, bottom).map((line, index) => {
|
||||||
|
if (index >= wagonStart && wagonCount > 0) {
|
||||||
|
line += WAGON[index - wagonStart].repeat(wagonCount);
|
||||||
|
}
|
||||||
|
|
||||||
if (distance === 0) {
|
if (distance === 0) {
|
||||||
return line;
|
return line;
|
||||||
} else if (distance > 0) {
|
} else if (distance > 0) {
|
||||||
|
|
@ -83,13 +104,31 @@ function getLocomotive(frame) {
|
||||||
return `\n${locomotive}\n`;
|
return `\n${locomotive}\n`;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const sl = new Command("sl")
|
export const sl = new Command()
|
||||||
.setExecute(function() {
|
.setManual({
|
||||||
|
purpose: "Displays animations aimed to correct users who accidentally enter sl instead of ls. SL stands for Steam Locomotive."
|
||||||
|
})
|
||||||
|
.addOption({
|
||||||
|
short: "w",
|
||||||
|
long: "wagons",
|
||||||
|
isInput: true
|
||||||
|
})
|
||||||
|
.setExecute((args, { inputs }) => {
|
||||||
|
let wagonCount = 1;
|
||||||
|
|
||||||
|
if (inputs?.w) {
|
||||||
|
wagonCount = parseInt(inputs.w);
|
||||||
|
|
||||||
|
if (!wagonCount || wagonCount < 0) {
|
||||||
|
return `${this.name}: Please specify a valid amount of wagons`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const stream = new Stream();
|
const stream = new Stream();
|
||||||
|
|
||||||
let frame = 0;
|
let frame = 0;
|
||||||
const interval = setInterval(() => {
|
const interval = setInterval(() => {
|
||||||
const text = getLocomotive(frame);
|
const text = getLocomotive(frame, wagonCount);
|
||||||
stream.send(text);
|
stream.send(text);
|
||||||
frame++;
|
frame++;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import { VirtualFile } from "../../../virtual-drive/file/virtualFile.js";
|
import { VirtualFile } from "../../../virtual-drive/file/virtualFile.js";
|
||||||
import Command from "../command.js";
|
import Command from "../command.js";
|
||||||
|
|
||||||
export const touch = new Command("touch")
|
export const touch = new Command()
|
||||||
.setRequireArgs(true)
|
.setRequireArgs(true)
|
||||||
.setManual({
|
.setManual({
|
||||||
purpose: "Change file timestamps",
|
purpose: "Change file timestamps",
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ import { formatRelativeTime } from "../../../_utils/date.utils.js";
|
||||||
import Command from "../command.js";
|
import Command from "../command.js";
|
||||||
|
|
||||||
|
|
||||||
export const uptime = new Command("uptime")
|
export const uptime = new Command()
|
||||||
.setManual({
|
.setManual({
|
||||||
purpose: "Displays the current uptime of the system"
|
purpose: "Displays the current uptime of the system"
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import Command from "../command.js";
|
import Command from "../command.js";
|
||||||
import CommandsManager from "../commands.js";
|
import CommandsManager from "../commands.js";
|
||||||
|
|
||||||
export const whatis = new Command("whatis")
|
export const whatis = new Command()
|
||||||
.setRequireArgs(true)
|
.setRequireArgs(true)
|
||||||
.setManual({
|
.setManual({
|
||||||
purpose: "Show information about a command"
|
purpose: "Show information about a command"
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import Command from "../command.js";
|
import Command from "../command.js";
|
||||||
|
|
||||||
export const whoami = new Command("whoami")
|
export const whoami = new Command()
|
||||||
.setManual({
|
.setManual({
|
||||||
purpose: "Display the username"
|
purpose: "Display the username"
|
||||||
})
|
})
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue