move everything
This commit is contained in:
parent
3ff7e76694
commit
9050581a10
25 changed files with 37 additions and 42 deletions
199
src/component/expr/InputBlock.tsx
Normal file
199
src/component/expr/InputBlock.tsx
Normal file
|
|
@ -0,0 +1,199 @@
|
|||
import { memo, useContext, useEffect, useMemo, useRef, useState } from "react";
|
||||
|
||||
import { trie } from "dope2";
|
||||
|
||||
import { EnvContext } from "../../context/EnvContext";
|
||||
// import type { Environment, ResolvedType } from "./eval";
|
||||
import "./InputBlock.css";
|
||||
import { Type } from "../other/Type";
|
||||
import type { ExprBlockState, State2Props } from "./ExprBlock";
|
||||
// import { attemptParseLiteral } from "./eval";
|
||||
import { Input } from "../other/Input";
|
||||
import { CallContext } from "../../context/CallContext";
|
||||
import { getActions } from "../app/actions";
|
||||
import { GlobalContext } from "../../context/GlobalContext";
|
||||
import { inferTypeInput } from "../../eval/infer_type";
|
||||
|
||||
interface Literal {
|
||||
kind: "literal";
|
||||
type: string; // todo: store (and serialize) real type
|
||||
};
|
||||
interface Name {
|
||||
kind: "name";
|
||||
}
|
||||
interface Text {
|
||||
kind: "text";
|
||||
}
|
||||
export type InputValueType = Literal | Name | Text;
|
||||
|
||||
export interface InputBlockState {
|
||||
kind: "input";
|
||||
text: string;
|
||||
value: InputValueType;
|
||||
focus: boolean
|
||||
}
|
||||
|
||||
// export type SuggestionType = ["literal"|"name", string, ResolvedType];
|
||||
// export type PrioritizedSuggestionType = [number, ...SuggestionType];
|
||||
|
||||
export interface InputBlockProps extends State2Props<InputBlockState,ExprBlockState> {
|
||||
onCancel: () => void;
|
||||
}
|
||||
|
||||
// const computeSuggestions = (
|
||||
// text: string,
|
||||
// env: Environment,
|
||||
// score: InputBlockProps['score'],
|
||||
// ): PrioritizedSuggestionType[] => {
|
||||
// const literals = attemptParseLiteral(text, env);
|
||||
// const ls: SuggestionType[] = [
|
||||
// // literals
|
||||
// ... literals.map((resolved) => ["literal", text, resolved]),
|
||||
|
||||
// // names
|
||||
// ... trie.suggest(env.names)(text)(Infinity)
|
||||
// .map(([name, resolved]) => ["name", name, resolved]),
|
||||
// ]
|
||||
// // return []; // <-- uncomment to disable suggestions (useful for debugging)
|
||||
// return ls
|
||||
// .map((suggestion: SuggestionType) =>
|
||||
// [score(suggestion[2]), ...suggestion] as PrioritizedSuggestionType)
|
||||
// .sort(([priorityA], [priorityB]) => priorityB - priorityA)
|
||||
// }
|
||||
|
||||
export function InputBlock({ state, setState, /*score,*/ onCancel }: InputBlockProps) {
|
||||
const {text, focus} = state;
|
||||
const globalContext = useContext(GlobalContext);
|
||||
const env = useContext(EnvContext);
|
||||
const callContext = useContext(CallContext);
|
||||
const inputRef = useRef<HTMLInputElement>(null);
|
||||
const [i, setI] = useState(0); // selected suggestion idx
|
||||
|
||||
const singleSuggestion = trie.growPrefix(env.names)(text);
|
||||
// const suggestions = useMemo(() => computeSuggestions(text, env, score), [text, score, env]);
|
||||
const suggestions = useMemo(() => [], []);
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
if (focus) {
|
||||
inputRef.current?.focus();
|
||||
}
|
||||
}, [focus]);
|
||||
|
||||
useEffect(() => {
|
||||
if (suggestions.length >= i) {
|
||||
setI(0);
|
||||
}
|
||||
}, [suggestions.length]);
|
||||
|
||||
const onTextChange = newText => {
|
||||
setState(state => ({...state,
|
||||
text: newText,
|
||||
value: (trie.get(env.names)(newText) ? {
|
||||
kind: "name",
|
||||
} : state.value),
|
||||
}));
|
||||
}
|
||||
|
||||
const onSelectSuggestion = () => {
|
||||
// const [_priority, kind, name, dynamic] = suggestions[i];
|
||||
// if (kind === "literal") {
|
||||
// setState(state => ({
|
||||
// ...state,
|
||||
// text: name,
|
||||
// value: {kind, type: prettyT(getType(dynamic))},
|
||||
// }));
|
||||
// }
|
||||
// else {
|
||||
// setState(state => ({
|
||||
// ...state,
|
||||
// text: name,
|
||||
// value: {kind},
|
||||
// }))
|
||||
// }
|
||||
};
|
||||
|
||||
const extraHandlers = {
|
||||
ArrowDown: (e) => {
|
||||
setI((i + 1) % suggestions.length);
|
||||
e.preventDefault();
|
||||
},
|
||||
ArrowUp: (e) => {
|
||||
setI((suggestions.length + i - 1) % suggestions.length);
|
||||
e.preventDefault();
|
||||
},
|
||||
" ": (e) => {
|
||||
if (text.length > 0) {
|
||||
if (callContext.addParam) {
|
||||
callContext.addParam();
|
||||
}
|
||||
else {
|
||||
const actions = getActions(globalContext, setState);
|
||||
actions.c();
|
||||
}
|
||||
}
|
||||
e.preventDefault();
|
||||
},
|
||||
};
|
||||
|
||||
const typeInfo = inferTypeInput(state, env);
|
||||
|
||||
return <><Input
|
||||
placeholder="<name or literal>"
|
||||
onCancel={onCancel}
|
||||
onEnter={onSelectSuggestion}
|
||||
onTextChange={onTextChange}
|
||||
text={text}
|
||||
suggestion={singleSuggestion}
|
||||
extraHandlers={extraHandlers}
|
||||
>
|
||||
<span className="suggestionsPlaceholder">
|
||||
<Suggestions
|
||||
suggestions={suggestions}
|
||||
onSelect={onSelectSuggestion}
|
||||
i={i} setI={setI} />
|
||||
</span>
|
||||
</Input>
|
||||
::<Type type={typeInfo.type} />
|
||||
</>
|
||||
}
|
||||
|
||||
function Suggestions({ suggestions, onSelect, i, setI }) {
|
||||
return <>{(suggestions.length > 0) &&
|
||||
<div className={"suggestions"}>
|
||||
{suggestions.map((suggestion, j) =>
|
||||
<SuggestionMemo key={j}
|
||||
{...{setI, j,
|
||||
onSelect,
|
||||
highlighted: i===j,
|
||||
suggestion}}/>)}
|
||||
</div>
|
||||
}</>;
|
||||
}
|
||||
|
||||
interface SuggestionProps {
|
||||
setI: any;
|
||||
j: number;
|
||||
onSelect: any;
|
||||
highlighted: boolean;
|
||||
// suggestion: PrioritizedSuggestionType;
|
||||
}
|
||||
|
||||
function Suggestion({ setI, j, onSelect, highlighted, /*suggestion: [priority, kind, text, resolved]*/ }: SuggestionProps) {
|
||||
const onMouseEnter = j => () => {
|
||||
setI(j);
|
||||
};
|
||||
const onMouseDown = j => () => {
|
||||
setI(j);
|
||||
onSelect();
|
||||
};
|
||||
return <div
|
||||
key={`${j}_${name}`}
|
||||
className={(highlighted ? " selected" : "")}
|
||||
onMouseEnter={onMouseEnter(j)}
|
||||
onMouseDown={onMouseDown(j)}>
|
||||
{/* ({priority}) ({kind}) {text} :: <Type type={resolved.t} /> */}
|
||||
</div>
|
||||
}
|
||||
|
||||
const SuggestionMemo = memo<SuggestionProps>(Suggestion);
|
||||
Loading…
Add table
Add a link
Reference in a new issue