forked from tools/josh
Add .editorconfig and format accordingly
This commit is contained in:
parent
67898842ba
commit
f574d84e0b
|
@ -0,0 +1,11 @@
|
||||||
|
root = true
|
||||||
|
|
||||||
|
[*]
|
||||||
|
charset = utf-8
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
|
||||||
|
end_of_line = lf
|
||||||
|
insert_final_newline = true
|
||||||
|
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 4
|
|
@ -45,7 +45,7 @@ export class Commands {
|
||||||
"cat": new Command(
|
"cat": new Command(
|
||||||
this.cat,
|
this.cat,
|
||||||
`concatenate and print files`,
|
`concatenate and print files`,
|
||||||
`cat FILE ...`,
|
`cat FILE...`,
|
||||||
`Reads files sequentially, writing them to the standard output.`,
|
`Reads files sequentially, writing them to the standard output.`,
|
||||||
new InputValidator({minArgs: 1})
|
new InputValidator({minArgs: 1})
|
||||||
),
|
),
|
||||||
|
@ -53,30 +53,32 @@ export class Commands {
|
||||||
this.clear,
|
this.clear,
|
||||||
`clear terminal output`,
|
`clear terminal output`,
|
||||||
`clear`,
|
`clear`,
|
||||||
`Clears all previous terminal output.`.trimLines(),
|
`Clears all previous terminal output.`,
|
||||||
new InputValidator({maxArgs: 0})
|
new InputValidator({maxArgs: 0})
|
||||||
),
|
),
|
||||||
"cd": new Command(
|
"cd": new Command(
|
||||||
this.cd,
|
this.cd,
|
||||||
`change directory`,
|
`change directory`,
|
||||||
`cd [DIRECTORY]`,
|
`cd [DIRECTORY]`,
|
||||||
`Changes the current working directory to [DIRECTORY].
|
`Changes the current working directory to [DIRECTORY]. If [DIRECTORY] is empty, the current working \\\
|
||||||
If [DIRECTORY] is empty, the current working directory is changed to the root.`.trimLines(),
|
directory is changed to the root.`.trimMultiLines(),
|
||||||
new InputValidator({maxArgs: 1})
|
new InputValidator({maxArgs: 1})
|
||||||
),
|
),
|
||||||
"cp": new Command(
|
"cp": new Command(
|
||||||
this.cp,
|
this.cp,
|
||||||
`copy files`,
|
`copy files`,
|
||||||
`cp [-R] SOURCE DESTINATION
|
`cp [-r | -R | --recursive] SOURCE DESTINATION
|
||||||
cp [-R] SOURCES... DESTINATION`,
|
cp [-r | -R | --recursive] SOURCES... DESTINATION`,
|
||||||
`In its first form, the file or directory at SOURCE is copied to DESTINATION.
|
`In its first form, the file or directory at SOURCE is copied to DESTINATION. If DESTINATION is an \\\
|
||||||
If DESTINATION is an existing directory, SOURCE is copied into that directory, retaining the file name from SOURCE.
|
existing directory, SOURCE is copied into that directory, retaining the file name from SOURCE. If \\\
|
||||||
If DESTINATION does not exist, SOURCE is copied to the exact location of DESTINATION.
|
DESTINATION does not exist, SOURCE is copied to the exact location of DESTINATION.
|
||||||
|
|
||||||
In its second form, all files and directories at SOURCES are copied to DESTINATION.
|
In its second form, all files and directories at SOURCES are copied to DESTINATION. DESTINATION must \\\
|
||||||
DESTINATION must be a pre-existing directory, and all SOURCES are copied into DESTINATION retaining the file names from SOURCES.
|
be a pre-existing directory, and all SOURCES are copied into DESTINATION retaining the file names \\\
|
||||||
|
from SOURCES.
|
||||||
|
|
||||||
In both forms, sources are not copied if they are directories unless the -R options is given.`.trimLines(),
|
In both forms, sources are not copied if they are directories unless the -R options is given.\\\
|
||||||
|
`.trimMultiLines(),
|
||||||
new InputValidator({minArgs: 2})
|
new InputValidator({minArgs: 2})
|
||||||
),
|
),
|
||||||
"echo": new Command(
|
"echo": new Command(
|
||||||
|
@ -84,14 +86,15 @@ export class Commands {
|
||||||
`display text`,
|
`display text`,
|
||||||
`echo [-n] [TEXT]`,
|
`echo [-n] [TEXT]`,
|
||||||
`Displays [TEXT].
|
`Displays [TEXT].
|
||||||
Unless the -n parameter is given, a newline is appended to the end.`.trimLines(),
|
|
||||||
|
Unless the -n parameter is given, a newline is appended to the end.`.trimMultiLines(),
|
||||||
new InputValidator()
|
new InputValidator()
|
||||||
),
|
),
|
||||||
"exit": new Command(
|
"exit": new Command(
|
||||||
this.exit,
|
this.exit,
|
||||||
`close session`,
|
`close session`,
|
||||||
`exit`,
|
`exit`,
|
||||||
`Closes the terminal session.`.trimLines(),
|
`Closes the terminal session.`,
|
||||||
new InputValidator({maxArgs: 0})
|
new InputValidator({maxArgs: 0})
|
||||||
),
|
),
|
||||||
"help": new Command(
|
"help": new Command(
|
||||||
|
@ -99,34 +102,37 @@ export class Commands {
|
||||||
`display documentation`,
|
`display documentation`,
|
||||||
`help [COMMAND...]`,
|
`help [COMMAND...]`,
|
||||||
`Displays help documentation for each command in [COMMAND...].
|
`Displays help documentation for each command in [COMMAND...].
|
||||||
If no commands are given, a list of all commands is shown.`.trimLines(),
|
|
||||||
|
If no commands are given, a list of all commands is shown.`.trimMultiLines(),
|
||||||
new InputValidator()
|
new InputValidator()
|
||||||
),
|
),
|
||||||
"ls": new Command(
|
"ls": new Command(
|
||||||
this.ls,
|
this.ls,
|
||||||
`list directory contents`,
|
`list directory contents`,
|
||||||
`ls [-a] [DIRECTORY...]`,
|
`ls [-a | -A] [DIRECTORY...]`,
|
||||||
`Displays the files and directories in [DIRECTORY...].
|
`Displays the files and directories in [DIRECTORY...]. If no directory is given, the files and \\\
|
||||||
If no directory is given, the files and directories in the current working directory are shown.
|
directories in the current working directory are shown. If more than one directory is given, the \\\
|
||||||
If more than one directory is given, the files and directories are shown for each given directory in order.
|
files and directories are shown for each given directory in order.
|
||||||
Files starting with a . are only shown if the -a option is given, with the exception of . and .., which are always shown.`.trimLines(),
|
|
||||||
|
Files starting with a . are only shown if the -a option is given, with the exception of . and .., \\\
|
||||||
|
which are always shown.`.trimMultiLines(),
|
||||||
new InputValidator()
|
new InputValidator()
|
||||||
),
|
),
|
||||||
"man": new Command(
|
"man": new Command(
|
||||||
this.man,
|
this.man,
|
||||||
`display manual documentation pages`,
|
`display manual documentation pages`,
|
||||||
`man PAGE...`,
|
`man PAGE...`,
|
||||||
`Displays the manual pages with names PAGE....`.trimLines(),
|
`Displays the manual pages with names PAGE....`,
|
||||||
new InputValidator()
|
new InputValidator()
|
||||||
),
|
),
|
||||||
"mkdir": new Command(
|
"mkdir": new Command(
|
||||||
this.mkdir,
|
this.mkdir,
|
||||||
`make directories`,
|
`make directories`,
|
||||||
`mkdir [-p] DIRECTORY ...`,
|
`mkdir [-p] DIRECTORY...`,
|
||||||
`Creates the directories given by DIRECTORY.
|
`Creates the directories given by DIRECTORY.
|
||||||
|
|
||||||
If more than one directory is given, the directories are created in the order they are given in.
|
If more than one directory is given, the directories are created in the order they are given in. If \\\
|
||||||
If the -p option is given, parent directories that do not exist are created as well.`.trimLines(),
|
the -p option is given, parent directories that do not exist are created as well.`.trimMultiLines(),
|
||||||
new InputValidator({minArgs: 1})
|
new InputValidator({minArgs: 1})
|
||||||
),
|
),
|
||||||
"mv": new Command(
|
"mv": new Command(
|
||||||
|
@ -134,12 +140,13 @@ export class Commands {
|
||||||
`move files`,
|
`move files`,
|
||||||
`mv SOURCE DESTINATION
|
`mv SOURCE DESTINATION
|
||||||
mv SOURCES... DESTINATION`,
|
mv SOURCES... DESTINATION`,
|
||||||
`In its first form, the file or directory at SOURCE is moved to DESTINATION.
|
`In its first form, the file or directory at SOURCE is moved to DESTINATION. If DESTINATION is an \\\
|
||||||
If DESTINATION is an existing directory, SOURCE is moved into that directory, retaining the file name from SOURCE.
|
existing directory, SOURCE is moved into that directory, retaining the file name from SOURCE. If \\\
|
||||||
If DESTINATION does not exist, SOURCE is moved to the exact location of DESTINATION.
|
DESTINATION does not exist, SOURCE is moved to the exact location of DESTINATION.
|
||||||
|
|
||||||
In its second form, all files and directories at SOURCES are moved to DESTINATION.
|
In its second form, all files and directories at SOURCES are moved to DESTINATION. DESTINATION must \\\
|
||||||
DESTINATION must be a pre-existing directory, and all SOURCES are moved into DESTINATION retaining the file names from SOURCES.`.trimLines(),
|
be a pre-existing directory, and all SOURCES are moved into DESTINATION retaining the file names \\\
|
||||||
|
from SOURCES.`.trimMultiLines(),
|
||||||
new InputValidator({minArgs: 2})
|
new InputValidator({minArgs: 2})
|
||||||
),
|
),
|
||||||
"open": new Command(
|
"open": new Command(
|
||||||
|
@ -148,62 +155,59 @@ export class Commands {
|
||||||
`open [-b | --blank] FILE`,
|
`open [-b | --blank] FILE`,
|
||||||
`Opens the web page linked to by FILE in this browser window.
|
`Opens the web page linked to by FILE in this browser window.
|
||||||
|
|
||||||
If -b or --blank is set, the web page is opened in a new tab.`.trimLines(),
|
If -b or --blank is set, the web page is opened in a new tab.`.trimMultiLines(),
|
||||||
new InputValidator({minArgs: 1, maxArgs: 1})
|
new InputValidator({minArgs: 1, maxArgs: 1})
|
||||||
),
|
),
|
||||||
"poweroff": new Command(
|
"poweroff": new Command(
|
||||||
this.poweroff,
|
this.poweroff,
|
||||||
`close down the system`,
|
`close down the system`,
|
||||||
`poweroff`,
|
`poweroff`,
|
||||||
`Automated shutdown procedure to nicely notify users when the system is shutting down.`.trimLines(),
|
`Automated shutdown procedure to nicely notify users when the system is shutting down.`,
|
||||||
new InputValidator({maxArgs: 0})
|
new InputValidator({maxArgs: 0})
|
||||||
),
|
),
|
||||||
"pwd": new Command(
|
"pwd": new Command(
|
||||||
this.pwd,
|
this.pwd,
|
||||||
`print working directory`,
|
`print working directory`,
|
||||||
`pwd`,
|
`pwd`,
|
||||||
`Displays the current working directory.`.trimLines(),
|
`Displays the current working directory.`,
|
||||||
new InputValidator({maxArgs: 0})
|
new InputValidator({maxArgs: 0})
|
||||||
),
|
),
|
||||||
"rm": new Command(
|
"rm": new Command(
|
||||||
this.rm,
|
this.rm,
|
||||||
`remove file`,
|
`remove file`,
|
||||||
`rm [-f | --force] [-r | -R | --recursive] [--no-preserve-root] FILE...`,
|
`rm [-f | --force] [-r | -R | --recursive] [--no-preserve-root] FILE...`,
|
||||||
`Removes the files given by FILE.
|
`Removes the files given by FILE. If more than one file is given, the files are removed in the order \\\
|
||||||
|
they are given in.
|
||||||
If more than one file is given, the files are removed in the order they are given in.
|
|
||||||
|
|
||||||
If -f or --force is set, no warning is given if a file could not be removed.
|
If -f or --force is set, no warning is given if a file could not be removed.
|
||||||
|
|
||||||
If -r, -R, or --recursive is set, files and directories are removed recursively.
|
If -r, -R, or --recursive is set, files and directories are removed recursively.
|
||||||
|
|
||||||
Unless --no-preserve-root is set, the root directory cannot be removed.`.trimLines(),
|
Unless --no-preserve-root is set, the root directory cannot be removed.`.trimMultiLines(),
|
||||||
new InputValidator({minArgs: 1})
|
new InputValidator({minArgs: 1})
|
||||||
),
|
),
|
||||||
"rmdir": new Command(
|
"rmdir": new Command(
|
||||||
this.rmdir,
|
this.rmdir,
|
||||||
`remove directories`,
|
`remove directories`,
|
||||||
`rmdir DIRECTORY...`,
|
`rmdir DIRECTORY...`,
|
||||||
`Removes the directories given by DIRECTORY.
|
`Removes the directories given by DIRECTORY. If more than one directory is given, the directories \\\
|
||||||
|
are removed in the order they are given in.`.trimMultiLines(),
|
||||||
If more than one directory is given, the directories are removed in the order they are given in.`.trimLines(),
|
|
||||||
new InputValidator({minArgs: 1})
|
new InputValidator({minArgs: 1})
|
||||||
),
|
),
|
||||||
"set": new Command(
|
"set": new Command(
|
||||||
this.set,
|
this.set,
|
||||||
`set environment variable`,
|
`set environment variable`,
|
||||||
`set key [value]`,
|
`set KEY [VALUE]`,
|
||||||
`Sets the environment variable with the given key to the given value.
|
`Sets the environment variable KEY to VALUE. If no value is given, the environment variable is \\\
|
||||||
If no value is given, the environment variable is cleared.`.trimLines(),
|
cleared. Read-only variables cannot be set.`.trimMultiLines(),
|
||||||
new InputValidator({minArgs: 1, maxArgs: 2})
|
new InputValidator({minArgs: 1, maxArgs: 2})
|
||||||
),
|
),
|
||||||
"touch": new Command(
|
"touch": new Command(
|
||||||
this.touch,
|
this.touch,
|
||||||
`change file timestamps`,
|
`change file timestamps`,
|
||||||
`touch FILE...`,
|
`touch FILE...`,
|
||||||
`Update the access and modification times of each FILE to the current time.
|
`Update the access and modification times of each FILE to the current time. If a file does not \\\
|
||||||
|
exist, it is created.`.trimMultiLines(),
|
||||||
If a file does not exist, it is created.`.trimLines(),
|
|
||||||
new InputValidator({minArgs: 1})
|
new InputValidator({minArgs: 1})
|
||||||
),
|
),
|
||||||
"whoami": new Command(
|
"whoami": new Command(
|
||||||
|
@ -297,7 +301,7 @@ export class Commands {
|
||||||
return this.moveCopyMappings(input)
|
return this.moveCopyMappings(input)
|
||||||
.map(([source, destination]) => {
|
.map(([source, destination]) => {
|
||||||
try {
|
try {
|
||||||
this.fileSystem.copy(source, destination, input.hasAnyOption(["r", "R"]));
|
this.fileSystem.copy(source, destination, input.hasAnyOption(["r", "R", "recursive"]));
|
||||||
return "";
|
return "";
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return error.message;
|
return error.message;
|
||||||
|
@ -358,12 +362,14 @@ export class Commands {
|
||||||
const commandEntries = commandNames
|
const commandEntries = commandNames
|
||||||
.map((it, i) => `${commandLinks[i]}${this.commands[it].summary}`);
|
.map((it, i) => `${commandLinks[i]}${this.commands[it].summary}`);
|
||||||
|
|
||||||
return `The source code of this website is <a href="https://git.fwdekker.com/FWDekker/fwdekker.com">available on git</a>.
|
return `The source code of this website is \\\
|
||||||
|
<a href="https://git.fwdekker.com/FWDekker/fwdekker.com">available on git</a>.
|
||||||
|
|
||||||
<b>List of commands</b>
|
<b>List of commands</b>
|
||||||
${commandEntries.join("\n")}
|
${commandEntries.join("\n")}
|
||||||
|
|
||||||
Write "help [COMMAND]" or click a command in the list above for more information on a command.`.trimLines();
|
Write "help [COMMAND]" or click a command in the list above for more information on a command.\\\
|
||||||
|
`.trimMultiLines();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -54,7 +54,8 @@ export class Environment {
|
||||||
*/
|
*/
|
||||||
delete(key: string): void {
|
delete(key: string): void {
|
||||||
if (!Environment.isKeyValid(key))
|
if (!Environment.isKeyValid(key))
|
||||||
throw new IllegalArgumentError("Environment variable keys can only contain alphanumerical characters and underscores.");
|
throw new IllegalArgumentError(
|
||||||
|
"Environment variable keys can only contain alphanumerical characters and underscores.");
|
||||||
|
|
||||||
delete this._variables[key];
|
delete this._variables[key];
|
||||||
}
|
}
|
||||||
|
@ -125,7 +126,8 @@ export class Environment {
|
||||||
*/
|
*/
|
||||||
set(key: string, value: string): void {
|
set(key: string, value: string): void {
|
||||||
if (!Environment.isKeyValid(key))
|
if (!Environment.isKeyValid(key))
|
||||||
throw new IllegalArgumentError("Environment variable keys can only contain alphanumerical characters and underscores.");
|
throw new IllegalArgumentError(
|
||||||
|
"Environment variable keys can only contain alphanumerical characters and underscores.");
|
||||||
|
|
||||||
this._variables[key] = value;
|
this._variables[key] = value;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
interface String {
|
interface String {
|
||||||
trimLines(): string;
|
trimLines(): string;
|
||||||
|
|
||||||
|
trimMultiLines(): string;
|
||||||
|
|
||||||
replaceAll(regex: RegExp, replacement: string): string;
|
replaceAll(regex: RegExp, replacement: string): string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,7 +10,18 @@ interface String {
|
||||||
* Returns this string with all leading and trailing whitespace removed from each line.
|
* Returns this string with all leading and trailing whitespace removed from each line.
|
||||||
*/
|
*/
|
||||||
String.prototype.trimLines = function(): string {
|
String.prototype.trimLines = function(): string {
|
||||||
return this.split("\n").map(it => it.trim()).join("\n");
|
return this.split("\n").map(it => it.trimStart()).join("\n");
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns this string with all leading and trailing whitespace removed from each line, and from lines that are split
|
||||||
|
* using a the `\\` symbol.
|
||||||
|
*
|
||||||
|
* That is, when writing multilines, write `\\\` at the end for this method to recognise where the string has been
|
||||||
|
* split.
|
||||||
|
*/
|
||||||
|
String.prototype.trimMultiLines = function(): string {
|
||||||
|
return this.trimLines().split("\\").map(it => it.trimStart()).join("");
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -417,7 +417,8 @@ export class InputParser {
|
||||||
switch (char) {
|
switch (char) {
|
||||||
case "\\":
|
case "\\":
|
||||||
if (i === input.length - 1)
|
if (i === input.length - 1)
|
||||||
throw new IllegalArgumentError("Unexpected end of input. `\\` was used but there was nothing to escape.");
|
throw new IllegalArgumentError(
|
||||||
|
"Unexpected end of input. `\\` was used but there was nothing to escape.");
|
||||||
|
|
||||||
const nextChar = input[i + 1];
|
const nextChar = input[i + 1];
|
||||||
if (isInSingleQuotes || isInDoubleQuotes)
|
if (isInSingleQuotes || isInDoubleQuotes)
|
||||||
|
|
Loading…
Reference in New Issue