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); +    }) +  }) +});  | 
