Users should be able to select points (not just lines) (#97)
* update selection datastructure to accomodate more selection metadata * Users should be able to select points (not just lines)
This commit is contained in:
29
src/App.tsx
29
src/App.tsx
@ -45,6 +45,7 @@ function App() {
|
||||
errorState,
|
||||
setProgramMemory,
|
||||
resetLogs,
|
||||
selectionRangeTypeMap,
|
||||
} = useStore((s) => ({
|
||||
editorView: s.editorView,
|
||||
setEditorView: s.setEditorView,
|
||||
@ -61,6 +62,7 @@ function App() {
|
||||
errorState: s.errorState,
|
||||
setProgramMemory: s.setProgramMemory,
|
||||
resetLogs: s.resetLogs,
|
||||
selectionRangeTypeMap: s.selectionRangeTypeMap,
|
||||
}))
|
||||
// const onChange = React.useCallback((value: string, viewUpdate: ViewUpdate) => {
|
||||
const onChange = (value: string, viewUpdate: ViewUpdate) => {
|
||||
@ -76,13 +78,30 @@ function App() {
|
||||
const ranges = viewUpdate.state.selection.ranges
|
||||
|
||||
const isChange =
|
||||
ranges.length !== selectionRange.length ||
|
||||
ranges.length !== selectionRange.codeBasedSelections.length ||
|
||||
ranges.some(({ from, to }, i) => {
|
||||
return from !== selectionRange[i][0] || to !== selectionRange[i][1]
|
||||
return (
|
||||
from !== selectionRange.codeBasedSelections[i].range[0] ||
|
||||
to !== selectionRange.codeBasedSelections[i].range[1]
|
||||
)
|
||||
})
|
||||
|
||||
if (!isChange) return
|
||||
setSelectionRanges(ranges.map(({ from, to }) => [from, to]))
|
||||
setSelectionRanges({
|
||||
otherSelections: [],
|
||||
codeBasedSelections: ranges.map(({ from, to }, i) => {
|
||||
if (selectionRangeTypeMap[to]) {
|
||||
return {
|
||||
type: selectionRangeTypeMap[to],
|
||||
range: [from, to],
|
||||
}
|
||||
}
|
||||
return {
|
||||
type: 'default',
|
||||
range: [from, to],
|
||||
}
|
||||
}),
|
||||
})
|
||||
}
|
||||
const [geoArray, setGeoArray] = useState<(ExtrudeGroup | SketchGroup)[]>([])
|
||||
useEffect(() => {
|
||||
@ -163,7 +182,7 @@ function App() {
|
||||
<div className="h-screen">
|
||||
<ModalContainer />
|
||||
<Allotment snap={true}>
|
||||
<Allotment vertical defaultSizes={[4, 1, 1]} minSize={20}>
|
||||
<Allotment vertical defaultSizes={[400, 1, 1]} minSize={20}>
|
||||
<div className="h-full flex flex-col items-start">
|
||||
<PanelHeader title="Editor" />
|
||||
{/* <button
|
||||
@ -190,7 +209,7 @@ function App() {
|
||||
<MemoryPanel />
|
||||
<Logs />
|
||||
</Allotment>
|
||||
<Allotment vertical defaultSizes={[4, 1]} minSize={20}>
|
||||
<Allotment vertical defaultSizes={[400, 1]} minSize={20}>
|
||||
<div className="h-full">
|
||||
<PanelHeader title="Drafting Board" />
|
||||
<Toolbar />
|
||||
|
@ -48,7 +48,7 @@ export const Toolbar = () => {
|
||||
if (!ast) return
|
||||
const pathToNode = getNodePathFromSourceRange(
|
||||
ast,
|
||||
selectionRanges[0]
|
||||
selectionRanges.codeBasedSelections[0].range
|
||||
)
|
||||
const { modifiedAst } = sketchOnExtrudedFace(
|
||||
ast,
|
||||
@ -85,7 +85,7 @@ export const Toolbar = () => {
|
||||
if (!ast) return
|
||||
const pathToNode = getNodePathFromSourceRange(
|
||||
ast,
|
||||
selectionRanges[0]
|
||||
selectionRanges.codeBasedSelections[0].range
|
||||
)
|
||||
const { modifiedAst, pathToExtrudeArg } = extrudeSketch(
|
||||
ast,
|
||||
@ -102,7 +102,7 @@ export const Toolbar = () => {
|
||||
if (!ast) return
|
||||
const pathToNode = getNodePathFromSourceRange(
|
||||
ast,
|
||||
selectionRanges[0]
|
||||
selectionRanges.codeBasedSelections[0].range
|
||||
)
|
||||
const { modifiedAst, pathToExtrudeArg } = extrudeSketch(
|
||||
ast,
|
||||
|
@ -98,7 +98,7 @@ export function useCalc({
|
||||
const { ast, programMemory, selectionRange } = useStore((s) => ({
|
||||
ast: s.ast,
|
||||
programMemory: s.programMemory,
|
||||
selectionRange: s.selectionRanges[0],
|
||||
selectionRange: s.selectionRanges.codeBasedSelections[0].range,
|
||||
}))
|
||||
const inputRef = useRef<HTMLInputElement>(null)
|
||||
const [availableVarInfo, setAvailableVarInfo] = useState<
|
||||
|
@ -28,7 +28,7 @@ import { useSetCursor } from '../hooks/useSetCursor'
|
||||
import { getConstraintLevelFromSourceRange } from '../lang/std/sketchcombos'
|
||||
import { createCallExpression, createPipeSubstitution } from '../lang/modifyAst'
|
||||
|
||||
function MovingSphere({
|
||||
function LineEnd({
|
||||
geo,
|
||||
sourceRange,
|
||||
editorCursor,
|
||||
@ -51,6 +51,8 @@ function MovingSphere({
|
||||
const [isMouseDown, setIsMouseDown] = useState(false)
|
||||
const baseColor = useConstraintColors(sourceRange)
|
||||
|
||||
const setCursor = useSetCursor(sourceRange, 'line-end')
|
||||
|
||||
const { setHighlightRange, guiMode, ast, updateAst, programMemory } =
|
||||
useStore((s) => ({
|
||||
setHighlightRange: s.setHighlightRange,
|
||||
@ -84,7 +86,6 @@ function MovingSphere({
|
||||
useEffect(() => {
|
||||
const handleMouseUp = () => {
|
||||
if (isMouseDown && ast) {
|
||||
const thePath = getNodePathFromSourceRange(ast, sourceRange)
|
||||
const current2d = point2DRef.current.clone()
|
||||
const inverseQuaternion = new Quaternion()
|
||||
if (
|
||||
@ -107,7 +108,7 @@ function MovingSphere({
|
||||
guiMode,
|
||||
from
|
||||
)
|
||||
|
||||
if (!(current2d.x === 0 && current2d.y === 0 && current2d.z === 0))
|
||||
updateAst(modifiedAst)
|
||||
ref.current.position.set(...position)
|
||||
}
|
||||
@ -142,7 +143,10 @@ function MovingSphere({
|
||||
setHover(false)
|
||||
setHighlightRange([0, 0])
|
||||
}}
|
||||
onPointerDown={() => inEditMode && setIsMouseDown(true)}
|
||||
onPointerDown={() => {
|
||||
inEditMode && setIsMouseDown(true)
|
||||
setCursor()
|
||||
}}
|
||||
>
|
||||
<primitive object={geo} scale={hovered ? 2 : 1} />
|
||||
<meshStandardMaterial
|
||||
@ -313,8 +317,8 @@ function WallRender({
|
||||
|
||||
const [editorCursor, setEditorCursor] = useState(false)
|
||||
useEffect(() => {
|
||||
const shouldHighlight = selectionRanges.some((range) =>
|
||||
isOverlap(geoInfo.__geoMeta.sourceRange, range)
|
||||
const shouldHighlight = selectionRanges.codeBasedSelections.some(
|
||||
({ range }) => isOverlap(geoInfo.__geoMeta.sourceRange, range)
|
||||
)
|
||||
setEditorCursor(shouldHighlight)
|
||||
}, [selectionRanges, geoInfo])
|
||||
@ -369,11 +373,17 @@ function PathRender({
|
||||
guiMode: s.guiMode,
|
||||
}))
|
||||
const [editorCursor, setEditorCursor] = useState(false)
|
||||
const [editorLineCursor, setEditorLineCursor] = useState(false)
|
||||
useEffect(() => {
|
||||
const shouldHighlight = selectionRanges.some((range) =>
|
||||
isOverlap(geoInfo.__geoMeta.sourceRange, range)
|
||||
const shouldHighlight = selectionRanges.codeBasedSelections.some(
|
||||
({ range }) => isOverlap(geoInfo.__geoMeta.sourceRange, range)
|
||||
)
|
||||
const shouldHighlightLine = selectionRanges.codeBasedSelections.some(
|
||||
({ range, type }) =>
|
||||
isOverlap(geoInfo.__geoMeta.sourceRange, range) && type === 'default'
|
||||
)
|
||||
setEditorCursor(shouldHighlight)
|
||||
setEditorLineCursor(shouldHighlightLine)
|
||||
}, [selectionRanges, geoInfo])
|
||||
return (
|
||||
<>
|
||||
@ -384,14 +394,14 @@ function PathRender({
|
||||
key={i}
|
||||
geo={meta.geo}
|
||||
sourceRange={geoInfo.__geoMeta.sourceRange}
|
||||
forceHighlight={forceHighlight || editorCursor}
|
||||
forceHighlight={editorLineCursor}
|
||||
rotation={rotation}
|
||||
position={position}
|
||||
/>
|
||||
)
|
||||
if (meta.type === 'lineEnd')
|
||||
return (
|
||||
<MovingSphere
|
||||
<LineEnd
|
||||
key={i}
|
||||
geo={meta.geo}
|
||||
from={geoInfo.from}
|
||||
@ -407,7 +417,7 @@ function PathRender({
|
||||
key={i}
|
||||
geo={meta.geo}
|
||||
sourceRange={geoInfo.__geoMeta.sourceRange}
|
||||
forceHighlight={forceHighlight || editorCursor}
|
||||
forceHighlight={forceHighlight || editorLineCursor}
|
||||
rotation={rotation}
|
||||
position={position}
|
||||
onClick={() => {
|
||||
@ -533,7 +543,12 @@ function useSetAppModeFromCursorLocation(artifacts: Artifact[]) {
|
||||
)[] = []
|
||||
artifacts?.forEach((artifact) => {
|
||||
artifact.value.forEach((geo) => {
|
||||
if (isOverlap(geo.__geoMeta.sourceRange, selectionRanges[0])) {
|
||||
if (
|
||||
isOverlap(
|
||||
geo.__geoMeta.sourceRange,
|
||||
selectionRanges.codeBasedSelections[0].range
|
||||
)
|
||||
) {
|
||||
artifactsWithinCursorRange.push({
|
||||
parentType: artifact.type,
|
||||
isParent: false,
|
||||
@ -545,7 +560,12 @@ function useSetAppModeFromCursorLocation(artifacts: Artifact[]) {
|
||||
}
|
||||
})
|
||||
artifact.__meta.forEach((meta) => {
|
||||
if (isOverlap(meta.sourceRange, selectionRanges[0])) {
|
||||
if (
|
||||
isOverlap(
|
||||
meta.sourceRange,
|
||||
selectionRanges.codeBasedSelections[0].range
|
||||
)
|
||||
) {
|
||||
artifactsWithinCursorRange.push({
|
||||
parentType: artifact.type,
|
||||
isParent: true,
|
||||
|
@ -21,9 +21,12 @@ export const ConvertToVariable = () => {
|
||||
useEffect(() => {
|
||||
if (!ast) return
|
||||
|
||||
const { isSafe, value } = isNodeSafeToReplace(ast, selectionRanges[0])
|
||||
const { isSafe, value } = isNodeSafeToReplace(
|
||||
ast,
|
||||
selectionRanges.codeBasedSelections[0].range
|
||||
)
|
||||
const canReplace = isSafe && value.type !== 'Identifier'
|
||||
const isOnlyOneSelection = selectionRanges.length === 1
|
||||
const isOnlyOneSelection = selectionRanges.codeBasedSelections.length === 1
|
||||
|
||||
const _enableHorz = canReplace && isOnlyOneSelection
|
||||
setEnableAngLen(_enableHorz)
|
||||
@ -41,7 +44,7 @@ export const ConvertToVariable = () => {
|
||||
const { modifiedAst: _modifiedAst } = moveValueIntoNewVariable(
|
||||
ast,
|
||||
programMemory,
|
||||
selectionRanges[0],
|
||||
selectionRanges.codeBasedSelections[0].range,
|
||||
variableName
|
||||
)
|
||||
|
||||
|
@ -26,8 +26,8 @@ export const EqualAngle = () => {
|
||||
const [transformInfos, setTransformInfos] = useState<TransformInfo[]>()
|
||||
useEffect(() => {
|
||||
if (!ast) return
|
||||
const paths = selectionRanges.map((selectionRange) =>
|
||||
getNodePathFromSourceRange(ast, selectionRange)
|
||||
const paths = selectionRanges.codeBasedSelections.map(({ range }) =>
|
||||
getNodePathFromSourceRange(ast, range)
|
||||
)
|
||||
const nodes = paths.map(
|
||||
(pathToNode) => getNodeFromPath<Value>(ast, pathToNode).node
|
||||
@ -52,7 +52,10 @@ export const EqualAngle = () => {
|
||||
)
|
||||
|
||||
const theTransforms = getTransformInfos(
|
||||
selectionRanges.slice(1),
|
||||
{
|
||||
...selectionRanges,
|
||||
codeBasedSelections: selectionRanges.codeBasedSelections.slice(1),
|
||||
},
|
||||
ast,
|
||||
'equalAngle'
|
||||
)
|
||||
|
@ -26,8 +26,8 @@ export const EqualLength = () => {
|
||||
const [transformInfos, setTransformInfos] = useState<TransformInfo[]>()
|
||||
useEffect(() => {
|
||||
if (!ast) return
|
||||
const paths = selectionRanges.map((selectionRange) =>
|
||||
getNodePathFromSourceRange(ast, selectionRange)
|
||||
const paths = selectionRanges.codeBasedSelections.map(({ range }) =>
|
||||
getNodePathFromSourceRange(ast, range)
|
||||
)
|
||||
const nodes = paths.map(
|
||||
(pathToNode) => getNodeFromPath<Value>(ast, pathToNode).node
|
||||
@ -52,7 +52,10 @@ export const EqualLength = () => {
|
||||
)
|
||||
|
||||
const theTransforms = getTransformInfos(
|
||||
selectionRanges.slice(1),
|
||||
{
|
||||
...selectionRanges,
|
||||
codeBasedSelections: selectionRanges.codeBasedSelections.slice(1),
|
||||
},
|
||||
ast,
|
||||
'equalLength'
|
||||
)
|
||||
|
@ -29,8 +29,8 @@ export const HorzVert = ({
|
||||
const [transformInfos, setTransformInfos] = useState<TransformInfo[]>()
|
||||
useEffect(() => {
|
||||
if (!ast) return
|
||||
const paths = selectionRanges.map((selectionRange) =>
|
||||
getNodePathFromSourceRange(ast, selectionRange)
|
||||
const paths = selectionRanges.codeBasedSelections.map(({ range }) =>
|
||||
getNodePathFromSourceRange(ast, range)
|
||||
)
|
||||
const nodes = paths.map(
|
||||
(pathToNode) => getNodeFromPath<Value>(ast, pathToNode).node
|
||||
|
@ -39,8 +39,8 @@ export const Intersect = () => {
|
||||
const [transformInfos, setTransformInfos] = useState<TransformInfo[]>()
|
||||
useEffect(() => {
|
||||
if (!ast) return
|
||||
const paths = selectionRanges.map((selectionRange) =>
|
||||
getNodePathFromSourceRange(ast, selectionRange)
|
||||
const paths = selectionRanges.codeBasedSelections.map(({ range }) =>
|
||||
getNodePathFromSourceRange(ast, range)
|
||||
)
|
||||
const nodes = paths.map(
|
||||
(pathToNode) => getNodeFromPath<Value>(ast, pathToNode).node
|
||||
@ -68,7 +68,10 @@ export const Intersect = () => {
|
||||
)
|
||||
|
||||
const theTransforms = getTransformInfos(
|
||||
selectionRanges.slice(1),
|
||||
{
|
||||
...selectionRanges,
|
||||
codeBasedSelections: selectionRanges.codeBasedSelections.slice(1),
|
||||
},
|
||||
ast,
|
||||
'intersect'
|
||||
)
|
||||
@ -150,7 +153,7 @@ export const Intersect = () => {
|
||||
}`}
|
||||
disabled={!enable}
|
||||
>
|
||||
Intersect
|
||||
perpendicularDistance
|
||||
</button>
|
||||
)
|
||||
}
|
||||
|
@ -25,8 +25,8 @@ export const RemoveConstrainingValues = () => {
|
||||
const [transformInfos, setTransformInfos] = useState<TransformInfo[]>()
|
||||
useEffect(() => {
|
||||
if (!ast) return
|
||||
const paths = selectionRanges.map((selectionRange) =>
|
||||
getNodePathFromSourceRange(ast, selectionRange)
|
||||
const paths = selectionRanges.codeBasedSelections.map(({ range }) =>
|
||||
getNodePathFromSourceRange(ast, range)
|
||||
)
|
||||
const nodes = paths.map(
|
||||
(pathToNode) => getNodeFromPath<Value>(ast, pathToNode).node
|
||||
@ -37,6 +37,7 @@ export const RemoveConstrainingValues = () => {
|
||||
toolTips.includes(node.callee.name as any)
|
||||
)
|
||||
|
||||
try {
|
||||
const theTransforms = getRemoveConstraintsTransforms(
|
||||
selectionRanges,
|
||||
ast,
|
||||
@ -46,6 +47,9 @@ export const RemoveConstrainingValues = () => {
|
||||
|
||||
const _enableHorz = isAllTooltips && theTransforms.every(Boolean)
|
||||
setEnableHorz(_enableHorz)
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
}
|
||||
}, [guiMode, selectionRanges])
|
||||
if (guiMode.mode !== 'sketch') return null
|
||||
|
||||
|
@ -35,8 +35,8 @@ export const SetAngleLength = ({
|
||||
const [transformInfos, setTransformInfos] = useState<TransformInfo[]>()
|
||||
useEffect(() => {
|
||||
if (!ast) return
|
||||
const paths = selectionRanges.map((selectionRange) =>
|
||||
getNodePathFromSourceRange(ast, selectionRange)
|
||||
const paths = selectionRanges.codeBasedSelections.map(({ range }) =>
|
||||
getNodePathFromSourceRange(ast, range)
|
||||
)
|
||||
const nodes = paths.map(
|
||||
(pathToNode) =>
|
||||
@ -60,7 +60,7 @@ export const SetAngleLength = ({
|
||||
<button
|
||||
onClick={async () => {
|
||||
if (!(transformInfos && ast)) return
|
||||
const { modifiedAst, valueUsedInTransform } = transformAstSketchLines({
|
||||
const { valueUsedInTransform } = transformAstSketchLines({
|
||||
ast: JSON.parse(JSON.stringify(ast)),
|
||||
selectionRanges,
|
||||
transformInfos,
|
||||
|
@ -43,8 +43,8 @@ export const SetHorzDistance = ({
|
||||
const [transformInfos, setTransformInfos] = useState<TransformInfo[]>()
|
||||
useEffect(() => {
|
||||
if (!ast) return
|
||||
const paths = selectionRanges.map((selectionRange) =>
|
||||
getNodePathFromSourceRange(ast, selectionRange)
|
||||
const paths = selectionRanges.codeBasedSelections.map(({ range }) =>
|
||||
getNodePathFromSourceRange(ast, range)
|
||||
)
|
||||
const nodes = paths.map(
|
||||
(pathToNode) => getNodeFromPath<Value>(ast, pathToNode).node
|
||||
@ -72,7 +72,10 @@ export const SetHorzDistance = ({
|
||||
)
|
||||
|
||||
const theTransforms = getTransformInfos(
|
||||
selectionRanges.slice(1),
|
||||
{
|
||||
...selectionRanges,
|
||||
codeBasedSelections: selectionRanges.codeBasedSelections.slice(1),
|
||||
},
|
||||
ast,
|
||||
horOrVert
|
||||
)
|
||||
@ -127,7 +130,6 @@ export const SetHorzDistance = ({
|
||||
sign,
|
||||
variableName
|
||||
)
|
||||
console.log(finalValue)
|
||||
// transform again but forcing certain values
|
||||
const { modifiedAst: _modifiedAst } =
|
||||
transformSecondarySketchLinesTagFirst({
|
||||
|
@ -1,15 +1,21 @@
|
||||
import { useStore, Range } from '../useStore'
|
||||
import { useStore, Selection, Selections } from '../useStore'
|
||||
|
||||
export function useSetCursor(sourceRange: Range) {
|
||||
export function useSetCursor(
|
||||
sourceRange: Selection['range'],
|
||||
type: Selection['type'] = 'default'
|
||||
) {
|
||||
const { setCursor, selectionRanges, isShiftDown } = useStore((s) => ({
|
||||
setCursor: s.setCursor,
|
||||
selectionRanges: s.selectionRanges,
|
||||
isShiftDown: s.isShiftDown,
|
||||
}))
|
||||
return () => {
|
||||
const ranges = isShiftDown
|
||||
? [...selectionRanges, sourceRange]
|
||||
: [sourceRange]
|
||||
setCursor(ranges)
|
||||
const selections: Selections = {
|
||||
...selectionRanges,
|
||||
codeBasedSelections: isShiftDown
|
||||
? [...selectionRanges.codeBasedSelections, { range: sourceRange, type }]
|
||||
: [{ range: sourceRange, type }],
|
||||
}
|
||||
setCursor(selections)
|
||||
}
|
||||
}
|
||||
|
@ -67,14 +67,17 @@ export function lineGeo({
|
||||
sign,
|
||||
} = trigCalcs({ from, to })
|
||||
|
||||
const lineEndLength = 0.25
|
||||
// create BoxGeometry with size [Hypotenuse3d, 0.1, 0.1] centered at center, with rotation of [0, ry, rz]
|
||||
const lineBody = new BoxGeometry(Hypotenuse3d, 0.1, 0.1)
|
||||
const lineBody = new BoxGeometry(Hypotenuse3d - lineEndLength, 0.1, 0.1)
|
||||
const __sign = to[0] === from[0] ? -1 : 1
|
||||
lineBody.translate((__sign * lineEndLength) / 2, 0, 0)
|
||||
lineBody.rotateY(ry)
|
||||
lineBody.rotateZ(rz)
|
||||
lineBody.translate(centre[0], centre[1], centre[2])
|
||||
|
||||
// create line end points with CylinderGeometry at `to`
|
||||
const lineEnd1 = new CylinderGeometry(0.05, 0.22, 0.25, 4)
|
||||
const lineEnd1 = new CylinderGeometry(0.05, 0.22, lineEndLength + 0.05, 4)
|
||||
lineEnd1.translate(0, -0.1, 0)
|
||||
lineEnd1.rotateY(Math.PI / 4)
|
||||
lineEnd1.rotateZ(rz)
|
||||
|
@ -15,7 +15,7 @@ import { internalFns } from './std/std'
|
||||
import { BufferGeometry } from 'three'
|
||||
|
||||
export type SourceRange = [number, number]
|
||||
export type PathToNode = [string | number, string][]
|
||||
export type PathToNode = [string | number, string][] // [pathKey, nodeType][]
|
||||
export type Metadata = {
|
||||
sourceRange: SourceRange
|
||||
pathToNode: PathToNode
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Range, TooTip } from '../useStore'
|
||||
import { Selection, TooTip } from '../useStore'
|
||||
import {
|
||||
Program,
|
||||
CallExpression,
|
||||
@ -534,7 +534,7 @@ export function createBinaryExpressionWithUnary([left, right]: [
|
||||
|
||||
export function giveSketchFnCallTag(
|
||||
ast: Program,
|
||||
range: Range,
|
||||
range: Selection['range'],
|
||||
tag?: string
|
||||
): { modifiedAst: Program; tag: string; isTagExisting: boolean } {
|
||||
const { node: primaryCallExp } = getNodeFromPath<CallExpression>(
|
||||
@ -563,7 +563,7 @@ export function giveSketchFnCallTag(
|
||||
export function moveValueIntoNewVariable(
|
||||
ast: Program,
|
||||
programMemory: ProgramMemory,
|
||||
sourceRange: Range,
|
||||
sourceRange: Selection['range'],
|
||||
variableName: string
|
||||
): {
|
||||
modifiedAst: Program
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { PathToNode, ProgramMemory } from './executor'
|
||||
import { Range } from '../useStore'
|
||||
import { Selection } from '../useStore'
|
||||
import {
|
||||
BinaryExpression,
|
||||
Program,
|
||||
@ -96,7 +96,7 @@ export function getNodeFromPathCurry(
|
||||
|
||||
function moreNodePathFromSourceRange(
|
||||
node: Value | ExpressionStatement | VariableDeclaration | ReturnStatement,
|
||||
sourceRange: Range,
|
||||
sourceRange: Selection['range'],
|
||||
previousPath: PathToNode = [['body', '']]
|
||||
): PathToNode {
|
||||
const [start, end] = sourceRange
|
||||
@ -239,7 +239,7 @@ function moreNodePathFromSourceRange(
|
||||
|
||||
export function getNodePathFromSourceRange(
|
||||
node: Program,
|
||||
sourceRange: Range,
|
||||
sourceRange: Selection['range'],
|
||||
previousPath: PathToNode = [['body', '']]
|
||||
): PathToNode {
|
||||
const [start, end] = sourceRange
|
||||
@ -269,7 +269,7 @@ export interface PrevVariable<T> {
|
||||
export function findAllPreviousVariables(
|
||||
ast: Program,
|
||||
programMemory: ProgramMemory,
|
||||
sourceRange: Range,
|
||||
sourceRange: Selection['range'],
|
||||
type: 'number' | 'string' = 'number'
|
||||
): {
|
||||
variables: PrevVariable<typeof type extends 'number' ? number : string>[]
|
||||
|
@ -64,7 +64,7 @@ export function getCoordsFromPaths(skGroup: SketchGroup, index = 0): Coords2d {
|
||||
|
||||
export function createFirstArg(
|
||||
sketchFn: TooTip,
|
||||
val: Value | [Value, Value],
|
||||
val: Value | [Value, Value] | [Value, Value, Value],
|
||||
tag?: Value
|
||||
): Value {
|
||||
if (!tag) {
|
||||
@ -84,6 +84,13 @@ export function createFirstArg(
|
||||
return createObjectExpression({ angle: val[0], length: val[1], tag })
|
||||
if (['angledLineToX', 'angledLineToY'].includes(sketchFn))
|
||||
return createObjectExpression({ angle: val[0], to: val[1], tag })
|
||||
if (['angledLineThatIntersects'].includes(sketchFn) && val[2])
|
||||
return createObjectExpression({
|
||||
angle: val[0],
|
||||
offset: val[1],
|
||||
intersectTag: val[2],
|
||||
tag,
|
||||
})
|
||||
} else {
|
||||
if (['xLine', 'yLine'].includes(sketchFn))
|
||||
return createObjectExpression({ length: val, tag })
|
||||
@ -1678,7 +1685,7 @@ function getFirstArgValuesForXYLineFns(callExpression: CallExpression): {
|
||||
const getAngledLineThatIntersects = (
|
||||
callExp: CallExpression
|
||||
): {
|
||||
val: [Value, Value]
|
||||
val: [Value, Value, Value]
|
||||
tag?: Value
|
||||
} => {
|
||||
const firstArg = callExp.arguments[0]
|
||||
@ -1688,15 +1695,18 @@ const getAngledLineThatIntersects = (
|
||||
const offset = firstArg.properties.find(
|
||||
(p) => p.key.name === 'offset'
|
||||
)?.value
|
||||
if (angle && offset) {
|
||||
return { val: [angle, offset], tag }
|
||||
const intersectTag = firstArg.properties.find(
|
||||
(p) => p.key.name === 'intersectTag'
|
||||
)?.value
|
||||
if (angle && offset && intersectTag) {
|
||||
return { val: [angle, offset, intersectTag], tag }
|
||||
}
|
||||
}
|
||||
throw new Error('expected ArrayExpression or ObjectExpression')
|
||||
}
|
||||
|
||||
export function getFirstArg(callExp: CallExpression): {
|
||||
val: Value | [Value, Value]
|
||||
val: Value | [Value, Value] | [Value, Value, Value]
|
||||
tag?: Value
|
||||
} {
|
||||
const name = callExp?.callee?.name
|
||||
|
@ -9,6 +9,7 @@ import {
|
||||
import { recast } from '../recast'
|
||||
import { initPromise } from '../rust'
|
||||
import { getSketchSegmentFromSourceRange } from './sketchConstraints'
|
||||
import { Selection } from '../../useStore'
|
||||
|
||||
beforeAll(() => initPromise)
|
||||
|
||||
@ -26,23 +27,30 @@ function testingSwapSketchFnCall({
|
||||
originalRange: [number, number]
|
||||
} {
|
||||
const startIndex = inputCode.indexOf(callToSwap)
|
||||
const range: [number, number] = [startIndex, startIndex + callToSwap.length]
|
||||
const range: Selection = {
|
||||
type: 'default',
|
||||
range: [startIndex, startIndex + callToSwap.length],
|
||||
}
|
||||
const tokens = lexer(inputCode)
|
||||
const ast = abstractSyntaxTree(tokens)
|
||||
const programMemory = executor(ast)
|
||||
const transformInfos = getTransformInfos([range], ast, constraintType)
|
||||
const selections = {
|
||||
codeBasedSelections: [range],
|
||||
otherSelections: [],
|
||||
}
|
||||
const transformInfos = getTransformInfos(selections, ast, constraintType)
|
||||
|
||||
if (!transformInfos) throw new Error('nope')
|
||||
const { modifiedAst } = transformAstSketchLines({
|
||||
ast,
|
||||
programMemory,
|
||||
selectionRanges: [range],
|
||||
selectionRanges: selections,
|
||||
transformInfos,
|
||||
referenceSegName: '',
|
||||
})
|
||||
return {
|
||||
newCode: recast(modifiedAst),
|
||||
originalRange: range,
|
||||
originalRange: range.range,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,16 +1,16 @@
|
||||
import { getAngle } from '../../lib/utils'
|
||||
import { Range, TooTip, toolTips } from '../../useStore'
|
||||
import { Selection, TooTip, toolTips } from '../../useStore'
|
||||
import {
|
||||
Program,
|
||||
VariableDeclarator,
|
||||
CallExpression,
|
||||
} from '../abstractSyntaxTree'
|
||||
import { SketchGroup } from '../executor'
|
||||
import { SketchGroup, SourceRange } from '../executor'
|
||||
import { InternalFn } from './stdTypes'
|
||||
|
||||
export function getSketchSegmentFromSourceRange(
|
||||
sketchGroup: SketchGroup,
|
||||
[rangeStart, rangeEnd]: Range
|
||||
[rangeStart, rangeEnd]: SourceRange
|
||||
): SketchGroup['value'][number] {
|
||||
const startSourceRange = sketchGroup.start?.__geoMeta.sourceRange
|
||||
if (
|
||||
|
@ -9,7 +9,7 @@ import {
|
||||
getConstraintLevelFromSourceRange,
|
||||
} from './sketchcombos'
|
||||
import { initPromise } from '../rust'
|
||||
import { TooTip } from '../../useStore'
|
||||
import { Selections, TooTip } from '../../useStore'
|
||||
import { executor } from '../../lang/executor'
|
||||
import { recast } from '../../lang/recast'
|
||||
|
||||
@ -80,6 +80,15 @@ function getConstraintTypeFromSourceHelper2(
|
||||
return getConstraintType(arg, fnName)
|
||||
}
|
||||
|
||||
function makeSelections(
|
||||
codeBaseSelections: Selections['codeBasedSelections']
|
||||
): Selections {
|
||||
return {
|
||||
codeBasedSelections: codeBaseSelections,
|
||||
otherSelections: [],
|
||||
}
|
||||
}
|
||||
|
||||
describe('testing transformAstForSketchLines for equal length constraint', () => {
|
||||
const inputScript = `const myVar = 3
|
||||
const myVar2 = 5
|
||||
@ -189,25 +198,28 @@ const part001 = startSketchAt([0, 0])
|
||||
show(part001)`
|
||||
it('It should transform the ast', () => {
|
||||
const ast = abstractSyntaxTree(lexer(inputScript))
|
||||
const selectionRanges = inputScript
|
||||
const selectionRanges: Selections['codeBasedSelections'] = inputScript
|
||||
.split('\n')
|
||||
.filter((ln) => ln.includes('//'))
|
||||
.map((ln) => {
|
||||
const comment = ln.split('//')[1]
|
||||
const start = inputScript.indexOf('//' + comment) - 7
|
||||
return [start, start]
|
||||
}) as [number, number][]
|
||||
return {
|
||||
type: 'default',
|
||||
range: [start, start],
|
||||
}
|
||||
})
|
||||
|
||||
const programMemory = executor(ast)
|
||||
const transformInfos = getTransformInfos(
|
||||
selectionRanges.slice(1),
|
||||
makeSelections(selectionRanges.slice(1)),
|
||||
ast,
|
||||
'equalLength'
|
||||
)
|
||||
|
||||
const newAst = transformSecondarySketchLinesTagFirst({
|
||||
ast,
|
||||
selectionRanges,
|
||||
selectionRanges: makeSelections(selectionRanges),
|
||||
transformInfos,
|
||||
programMemory,
|
||||
})?.modifiedAst
|
||||
@ -271,21 +283,28 @@ const part001 = startSketchAt([0, 0])
|
||||
|> angledLineToY([301, myVar], %) // select for vertical constraint 10
|
||||
show(part001)`
|
||||
const ast = abstractSyntaxTree(lexer(inputScript))
|
||||
const selectionRanges = inputScript
|
||||
const selectionRanges: Selections['codeBasedSelections'] = inputScript
|
||||
.split('\n')
|
||||
.filter((ln) => ln.includes('// select for horizontal constraint'))
|
||||
.map((ln) => {
|
||||
const comment = ln.split('//')[1]
|
||||
const start = inputScript.indexOf('//' + comment) - 7
|
||||
return [start, start]
|
||||
}) as [number, number][]
|
||||
return {
|
||||
type: 'default',
|
||||
range: [start, start],
|
||||
}
|
||||
})
|
||||
|
||||
const programMemory = executor(ast)
|
||||
const transformInfos = getTransformInfos(selectionRanges, ast, 'horizontal')
|
||||
const transformInfos = getTransformInfos(
|
||||
makeSelections(selectionRanges),
|
||||
ast,
|
||||
'horizontal'
|
||||
)
|
||||
|
||||
const newAst = transformAstSketchLines({
|
||||
ast,
|
||||
selectionRanges,
|
||||
selectionRanges: makeSelections(selectionRanges),
|
||||
transformInfos,
|
||||
programMemory,
|
||||
referenceSegName: '',
|
||||
@ -321,21 +340,28 @@ const part001 = startSketchAt([0, 0])
|
||||
|> yLineTo(myVar, %) // select for vertical constraint 10
|
||||
show(part001)`
|
||||
const ast = abstractSyntaxTree(lexer(inputScript))
|
||||
const selectionRanges = inputScript
|
||||
const selectionRanges: Selections['codeBasedSelections'] = inputScript
|
||||
.split('\n')
|
||||
.filter((ln) => ln.includes('// select for vertical constraint'))
|
||||
.map((ln) => {
|
||||
const comment = ln.split('//')[1]
|
||||
const start = inputScript.indexOf('//' + comment) - 7
|
||||
return [start, start]
|
||||
}) as [number, number][]
|
||||
return {
|
||||
type: 'default',
|
||||
range: [start, start],
|
||||
}
|
||||
})
|
||||
|
||||
const programMemory = executor(ast)
|
||||
const transformInfos = getTransformInfos(selectionRanges, ast, 'vertical')
|
||||
const transformInfos = getTransformInfos(
|
||||
makeSelections(selectionRanges),
|
||||
ast,
|
||||
'vertical'
|
||||
)
|
||||
|
||||
const newAst = transformAstSketchLines({
|
||||
ast,
|
||||
selectionRanges,
|
||||
selectionRanges: makeSelections(selectionRanges),
|
||||
transformInfos,
|
||||
programMemory,
|
||||
referenceSegName: '',
|
||||
@ -404,7 +430,7 @@ function helperThing(
|
||||
constraint: ConstraintType
|
||||
): string {
|
||||
const ast = abstractSyntaxTree(lexer(inputScript))
|
||||
const selectionRanges = inputScript
|
||||
const selectionRanges: Selections['codeBasedSelections'] = inputScript
|
||||
.split('\n')
|
||||
.filter((ln) =>
|
||||
linesOfInterest.some((lineOfInterest) => ln.includes(lineOfInterest))
|
||||
@ -412,19 +438,22 @@ function helperThing(
|
||||
.map((ln) => {
|
||||
const comment = ln.split('//')[1]
|
||||
const start = inputScript.indexOf('//' + comment) - 7
|
||||
return [start, start]
|
||||
}) as [number, number][]
|
||||
return {
|
||||
type: 'default',
|
||||
range: [start, start],
|
||||
}
|
||||
})
|
||||
|
||||
const programMemory = executor(ast)
|
||||
const transformInfos = getTransformInfos(
|
||||
selectionRanges.slice(1),
|
||||
makeSelections(selectionRanges.slice(1)),
|
||||
ast,
|
||||
constraint
|
||||
)
|
||||
|
||||
const newAst = transformSecondarySketchLinesTagFirst({
|
||||
ast,
|
||||
selectionRanges,
|
||||
selectionRanges: makeSelections(selectionRanges),
|
||||
transformInfos,
|
||||
programMemory,
|
||||
})?.modifiedAst
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { TransformCallback } from './stdTypes'
|
||||
import { Ranges, toolTips, TooTip, Range } from '../../useStore'
|
||||
import { Selections, toolTips, TooTip, Selection } from '../../useStore'
|
||||
import {
|
||||
BinaryPart,
|
||||
CallExpression,
|
||||
@ -127,7 +127,6 @@ const xyLineSetLength =
|
||||
: referenceSeg
|
||||
? segRef
|
||||
: args[0]
|
||||
// console.log({ lineVal, segRef, forceValueUsedInTransform, args })
|
||||
return createCallWrapper(xOrY, lineVal, tag, getArgLiteralVal(args[0]))
|
||||
}
|
||||
|
||||
@ -279,7 +278,6 @@ const setHorzVertDistanceForAngleLineCreateNode =
|
||||
(forceValueUsedInTransform as BinaryPart) ||
|
||||
createLiteral(valueUsedInTransform),
|
||||
])
|
||||
console.log('here or no?', binExp)
|
||||
return createCallWrapper(
|
||||
xOrY === 'x' ? 'angledLineToX' : 'angledLineToY',
|
||||
[varValA, binExp],
|
||||
@ -1099,7 +1097,7 @@ export function getTransformInfo(
|
||||
}
|
||||
|
||||
export function getConstraintType(
|
||||
val: Value | [Value, Value],
|
||||
val: Value | [Value, Value] | [Value, Value, Value],
|
||||
fnName: TooTip
|
||||
): LineInputsType | null {
|
||||
// this function assumes that for two val sketch functions that one arg is locked down not both
|
||||
@ -1133,12 +1131,12 @@ export function getConstraintType(
|
||||
}
|
||||
|
||||
export function getTransformInfos(
|
||||
selectionRanges: Ranges,
|
||||
selectionRanges: Selections,
|
||||
ast: Program,
|
||||
constraintType: ConstraintType
|
||||
): TransformInfo[] {
|
||||
const paths = selectionRanges.map((selectionRange) =>
|
||||
getNodePathFromSourceRange(ast, selectionRange)
|
||||
const paths = selectionRanges.codeBasedSelections.map(({ range }) =>
|
||||
getNodePathFromSourceRange(ast, range)
|
||||
)
|
||||
const nodes = paths.map(
|
||||
(pathToNode) =>
|
||||
@ -1160,13 +1158,13 @@ export function getTransformInfos(
|
||||
}
|
||||
|
||||
export function getRemoveConstraintsTransforms(
|
||||
selectionRanges: Ranges,
|
||||
selectionRanges: Selections,
|
||||
ast: Program,
|
||||
constraintType: ConstraintType
|
||||
): TransformInfo[] {
|
||||
// return ()
|
||||
const paths = selectionRanges.map((selectionRange) =>
|
||||
getNodePathFromSourceRange(ast, selectionRange)
|
||||
const paths = selectionRanges.codeBasedSelections.map((selectionRange) =>
|
||||
getNodePathFromSourceRange(ast, selectionRange.range)
|
||||
)
|
||||
const nodes = paths.map(
|
||||
(pathToNode) => getNodeFromPath<Value>(ast, pathToNode).node
|
||||
@ -1190,7 +1188,7 @@ export function transformSecondarySketchLinesTagFirst({
|
||||
forceValueUsedInTransform,
|
||||
}: {
|
||||
ast: Program
|
||||
selectionRanges: Ranges
|
||||
selectionRanges: Selections
|
||||
transformInfos: TransformInfo[]
|
||||
programMemory: ProgramMemory
|
||||
forceSegName?: string
|
||||
@ -1204,7 +1202,7 @@ export function transformSecondarySketchLinesTagFirst({
|
||||
}
|
||||
} {
|
||||
// let node = JSON.parse(JSON.stringify(ast))
|
||||
const primarySelection = selectionRanges[0]
|
||||
const primarySelection = selectionRanges.codeBasedSelections[0].range
|
||||
|
||||
const { modifiedAst, tag, isTagExisting } = giveSketchFnCallTag(
|
||||
ast,
|
||||
@ -1215,7 +1213,10 @@ export function transformSecondarySketchLinesTagFirst({
|
||||
return {
|
||||
...transformAstSketchLines({
|
||||
ast: modifiedAst,
|
||||
selectionRanges: selectionRanges.slice(1),
|
||||
selectionRanges: {
|
||||
...selectionRanges,
|
||||
codeBasedSelections: selectionRanges.codeBasedSelections.slice(1),
|
||||
},
|
||||
referencedSegmentRange: primarySelection,
|
||||
transformInfos,
|
||||
programMemory,
|
||||
@ -1239,18 +1240,18 @@ export function transformAstSketchLines({
|
||||
referencedSegmentRange,
|
||||
}: {
|
||||
ast: Program
|
||||
selectionRanges: Ranges
|
||||
selectionRanges: Selections
|
||||
transformInfos: TransformInfo[]
|
||||
programMemory: ProgramMemory
|
||||
referenceSegName: string
|
||||
forceValueUsedInTransform?: Value
|
||||
referencedSegmentRange?: Range
|
||||
referencedSegmentRange?: Selection['range']
|
||||
}): { modifiedAst: Program; valueUsedInTransform?: number } {
|
||||
// deep clone since we are mutating in a loop, of which any could fail
|
||||
let node = JSON.parse(JSON.stringify(ast))
|
||||
let _valueUsedInTransform // TODO should this be an array?
|
||||
|
||||
selectionRanges.forEach((range, index) => {
|
||||
selectionRanges.codeBasedSelections.forEach(({ range }, index) => {
|
||||
const callBack = transformInfos?.[index].createNode
|
||||
const transformTo = transformInfos?.[index].tooltip
|
||||
if (!callBack || !transformTo) throw new Error('no callback helper')
|
||||
@ -1343,7 +1344,7 @@ function getArgLiteralVal(arg: Value): number {
|
||||
}
|
||||
|
||||
export function getConstraintLevelFromSourceRange(
|
||||
cursorRange: Range,
|
||||
cursorRange: Selection['range'],
|
||||
ast: Program
|
||||
): 'free' | 'partial' | 'full' {
|
||||
const { node: sketchFnExp } = getNodeFromPath<CallExpression>(
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { isOverlap, roundOff } from './utils'
|
||||
import { Range } from '../useStore'
|
||||
import { SourceRange } from '../lang/executor'
|
||||
|
||||
describe('testing isOverlapping', () => {
|
||||
testBothOrders([0, 3], [3, 10])
|
||||
@ -11,7 +11,7 @@ describe('testing isOverlapping', () => {
|
||||
testBothOrders([0, 5], [-2, -1], false)
|
||||
})
|
||||
|
||||
function testBothOrders(a: Range, b: Range, result = true) {
|
||||
function testBothOrders(a: SourceRange, b: SourceRange, result = true) {
|
||||
it(`test is overlapping ${a} ${b}`, () => {
|
||||
expect(isOverlap(a, b)).toBe(result)
|
||||
expect(isOverlap(b, a)).toBe(result)
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { Range } from '../useStore'
|
||||
import { SourceRange } from '../lang/executor'
|
||||
|
||||
export function isOverlap(a: Range, b: Range) {
|
||||
export function isOverlap(a: SourceRange, b: SourceRange) {
|
||||
const [startingRange, secondRange] = a[0] < b[0] ? [a, b] : [b, a]
|
||||
const [lastOfFirst, firstOfSecond] = [startingRange[1], secondRange[0]]
|
||||
return lastOfFirst >= firstOfSecond
|
||||
|
@ -3,13 +3,25 @@ import { persist } from 'zustand/middleware'
|
||||
import { addLineHighlight, EditorView } from './editor/highlightextension'
|
||||
import { Program, abstractSyntaxTree } from './lang/abstractSyntaxTree'
|
||||
import { getNodeFromPath } from './lang/queryAst'
|
||||
import { ProgramMemory, Position, PathToNode, Rotation } from './lang/executor'
|
||||
import {
|
||||
ProgramMemory,
|
||||
Position,
|
||||
PathToNode,
|
||||
Rotation,
|
||||
SourceRange,
|
||||
} from './lang/executor'
|
||||
import { recast } from './lang/recast'
|
||||
import { asyncLexer } from './lang/tokeniser'
|
||||
import { EditorSelection } from '@codemirror/state'
|
||||
|
||||
export type Range = [number, number]
|
||||
export type Ranges = Range[]
|
||||
export type Selection = {
|
||||
type: 'default' | 'line-end' | 'line-mid'
|
||||
range: SourceRange
|
||||
}
|
||||
export type Selections = {
|
||||
otherSelections: ('y-axis' | 'x-axis' | 'z-axis')[]
|
||||
codeBasedSelections: Selection[]
|
||||
}
|
||||
export type TooTip =
|
||||
| 'lineTo'
|
||||
| 'line'
|
||||
@ -80,10 +92,11 @@ interface StoreState {
|
||||
editorView: EditorView | null
|
||||
setEditorView: (editorView: EditorView) => void
|
||||
highlightRange: [number, number]
|
||||
setHighlightRange: (range: Range) => void
|
||||
setCursor: (selections: Ranges) => void
|
||||
selectionRanges: Ranges
|
||||
setSelectionRanges: (range: Ranges) => void
|
||||
setHighlightRange: (range: Selection['range']) => void
|
||||
setCursor: (selections: Selections) => void
|
||||
selectionRanges: Selections
|
||||
selectionRangeTypeMap: { [key: number]: Selection['type'] }
|
||||
setSelectionRanges: (range: Selections) => void
|
||||
guiMode: GuiModes
|
||||
lastGuiMode: GuiModes
|
||||
setGuiMode: (guiMode: GuiModes) => void
|
||||
@ -118,27 +131,39 @@ export const useStore = create<StoreState>()(
|
||||
set({ editorView })
|
||||
},
|
||||
highlightRange: [0, 0],
|
||||
setHighlightRange: (highlightRange) => {
|
||||
set({ highlightRange })
|
||||
setHighlightRange: (selection) => {
|
||||
set({ highlightRange: selection })
|
||||
const editorView = get().editorView
|
||||
if (editorView) {
|
||||
editorView.dispatch({ effects: addLineHighlight.of(highlightRange) })
|
||||
editorView.dispatch({ effects: addLineHighlight.of(selection) })
|
||||
}
|
||||
},
|
||||
setCursor: (ranges: Ranges) => {
|
||||
setCursor: (selections) => {
|
||||
const { editorView } = get()
|
||||
if (!editorView) return
|
||||
const ranges: ReturnType<typeof EditorSelection.cursor>[] = []
|
||||
const selectionRangeTypeMap: { [key: number]: Selection['type'] } = {}
|
||||
set({ selectionRangeTypeMap })
|
||||
selections.codeBasedSelections.forEach(({ range, type }) => {
|
||||
ranges.push(EditorSelection.cursor(range[1]))
|
||||
selectionRangeTypeMap[range[1]] = type
|
||||
})
|
||||
setTimeout(() => {
|
||||
editorView.dispatch({
|
||||
selection: EditorSelection.create(
|
||||
[...ranges.map(([start, end]) => EditorSelection.cursor(end))],
|
||||
ranges.length - 1
|
||||
ranges,
|
||||
selections.codeBasedSelections.length - 1
|
||||
),
|
||||
})
|
||||
})
|
||||
},
|
||||
selectionRanges: [[0, 0]],
|
||||
setSelectionRanges: (selectionRanges) => {
|
||||
set({ selectionRanges })
|
||||
selectionRangeTypeMap: {},
|
||||
selectionRanges: {
|
||||
otherSelections: [],
|
||||
codeBasedSelections: [],
|
||||
},
|
||||
setSelectionRanges: (selectionRanges) =>
|
||||
set({ selectionRanges, selectionRangeTypeMap: {} }),
|
||||
guiMode: { mode: 'default' },
|
||||
lastGuiMode: { mode: 'default' },
|
||||
setGuiMode: (guiMode) => {
|
||||
@ -162,7 +187,6 @@ export const useStore = create<StoreState>()(
|
||||
},
|
||||
updateAst: async (ast, focusPath) => {
|
||||
const newCode = recast(ast)
|
||||
console.log('running update Ast', ast)
|
||||
const astWithUpdatedSource = abstractSyntaxTree(
|
||||
await asyncLexer(newCode)
|
||||
)
|
||||
@ -173,7 +197,15 @@ export const useStore = create<StoreState>()(
|
||||
const { start, end } = node
|
||||
if (!start || !end) return
|
||||
setTimeout(() => {
|
||||
get().setCursor([[start, end]])
|
||||
get().setCursor({
|
||||
codeBasedSelections: [
|
||||
{
|
||||
type: 'default',
|
||||
range: [start, end],
|
||||
},
|
||||
],
|
||||
otherSelections: [],
|
||||
})
|
||||
})
|
||||
}
|
||||
},
|
||||
|
Reference in New Issue
Block a user