Compare commits
No commits in common. "7b6d18bc6a2af175471bf9295f2e50928ea61cbe" and "8385f08923f4478b9125c9fc69c9e725279d4306" have entirely different histories.
7b6d18bc6a
...
8385f08923
6 changed files with 46 additions and 55 deletions
|
|
@ -1,15 +1,17 @@
|
|||
import { useEffect, useMemo, useState } from 'react';
|
||||
import { extendedEnv } from './environment';
|
||||
import { GlobalContext } from '../../context/GlobalContext';
|
||||
import { deepEvalExpr } from '../../eval/deep_eval';
|
||||
import { inferType, scoreTypeInfo } from '../../eval/infer_type';
|
||||
import { ExprBlock, type ExprBlockState } from '../expr/ExprBlock';
|
||||
import { TypeInfoBlock } from '../other/Type';
|
||||
import { Value } from '../other/Value';
|
||||
import { actionShortcuts } from './actions';
|
||||
import { biggerExample, emptySet, factorial, higherOrder, higherOrder2Params, inc, initialEditorState, lambda2Params, nonEmptyEditorState, pushBool, setOfListOfBool, tripleFunctionCallEditorState } from "./configurations";
|
||||
import { extendedEnv } from './environment';
|
||||
|
||||
import './App.css';
|
||||
import { evalExpr } from '../../eval/eval';
|
||||
import { Value } from '../other/Value';
|
||||
import { Type, TypeInfoBlock } from '../other/Type';
|
||||
import { deepEvalExpr } from '../../eval/deep_eval';
|
||||
|
||||
|
||||
const examples: [string, ExprBlockState][] = [
|
||||
["empty editor" , initialEditorState ],
|
||||
|
|
@ -138,11 +140,10 @@ export function App() {
|
|||
|
||||
// static evalution
|
||||
const typeInfo = useMemo(() => inferType(currentState, extendedEnv), [currentState]);
|
||||
|
||||
// dynamic evalution
|
||||
// dynamic evalutions
|
||||
const evalResult = evalExpr(currentState, extendedEnv);
|
||||
const deepEvalResult = deepEvalExpr(currentState, extendedEnv);
|
||||
|
||||
const err = typeInfo.err || deepEvalResult.err;
|
||||
console.log({deepEvalResult});
|
||||
|
||||
const onCopy = () => {
|
||||
const serialized = JSON.stringify(currentState);
|
||||
|
|
@ -215,7 +216,7 @@ export function App() {
|
|||
/>
|
||||
=
|
||||
<Value dynamic={{
|
||||
i: err ? undefined : deepEvalResult.val,
|
||||
i: evalResult.val,
|
||||
t: typeInfo.type,
|
||||
}}/>
|
||||
::
|
||||
|
|
|
|||
|
|
@ -41,7 +41,6 @@ function nestedInputProperties({state, setState, score, typeInfo, evalResult}: C
|
|||
setState(state => ({...state, input: callback(state.input)}));
|
||||
};
|
||||
const onInputCancel = () => {
|
||||
|
||||
setState(state => /*addFocusRightMost*/(state.fn)); // we become our function
|
||||
};
|
||||
const scoreInput = (inputSuggestion: ExprBlockState) => {
|
||||
|
|
@ -53,9 +52,7 @@ function nestedInputProperties({state, setState, score, typeInfo, evalResult}: C
|
|||
export function CallBlock(props: CallBlockProps) {
|
||||
const globalContext = useContext(GlobalContext);
|
||||
const addParam = getActions(globalContext, props.setState).c;
|
||||
const err = props.typeInfo.err || props.evalResult.err;
|
||||
|
||||
return <span className="functionBlock dropdownContainer">
|
||||
return <span className={"functionBlock"}>
|
||||
<CallContext value={{addParam}}>
|
||||
<FunctionHeader {...props} addParam={addParam} />
|
||||
<div className="functionParams">
|
||||
|
|
@ -69,12 +66,6 @@ export function CallBlock(props: CallBlockProps) {
|
|||
</div>
|
||||
</div>
|
||||
</CallContext>
|
||||
{(err !== undefined) &&
|
||||
<span className="">
|
||||
<div className="errorMessage">
|
||||
{err.message.trim()}
|
||||
</div>
|
||||
</span>}
|
||||
</span>;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
.errorMessage {
|
||||
color: darkred;
|
||||
background-color: pink;
|
||||
/* margin-top: 4px; */
|
||||
margin-top: 4px;
|
||||
z-index: 10;
|
||||
font-family: var(--my-monospace-font);
|
||||
white-space-collapse: preserve;
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ const computeSuggestions = (
|
|||
return result;
|
||||
}
|
||||
|
||||
export function InputBlock({ state, setState, score, onCancel, typeInfo, evalResult }: InputBlockProps) {
|
||||
export function InputBlock({ state, setState, score, onCancel, typeInfo }: InputBlockProps) {
|
||||
const {text, focus} = state;
|
||||
const globalContext = useContext(GlobalContext);
|
||||
const env = typeInfo.env;
|
||||
|
|
@ -144,7 +144,7 @@ export function InputBlock({ state, setState, score, onCancel, typeInfo, evalRes
|
|||
},
|
||||
};
|
||||
|
||||
const err = typeInfo.err || evalResult.err;
|
||||
const err = typeInfo.err || evalExpr(state, env).err;
|
||||
|
||||
return <>
|
||||
<Input
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
import { useEffect, useRef, type ReactNode, type KeyboardEvent, useState } from "react";
|
||||
|
||||
import "./Input.css";
|
||||
import { focusPrevElement, focusNextElement, setRightMostCaretPosition } from "../../util/dom_trickery";
|
||||
|
||||
interface InputProps {
|
||||
placeholder: string;
|
||||
|
|
@ -26,6 +25,38 @@ function getCaretPosition(ref: React.RefObject<HTMLInputElement| null>): number
|
|||
return ref.current?.selectionStart || 0;
|
||||
}
|
||||
|
||||
// Move caret all the way to the right in the currently focused element
|
||||
function setRightMostCaretPosition(elem) {
|
||||
const range = document.createRange();
|
||||
range.selectNode(elem);
|
||||
if (elem.lastChild) { // if no text is entered, there is no lastChild
|
||||
range.setStart(elem.lastChild, elem.textContent.length);
|
||||
range.setEnd(elem.lastChild, elem.textContent.length);
|
||||
const selection = window.getSelection();
|
||||
selection?.removeAllRanges();
|
||||
selection?.addRange(range);
|
||||
}
|
||||
}
|
||||
|
||||
function focusNextElement() {
|
||||
const editable = Array.from<any>(document.querySelectorAll('input.editable'));
|
||||
const index = editable.indexOf(document.activeElement);
|
||||
const nextElem = editable[index+1];
|
||||
if (nextElem) {
|
||||
nextElem.focus();
|
||||
}
|
||||
}
|
||||
|
||||
function focusPrevElement() {
|
||||
const editable = Array.from<any>(document.querySelectorAll('input.editable'));
|
||||
const index = editable.indexOf(document.activeElement);
|
||||
const prevElem = editable[index-1]
|
||||
if (prevElem) {
|
||||
prevElem.focus();
|
||||
setRightMostCaretPosition(prevElem);
|
||||
}
|
||||
}
|
||||
|
||||
export function Input({placeholder, text, suggestion, onTextChange, onEnter, onCancel, extraHandlers, children}: InputProps) {
|
||||
const ref = useRef<HTMLInputElement>(null);
|
||||
const [focus, setFocus] = useState<"yes"|"hide"|"no">("no");
|
||||
|
|
|
|||
|
|
@ -1,32 +0,0 @@
|
|||
|
||||
// Move caret all the way to the right in the currently focused element
|
||||
export function setRightMostCaretPosition(elem) {
|
||||
const range = document.createRange();
|
||||
range.selectNode(elem);
|
||||
if (elem.lastChild) { // if no text is entered, there is no lastChild
|
||||
range.setStart(elem.lastChild, elem.textContent.length);
|
||||
range.setEnd(elem.lastChild, elem.textContent.length);
|
||||
const selection = window.getSelection();
|
||||
selection?.removeAllRanges();
|
||||
selection?.addRange(range);
|
||||
}
|
||||
}
|
||||
|
||||
export function focusNextElement() {
|
||||
const editable = Array.from<any>(document.querySelectorAll('input.editable'));
|
||||
const index = editable.indexOf(document.activeElement);
|
||||
const nextElem = editable[index + 1];
|
||||
if (nextElem) {
|
||||
nextElem.focus();
|
||||
}
|
||||
}
|
||||
|
||||
export function focusPrevElement() {
|
||||
const editable = Array.from<any>(document.querySelectorAll('input.editable'));
|
||||
const index = editable.indexOf(document.activeElement);
|
||||
const prevElem = editable[index - 1];
|
||||
if (prevElem) {
|
||||
prevElem.focus();
|
||||
setRightMostCaretPosition(prevElem);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue