simplify suggestions ordering

This commit is contained in:
Joeri Exelmans 2025-05-20 16:53:04 +02:00
parent fdbf43a4e9
commit bb6e742f5f
8 changed files with 109 additions and 110 deletions

View file

@ -3,13 +3,12 @@ import { memo, useContext, useEffect, useMemo, useRef, useState } from "react";
import { getType, prettyT, trie } from "dope2";
import { EnvContext } from "./EnvContext";
import type { Dynamic, ResolvedType } from "./eval";
import type { Environment, ResolvedType } from "./eval";
import "./InputBlock.css";
import { Type } from "./Type";
import type { ExprBlockState, State2Props } from "./ExprBlock";
import { attemptParseLiteral } from "./eval";
import { Input } from "./Input";
import { initialEditorState } from "./configurations";
import { CallContext } from "./CallContext";
import { getActions } from "./actions";
import { GlobalContext } from "./GlobalContext";
@ -33,37 +32,35 @@ export interface InputBlockState {
focus: boolean
}
export type SuggestionType = ['literal'|'name', string, Dynamic];
export type SuggestionType = ["literal"|"name", string, ResolvedType];
export type PrioritizedSuggestionType = [number, ...SuggestionType];
interface InputBlockProps extends State2Props<InputBlockState,ExprBlockState> {
export interface InputBlockProps extends State2Props<InputBlockState,ExprBlockState> {
onCancel: () => void;
}
const computeSuggestions = (text, env, suggestionPriority: (s: ResolvedType) => number): PrioritizedSuggestionType[] => {
const computeSuggestions = (
text: string,
env: Environment,
score: InputBlockProps['score'],
): PrioritizedSuggestionType[] => {
const literals = attemptParseLiteral(text, env);
const ls: SuggestionType[] = [
// literals
... literals.map((lit) => ["literal", text, lit]),
... literals.map((resolved) => ["literal", text, resolved]),
// names
... trie.suggest(env.names)(text)(Infinity)
.map(([name,type]) => [
"name",
name, {
...type,
substitutions: type.substitutions || new Map(),
kind: type.kind || "value",
}]),
.map(([name, resolved]) => ["name", name, resolved]),
]
// return []; // <-- uncomment to disable suggestions (useful for debugging)
return ls
.map((suggestion) => [suggestionPriority(suggestion[2]), ...suggestion] as PrioritizedSuggestionType)
.map((suggestion: SuggestionType) =>
[score(suggestion[2]), ...suggestion] as PrioritizedSuggestionType)
.sort(([priorityA], [priorityB]) => priorityB - priorityA)
}
export function InputBlock({ state, setState, suggestionPriority, onCancel }: InputBlockProps) {
export function InputBlock({ state, setState, score, onCancel }: InputBlockProps) {
const {text, focus} = state;
const globalContext = useContext(GlobalContext);
const env = useContext(EnvContext);
@ -72,7 +69,7 @@ export function InputBlock({ state, setState, suggestionPriority, onCancel }: In
const [i, setI] = useState(0); // selected suggestion idx
const singleSuggestion = trie.growPrefix(env.names)(text);
const suggestions = useMemo(() => computeSuggestions(text, env, suggestionPriority), [text, suggestionPriority, env]);
const suggestions = useMemo(() => computeSuggestions(text, env, score), [text, score, env]);
useEffect(() => {
@ -176,20 +173,20 @@ interface SuggestionProps {
suggestion: PrioritizedSuggestionType;
}
function Suggestion({ setI, j, onSelect, highlighted, suggestion: [priority, kind, name, dynamic] }: SuggestionProps) {
function Suggestion({ setI, j, onSelect, highlighted, suggestion: [priority, kind, text, resolved] }: SuggestionProps) {
const onMouseEnter = j => () => {
setI(j);
};
const onMouseDown = j => () => {
setI(j);
onSelect([priority, kind, name, dynamic]);
onSelect();
};
return <div
key={`${j}_${name}`}
className={(highlighted ? " selected" : "")}
onMouseEnter={onMouseEnter(j)}
onMouseDown={onMouseDown(j)}>
({priority}) ({kind}) {name} :: <Type type={getType(dynamic)} />
({priority}) ({kind}) {text} :: <Type type={resolved.t} />
</div>
}