diff options
author | Shin'ya Ueoka <ueokande@i-beam.org> | 2020-03-24 21:53:09 +0900 |
---|---|---|
committer | Shin'ya Ueoka <ueokande@i-beam.org> | 2020-03-25 06:41:00 +0900 |
commit | 2e1356b4c67206e1eda82d842fe4280452a048ff (patch) | |
tree | a1a5da44e5bbd0bf6d28e559dbc7fc090a64b571 | |
parent | 348051972ea816e506e483cb363bfea1e1474d23 (diff) |
Add command-line parser on console scripts
-rw-r--r-- | src/console/commandline/CommandLineParser.ts | 38 | ||||
-rw-r--r-- | src/console/commandline/CommandParser.ts | 52 | ||||
-rw-r--r-- | src/shared/Command.ts | 15 | ||||
-rw-r--r-- | test/console/commandline/CommandLineParser.test.ts | 29 | ||||
-rw-r--r-- | test/console/commandline/CommandParser.test.ts | 15 |
5 files changed, 149 insertions, 0 deletions
diff --git a/src/console/commandline/CommandLineParser.ts b/src/console/commandline/CommandLineParser.ts new file mode 100644 index 0000000..a166f49 --- /dev/null +++ b/src/console/commandline/CommandLineParser.ts @@ -0,0 +1,38 @@ +import CommandParser from "./CommandParser"; +import { Command } from "../../shared/Command"; + +export type CommandLine = { + readonly command: Command, + readonly args: string +} + +export enum InputPhase { + OnCommand, + OnArgs, +} + +export default class CommandLineParser { + private commandParser: CommandParser = new CommandParser(); + + inputPhase(line: string): InputPhase { + line = line.trimLeft(); + if (line.length == 0) { + return InputPhase.OnCommand + } + const command = line.split(/\s+/, 1)[0]; + if (line.length == command.length) { + return InputPhase.OnCommand + } + return InputPhase.OnArgs; + } + + parse(line: string): CommandLine { + const trimLeft = line.trimLeft(); + const command = trimLeft.split(/\s+/, 1)[0]; + const args = trimLeft.slice(command.length).trimLeft(); + return { + command: this.commandParser.parse(command), + args: args, + } + } +} diff --git a/src/console/commandline/CommandParser.ts b/src/console/commandline/CommandParser.ts new file mode 100644 index 0000000..5228c77 --- /dev/null +++ b/src/console/commandline/CommandParser.ts @@ -0,0 +1,52 @@ +import { Command } from "../../shared/Command"; + +export class UnknownCommandError extends Error { + constructor(value: string) { + super(`unknown command '${value}'`); + } +} + +export default class CommandParser { + parse(value: string): Command { + switch (value) { + case 'o': + case 'open': + return Command.Open; + case 't': + case 'tabopen': + return Command.TabOpen; + case 'w': + case 'winopen': + return Command.WindowOpen; + case 'b': + case 'buffer': + return Command.Buffer; + case 'bd': + case 'bdel': + case 'bdelete': + return Command.BufferDelete; + case 'bd!': + case 'bdel!': + case 'bdelete!': + return Command.BufferDeleteForce; + case 'bdeletes': + return Command.BuffersDelete; + case 'bdeletes!': + return Command.BuffersDeleteForce; + case 'addbookmark': + return Command.AddBookmark; + case 'q': + case 'quit': + return Command.Quit; + case 'qa': + case 'quitall': + return Command.QuitAll; + case 'set': + return Command.Set; + case 'h': + case 'help': + return Command.Help; + } + throw new UnknownCommandError(value); + } +} diff --git a/src/shared/Command.ts b/src/shared/Command.ts new file mode 100644 index 0000000..e492f4a --- /dev/null +++ b/src/shared/Command.ts @@ -0,0 +1,15 @@ +export enum Command { + Open = "open", + TabOpen = "tabopen", + WindowOpen = "winopen", + Buffer = "buffer", + BufferDelete = "bdelete", + BufferDeleteForce = "bdelete!", + BuffersDelete = "bdeletes", + BuffersDeleteForce = "bdeletes!", + AddBookmark = "addbookmark", + Quit = "quit", + QuitAll = "quitall", + Set = "set", + Help = "help", +} diff --git a/test/console/commandline/CommandLineParser.test.ts b/test/console/commandline/CommandLineParser.test.ts new file mode 100644 index 0000000..6aec682 --- /dev/null +++ b/test/console/commandline/CommandLineParser.test.ts @@ -0,0 +1,29 @@ +import CommandLineParser, {InputPhase} from "../../../src/console/commandline/CommandLineParser"; +import { Command } from "../../../src/shared/Command"; +import { expect } from "chai"; + +describe("CommandLineParser", () => { + describe("#inputPhase", () => { + it("returns parsed command-line", () => { + const sut = new CommandLineParser(); + expect(sut.inputPhase("")).to.equal(InputPhase.OnCommand); + expect(sut.inputPhase("op")).to.equal(InputPhase.OnCommand); + expect(sut.inputPhase("open ")).to.equal(InputPhase.OnArgs); + expect(sut.inputPhase("open apple")).to.equal(InputPhase.OnArgs) + }); + }); + describe("#parse", () => { + it("returns parsed command-line", () => { + const sut = new CommandLineParser(); + expect(sut.parse("open google apple")).to.deep.equal({ + command: Command.Open, + args: "google apple", + }); + + expect(sut.parse("qa")).to.deep.equal({ + command: Command.QuitAll, + args: "", + }); + }) + }) +}); diff --git a/test/console/commandline/CommandParser.test.ts b/test/console/commandline/CommandParser.test.ts new file mode 100644 index 0000000..4ad78fd --- /dev/null +++ b/test/console/commandline/CommandParser.test.ts @@ -0,0 +1,15 @@ +import CommandParser, { UnknownCommandError } from "../../../src/console/commandline/CommandParser"; +import { Command } from "../../../src/shared/Command"; +import { expect } from "chai" + +describe("CommandParser", () => { + describe("#parse", () => { + it("returns matched command with the string", () => { + const sut = new CommandParser(); + expect(sut.parse("open")).to.equal(Command.Open); + expect(sut.parse("w")).to.equal(Command.WindowOpen); + expect(sut.parse("bdelete!")).to.equal(Command.BufferDeleteForce); + expect(() => sut.parse("harakiri")).to.throw(UnknownCommandError); + }) + }) +}); |