diff options
-rw-r--r-- | src/console/actions/console.ts | 37 | ||||
-rw-r--r-- | src/console/components/Console.tsx | 20 | ||||
-rw-r--r-- | src/shared/Command.ts | 29 |
3 files changed, 81 insertions, 5 deletions
diff --git a/src/console/actions/console.ts b/src/console/actions/console.ts index f7fa7a2..cef04fe 100644 --- a/src/console/actions/console.ts +++ b/src/console/actions/console.ts @@ -1,5 +1,20 @@ import * as messages from '../../shared/messages'; import * as actions from './index'; +import { Command } from "../../shared/Command"; + +const commandDocs = { + [Command.Set]: 'Set a value of the property', + [Command.Open]: 'Open a URL or search by keywords in current tab', + [Command.TabOpen]: 'Open a URL or search by keywords in new tab', + [Command.WindowOpen]: 'Open a URL or search by keywords in new window', + [Command.Buffer]: 'Select tabs by matched keywords', + [Command.BufferDelete]: 'Close a certain tab matched by keywords', + [Command.BuffersDelete]: 'Close all tabs matched by keywords', + [Command.Quit]: 'Close the current tab', + [Command.QuitAll]: 'Close all tabs', + [Command.AddBookmark]: 'Add current page to bookmarks', + [Command.Help]: 'Open Vim Vixen help in new tab', +}; const hide = (): actions.ConsoleAction => { return { @@ -68,6 +83,26 @@ const setConsoleText = (consoleText: string): actions.ConsoleAction => { }; }; +const getCommandCompletions = (text: string): actions.ConsoleAction => { + const items = Object.entries(commandDocs) + .filter(([name]) => name.startsWith(text.trimLeft())) + .map(([name, doc]) => ({ + caption: name, + content: name, + url: doc, + })); + const completions = [{ + name: "Console Command", + items, + }]; + return { + type: actions.CONSOLE_SET_COMPLETIONS, + completions, + completionSource: text, + } +}; + + const getCompletions = async(text: string): Promise<actions.ConsoleAction> => { const completions = await browser.runtime.sendMessage({ type: messages.CONSOLE_QUERY_COMPLETIONS, @@ -94,5 +129,5 @@ const completionPrev = (): actions.ConsoleAction => { export { hide, showCommand, showFind, showError, showInfo, hideCommand, setConsoleText, - enterCommand, enterFind, getCompletions, completionNext, completionPrev, + enterCommand, enterFind, getCompletions, getCommandCompletions, completionNext, completionPrev, }; diff --git a/src/console/components/Console.tsx b/src/console/components/Console.tsx index eafe2a7..0a102a0 100644 --- a/src/console/components/Console.tsx +++ b/src/console/components/Console.tsx @@ -6,6 +6,7 @@ import Completion from './console/Completion'; import Message from './console/Message'; import * as consoleActions from '../../console/actions/console'; import { State as AppState } from '../reducers'; +import CommandLineParser, { InputPhase } from "../commandline/CommandLineParser"; const COMPLETION_MAX_ITEMS = 33; @@ -18,6 +19,8 @@ type Props = StateProps & DispatchProps; class Console extends React.Component<Props> { private input: React.RefObject<Input>; + private commandLineParser: CommandLineParser = new CommandLineParser(); + constructor(props: Props) { super(props); @@ -103,16 +106,16 @@ class Console extends React.Component<Props> { onChange(e: React.ChangeEvent<HTMLInputElement>) { const text = e.target.value; this.props.dispatch(consoleActions.setConsoleText(text)); - if (this.props.mode === 'command') { - this.props.dispatch(consoleActions.getCompletions(text)); + if (this.props.mode !== 'command') { + return } + this.updateCompletions(text) } componentDidUpdate(prevProps: Props) { if (prevProps.mode !== 'command' && this.props.mode === 'command') { - this.props.dispatch( - consoleActions.getCompletions(this.props.consoleText)); + this.updateCompletions(this.props.consoleText); this.focus(); } else if (prevProps.mode !== 'find' && this.props.mode === 'find') { this.focus(); @@ -154,6 +157,15 @@ class Console extends React.Component<Props> { this.input.current.focus(); } } + + private updateCompletions(text: string) { + const phase = this.commandLineParser.inputPhase(text); + if (phase === InputPhase.OnCommand) { + return this.props.dispatch(consoleActions.getCommandCompletions(text)); + } else { + this.props.dispatch(consoleActions.getCompletions(text)); + } + } } const mapStateToProps = (state: AppState) => ({ ...state }); diff --git a/src/shared/Command.ts b/src/shared/Command.ts index e492f4a..b8c21ce 100644 --- a/src/shared/Command.ts +++ b/src/shared/Command.ts @@ -13,3 +13,32 @@ export enum Command { Set = "set", Help = "help", } + +export namespace Command { + export function members(): Command[] { + return [ + Command.Open , + Command.TabOpen , + Command.WindowOpen , + Command.Buffer , + Command.BufferDelete , + Command.BufferDeleteForce , + Command.BuffersDelete , + Command.BuffersDeleteForce , + Command.AddBookmark , + Command.Quit , + Command.QuitAll , + Command.Set , + Command.Help , + ] + } + + export function valueOf(value: string): Command { + const map = new Map(members().map(cmd => [cmd.toString(), cmd])); + const cmd = map.get(value); + if (!cmd) { + throw new Error(`unknown command '${value}`); + } + return cmd; + } +} |