aboutsummaryrefslogtreecommitdiff
path: root/src/console/components
diff options
context:
space:
mode:
Diffstat (limited to 'src/console/components')
-rw-r--r--src/console/components/CommandPrompt.tsx219
-rw-r--r--src/console/components/Console.tsx2
2 files changed, 65 insertions, 156 deletions
diff --git a/src/console/components/CommandPrompt.tsx b/src/console/components/CommandPrompt.tsx
index f6f4d8f..24f46ae 100644
--- a/src/console/components/CommandPrompt.tsx
+++ b/src/console/components/CommandPrompt.tsx
@@ -1,17 +1,12 @@
import React from "react";
import * as consoleActions from "../actions/console";
-import * as completionActions from "../actions/completion";
import AppContext from "./AppContext";
-import CommandLineParser, {
- InputPhase,
-} from "../commandline/CommandLineParser";
import Completion from "./console/Completion";
import Input from "./console//Input";
-import { Command } from "../../shared/Command";
import styled from "styled-components";
-import reducer, { defaultState, completedText } from "../reducers/completion";
-import CompletionType from "../../shared/CompletionType";
+import { useCompletions, useSelectCompletion } from "../completion/hooks";
import useAutoResize from "../hooks/useAutoResize";
+import { CompletionProvider } from "../completion/provider";
const COMPLETION_MAX_ITEMS = 33;
@@ -19,13 +14,20 @@ const ConsoleWrapper = styled.div`
border-top: 1px solid gray;
`;
-const CommandPrompt: React.FC = () => {
- const { state, dispatch } = React.useContext(AppContext);
- const [completionState, completionDispatch] = React.useReducer(
- reducer,
- defaultState
- );
- const commandLineParser = new CommandLineParser();
+interface Props {
+ initialInputValue: string;
+}
+
+const CommandPromptInner: React.FC<Props> = ({ initialInputValue }) => {
+ const { dispatch } = React.useContext(AppContext);
+ const [inputValue, setInputValue] = React.useState(initialInputValue);
+ const { completions, updateCompletions } = useCompletions();
+ const {
+ select,
+ currentValue,
+ selectNext,
+ selectPrev,
+ } = useSelectCompletion();
useAutoResize();
@@ -33,174 +35,81 @@ const CommandPrompt: React.FC = () => {
dispatch(consoleActions.hideCommand());
};
- const doEnter = (e: React.KeyboardEvent<HTMLInputElement>) => {
- e.stopPropagation();
- e.preventDefault();
+ const isCancelKey = React.useCallback(
+ (e: React.KeyboardEvent<HTMLInputElement>) =>
+ e.key === "Escape" ||
+ (e.ctrlKey && e.key === "[") ||
+ (e.ctrlKey && e.key === "c"),
+ []
+ );
- const value = (e.target as HTMLInputElement).value;
- dispatch(consoleActions.enterCommand(value));
- };
+ const isNextKey = React.useCallback(
+ (e: React.KeyboardEvent<HTMLInputElement>) =>
+ (!e.shiftKey && e.key === "Tab") || (e.ctrlKey && e.key === "n"),
+ []
+ );
- const selectNext = (e: React.KeyboardEvent<HTMLInputElement>) => {
- completionDispatch(completionActions.completionNext());
- e.stopPropagation();
- e.preventDefault();
- };
+ const isPrevKey = React.useCallback(
+ (e: React.KeyboardEvent<HTMLInputElement>) =>
+ (e.shiftKey && e.key === "Tab") || (e.ctrlKey && e.key === "p"),
+ []
+ );
- const selectPrev = (e: React.KeyboardEvent<HTMLInputElement>) => {
- completionDispatch(completionActions.completionPrev());
- e.stopPropagation();
- e.preventDefault();
- };
+ const isEnterKey = React.useCallback(
+ (e: React.KeyboardEvent<HTMLInputElement>) =>
+ e.key === "Enter" || (e.ctrlKey && e.key === "m"),
+ []
+ );
const onKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
- switch (e.key) {
- case "Escape":
- dispatch(consoleActions.hideCommand());
- break;
- case "Enter":
- doEnter(e);
- break;
- case "Tab":
- if (e.shiftKey) {
- completionDispatch(completionActions.completionPrev());
- } else {
- completionDispatch(completionActions.completionNext());
- }
- e.stopPropagation();
- e.preventDefault();
- break;
- case "[":
- if (e.ctrlKey) {
- e.preventDefault();
- dispatch(consoleActions.hideCommand());
- }
- break;
- case "c":
- if (e.ctrlKey) {
- e.preventDefault();
- dispatch(consoleActions.hideCommand());
- }
- break;
- case "m":
- if (e.ctrlKey) {
- doEnter(e);
- }
- break;
- case "n":
- if (e.ctrlKey) {
- selectNext(e);
- }
- break;
- case "p":
- if (e.ctrlKey) {
- selectPrev(e);
- }
- break;
+ if (isCancelKey(e)) {
+ dispatch(consoleActions.hideCommand());
+ } else if (isEnterKey(e)) {
+ const value = (e.target as HTMLInputElement).value;
+ dispatch(consoleActions.enterCommand(value));
+ } else if (isNextKey(e)) {
+ selectNext();
+ } else if (isPrevKey(e)) {
+ selectPrev();
+ } else {
+ return;
}
+
+ e.stopPropagation();
+ e.preventDefault();
};
const onChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const text = e.target.value;
- dispatch(consoleActions.setConsoleText(text));
- const action = getCompletionAction(text);
- Promise.resolve(action).then((a) => {
- if (a) {
- completionDispatch(a);
- }
- });
+ setInputValue(text);
};
React.useEffect(() => {
- completionActions.startCompletion().then((action) => {
- completionDispatch(action);
-
- const completionAction = getCompletionAction(
- state.consoleText,
- action.completionTypes
- );
- Promise.resolve(completionAction).then((a) => {
- if (a) {
- completionDispatch(a);
- }
- });
- });
- }, []);
-
- const getCompletionAction = (
- text: string,
- completionTypes: CompletionType[] | undefined = undefined
- ) => {
- const types = completionTypes || completionState.completionTypes;
- const phase = commandLineParser.inputPhase(text);
- if (phase === InputPhase.OnCommand) {
- return completionActions.getCommandCompletions(text);
- } else {
- const cmd = commandLineParser.parse(text);
- switch (cmd.command) {
- case Command.Open:
- case Command.TabOpen:
- case Command.WindowOpen:
- return completionActions.getOpenCompletions(
- types,
- text,
- cmd.command,
- cmd.args
- );
- case Command.Buffer:
- return completionActions.getTabCompletions(
- text,
- cmd.command,
- cmd.args,
- false
- );
- case Command.BufferDelete:
- case Command.BuffersDelete:
- return completionActions.getTabCompletions(
- text,
- cmd.command,
- cmd.args,
- true
- );
- case Command.BufferDeleteForce:
- case Command.BuffersDeleteForce:
- return completionActions.getTabCompletions(
- text,
- cmd.command,
- cmd.args,
- false
- );
- case Command.Set:
- return completionActions.getPropertyCompletions(
- text,
- cmd.command,
- cmd.args
- );
- }
- }
- return undefined;
- };
+ updateCompletions(inputValue);
+ }, [inputValue]);
return (
<ConsoleWrapper>
<Completion
size={COMPLETION_MAX_ITEMS}
- completions={completionState.completions}
- select={completionState.select}
+ completions={completions}
+ select={select}
/>
<Input
prompt={":"}
onBlur={onBlur}
onKeyDown={onKeyDown}
onChange={onChange}
- value={
- completionState.select < 0
- ? state.consoleText
- : completedText(completionState)
- }
+ value={select == -1 ? inputValue : currentValue}
/>
</ConsoleWrapper>
);
};
+const CommandPrompt: React.FC<Props> = ({ initialInputValue }) => (
+ <CompletionProvider initialInputValue={initialInputValue}>
+ <CommandPromptInner initialInputValue={initialInputValue} />
+ </CompletionProvider>
+);
+
export default CommandPrompt;
diff --git a/src/console/components/Console.tsx b/src/console/components/Console.tsx
index f6f4234..508c6eb 100644
--- a/src/console/components/Console.tsx
+++ b/src/console/components/Console.tsx
@@ -16,7 +16,7 @@ const Console: React.FC = () => {
switch (state.mode) {
case "command":
- return <CommandPrompt />;
+ return <CommandPrompt initialInputValue={state.consoleText} />;
case "find":
return <FindPrompt />;
case "info":