Let ... in ... block autocomplete also sorted by best 'match', type-wise

This commit is contained in:
Joeri Exelmans 2025-05-16 08:51:58 +02:00
parent 2d81e42447
commit 8abbac4bc9
7 changed files with 66 additions and 43 deletions

View file

@ -4,11 +4,12 @@ import { growEnv } from "dope2";
import { Editor, type EditorState } from "./Editor";
import { EnvContext } from "./EnvContext";
import { evalEditorBlock, type ResolvedType } from "./eval";
import { evalEditorBlock, evalLetInBlock, scoreResolved, type ResolvedType } from "./eval";
import { type State2Props } from "./Editor";
import { autoInputWidth } from "./util/dom_trickery";
import "./LetInBlock.css";
import type { SuggestionType } from "./InputBlock";
export interface LetInBlockState {
kind: "let";
@ -17,17 +18,19 @@ export interface LetInBlockState {
inner: EditorState;
}
interface LetInBlockProps extends State2Props<LetInBlockState> {
interface LetInBlockProps extends State2Props<LetInBlockState,EditorState> {
suggestionPriority: (suggestion: SuggestionType) => number;
}
export function makeInnerEnv(env, name: string, value: ResolvedType) {
if (value.kind === "value") {
return growEnv(env)(name)(value)
}
return env;
}
export function LetInBlock({state, setState}: LetInBlockProps) {
export function LetInBlock({state, setState, suggestionPriority}: LetInBlockProps) {
const {name, value, inner} = state;
const env = useContext(EnvContext);
const valueResolved = evalEditorBlock(value, env);
@ -47,10 +50,12 @@ export function LetInBlock({state, setState}: LetInBlockProps) {
useEffect(() => autoInputWidth(nameRef, name, 60), [nameRef, name]);
console.log({innerEnv});
return <span className="letIn">
<div className="decl">
<span className="keyword">let</span>
&nbsp;
<input
ref={nameRef}
className='editable'
@ -58,22 +63,28 @@ export function LetInBlock({state, setState}: LetInBlockProps) {
placeholder="<name>"
onChange={onChangeName}
/>
<span className="keyword">=</span>
<span className="keyword">&nbsp;=&nbsp;</span>
<Editor
state={value}
setState={setValue}
suggestionPriority={() => 0}
onCancel={() => {}}
suggestionPriority={(suggestion: SuggestionType) => {
const innerEnv = makeInnerEnv(env, name, suggestion[2]);
const resolved = evalEditorBlock(inner, innerEnv);
return scoreResolved(resolved, suggestionPriority);
}}
onCancel={() => setState(state => state.inner)} // keep inner
/>
&nbsp;<span className="keyword">in</span>
<span className="keyword">in</span>
</div>
<div className="inner">
<EnvContext value={innerEnv}>
<Editor
state={inner}
setState={setInner}
suggestionPriority={() => 0}
onCancel={() => {}}
suggestionPriority={(suggestion: SuggestionType) => {
return suggestionPriority(suggestion)
}}
onCancel={() => setState(state => state.value)} // keep value
/>
</EnvContext>
</div>