forked from tools/josh
1
0
Fork 0

Add .editorconfig and format accordingly

This commit is contained in:
Florine W. Dekker 2019-11-06 15:07:56 +01:00
parent 67898842ba
commit f574d84e0b
Signed by: FWDekker
GPG Key ID: B1B567AF58D6EE0F
5 changed files with 85 additions and 52 deletions

11
.editorconfig Normal file
View File

@ -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

View File

@ -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();
} }
} }

View File

@ -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;
} }

View File

@ -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("");
}; };
/** /**

View File

@ -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)