aboutsummaryrefslogtreecommitdiff
path: root/src/server/repl.ts
diff options
context:
space:
mode:
authorFawn <fangrui_tong@brown.edu>2020-01-09 15:52:05 -0500
committerFawn <fangrui_tong@brown.edu>2020-01-09 15:52:05 -0500
commit9a8d2a903b10568686cc66c849fba21b1ab75be2 (patch)
treeea0bf48e4f47c72f9eeab3cbd00a5f1494abbb34 /src/server/repl.ts
parente0a8d325d601d305a166c1683dccfcc67e91fe95 (diff)
parent540bda7295f6ee7c2eed848598de6f5df74b2723 (diff)
pull and merge with master
Diffstat (limited to 'src/server/repl.ts')
-rw-r--r--src/server/repl.ts57
1 files changed, 35 insertions, 22 deletions
diff --git a/src/server/repl.ts b/src/server/repl.ts
index bd00e48cd..ad55b6aaa 100644
--- a/src/server/repl.ts
+++ b/src/server/repl.ts
@@ -3,7 +3,7 @@ import { red, green, white } from "colors";
export interface Configuration {
identifier: () => string | string;
- onInvalid?: (culprit?: string) => string | string;
+ onInvalid?: (command: string, validCommand: boolean) => string | string;
onValid?: (success?: string) => string | string;
isCaseSensitive?: boolean;
}
@@ -16,8 +16,8 @@ export interface Registration {
export default class Repl {
private identifier: () => string | string;
- private onInvalid: (culprit?: string) => string | string;
- private onValid: (success: string) => string | string;
+ private onInvalid: ((command: string, validCommand: boolean) => string) | string;
+ private onValid: ((success: string) => string) | string;
private isCaseSensitive: boolean;
private commandMap = new Map<string, Registration[]>();
public interface: Interface;
@@ -34,18 +34,24 @@ export default class Repl {
private resolvedIdentifier = () => typeof this.identifier === "string" ? this.identifier : this.identifier();
- private usage = () => {
- const resolved = this.keys;
- if (resolved) {
- return resolved;
- }
- const members: string[] = [];
- const keys = this.commandMap.keys();
- let next: IteratorResult<string>;
- while (!(next = keys.next()).done) {
- members.push(next.value);
+ private usage = (command: string, validCommand: boolean) => {
+ if (validCommand) {
+ const formatted = white(command);
+ const patterns = green(this.commandMap.get(command)!.map(({ argPatterns }) => `${formatted} ${argPatterns.join(" ")}`).join('\n'));
+ return `${this.resolvedIdentifier()}\nthe given arguments do not match any registered patterns for ${formatted}\nthe list of valid argument patterns is given by:\n${patterns}`;
+ } else {
+ const resolved = this.keys;
+ if (resolved) {
+ return resolved;
+ }
+ const members: string[] = [];
+ const keys = this.commandMap.keys();
+ let next: IteratorResult<string>;
+ while (!(next = keys.next()).done) {
+ members.push(next.value);
+ }
+ return `${this.resolvedIdentifier()} commands: { ${members.sort().join(", ")} }`;
}
- return `${this.resolvedIdentifier()} commands: { ${members.sort().join(", ")} }`;
}
private success = (command: string) => `${this.resolvedIdentifier()} completed execution of ${white(command)}`;
@@ -61,8 +67,8 @@ export default class Repl {
}
}
- private invalid = (culprit?: string) => {
- console.log(red(typeof this.onInvalid === "string" ? this.onInvalid : this.onInvalid(culprit)));
+ private invalid = (command: string, validCommand: boolean) => {
+ console.log(red(typeof this.onInvalid === "string" ? this.onInvalid : this.onInvalid(command, validCommand)));
this.busy = false;
}
@@ -83,7 +89,7 @@ export default class Repl {
}
const [command, ...args] = line.split(/\s+/g);
if (!command) {
- return this.invalid();
+ return this.invalid(command, false);
}
const registered = this.commandMap.get(command);
if (registered) {
@@ -91,25 +97,32 @@ export default class Repl {
const candidates = registered.filter(({ argPatterns: { length: count } }) => count === length);
for (const { argPatterns, action } of candidates) {
const parsed: string[] = [];
- let matched = false;
+ let matched = true;
if (length) {
for (let i = 0; i < length; i++) {
let matches: RegExpExecArray | null;
if ((matches = argPatterns[i].exec(args[i])) === null) {
+ matched = false;
break;
}
parsed.push(matches[0]);
}
- matched = true;
}
if (!length || matched) {
- await action(parsed);
- this.valid(`${command} ${parsed.join(" ")}`);
+ const result = action(parsed);
+ const resolve = () => this.valid(`${command} ${parsed.join(" ")}`);
+ if (result instanceof Promise) {
+ result.then(resolve);
+ } else {
+ resolve();
+ }
return;
}
}
+ this.invalid(command, true);
+ } else {
+ this.invalid(command, false);
}
- this.invalid(command);
}
} \ No newline at end of file