focus on extrude literal when extruding sketch
This commit is contained in:
@ -62,8 +62,11 @@ export const Toolbar = () => {
|
|||||||
onClick={() => {
|
onClick={() => {
|
||||||
if (!ast) return
|
if (!ast) return
|
||||||
const pathToNode = getNodePathFromSourceRange(ast, selectionRange)
|
const pathToNode = getNodePathFromSourceRange(ast, selectionRange)
|
||||||
const { modifiedAst } = extrudeSketch(ast, pathToNode)
|
const { modifiedAst, pathToExtrudeArg } = extrudeSketch(
|
||||||
updateAst(modifiedAst)
|
ast,
|
||||||
|
pathToNode
|
||||||
|
)
|
||||||
|
updateAst(modifiedAst, pathToExtrudeArg)
|
||||||
}}
|
}}
|
||||||
className="border m-1 px-1 rounded"
|
className="border m-1 px-1 rounded"
|
||||||
>
|
>
|
||||||
@ -73,8 +76,12 @@ export const Toolbar = () => {
|
|||||||
onClick={() => {
|
onClick={() => {
|
||||||
if (!ast) return
|
if (!ast) return
|
||||||
const pathToNode = getNodePathFromSourceRange(ast, selectionRange)
|
const pathToNode = getNodePathFromSourceRange(ast, selectionRange)
|
||||||
const { modifiedAst } = extrudeSketch(ast, pathToNode, false)
|
const { modifiedAst, pathToExtrudeArg } = extrudeSketch(
|
||||||
updateAst(modifiedAst)
|
ast,
|
||||||
|
pathToNode,
|
||||||
|
false
|
||||||
|
)
|
||||||
|
updateAst(modifiedAst, pathToExtrudeArg)
|
||||||
}}
|
}}
|
||||||
className="border m-1 px-1 rounded"
|
className="border m-1 px-1 rounded"
|
||||||
>
|
>
|
||||||
|
@ -55,7 +55,10 @@ function MovingSphere({
|
|||||||
const { originalXY } = useMemo(() => {
|
const { originalXY } = useMemo(() => {
|
||||||
if (ast) {
|
if (ast) {
|
||||||
const thePath = getNodePathFromSourceRange(ast, sourceRange)
|
const thePath = getNodePathFromSourceRange(ast, sourceRange)
|
||||||
const callExpression = getNodeFromPath(ast, thePath) as CallExpression
|
const { node: callExpression } = getNodeFromPath<CallExpression>(
|
||||||
|
ast,
|
||||||
|
thePath
|
||||||
|
)
|
||||||
const [xArg, yArg] = callExpression?.arguments || []
|
const [xArg, yArg] = callExpression?.arguments || []
|
||||||
const x = xArg?.type === 'Literal' ? xArg.value : -1
|
const x = xArg?.type === 'Literal' ? xArg.value : -1
|
||||||
const y = yArg?.type === 'Literal' ? yArg.value : -1
|
const y = yArg?.type === 'Literal' ? yArg.value : -1
|
||||||
|
@ -1,82 +1,82 @@
|
|||||||
|
import { PathToNode } from './executor'
|
||||||
import { Token } from './tokeniser'
|
import { Token } from './tokeniser'
|
||||||
|
|
||||||
type syntaxType =
|
type syntaxType =
|
||||||
| 'Program'
|
| 'Program'
|
||||||
| 'ExpressionStatement'
|
| 'ExpressionStatement'
|
||||||
| 'BinaryExpression'
|
| 'BinaryExpression'
|
||||||
| 'NumberLiteral'
|
|
||||||
| 'StringLiteral'
|
|
||||||
| 'CallExpression'
|
| 'CallExpression'
|
||||||
| 'Identifier'
|
| 'Identifier'
|
||||||
| 'BlockStatement'
|
| 'BlockStatement'
|
||||||
| 'IfStatement'
|
|
||||||
| 'WhileStatement'
|
|
||||||
| 'FunctionDeclaration'
|
|
||||||
| 'ReturnStatement'
|
| 'ReturnStatement'
|
||||||
| 'VariableDeclaration'
|
| 'VariableDeclaration'
|
||||||
| 'VariableDeclarator'
|
| 'VariableDeclarator'
|
||||||
| 'AssignmentExpression'
|
|
||||||
| 'UnaryExpression'
|
|
||||||
| 'MemberExpression'
|
| 'MemberExpression'
|
||||||
| 'ArrayExpression'
|
| 'ArrayExpression'
|
||||||
| 'ObjectExpression'
|
| 'ObjectExpression'
|
||||||
| 'ObjectProperty'
|
| 'ObjectProperty'
|
||||||
| 'Property'
|
|
||||||
| 'LogicalExpression'
|
|
||||||
| 'ConditionalExpression'
|
|
||||||
| 'ForStatement'
|
|
||||||
| 'ForInStatement'
|
|
||||||
| 'ForOfStatement'
|
|
||||||
| 'BreakStatement'
|
|
||||||
| 'ContinueStatement'
|
|
||||||
| 'SwitchStatement'
|
|
||||||
| 'SwitchCase'
|
|
||||||
| 'ThrowStatement'
|
|
||||||
| 'TryStatement'
|
|
||||||
| 'CatchClause'
|
|
||||||
| 'ClassDeclaration'
|
|
||||||
| 'ClassBody'
|
|
||||||
| 'MethodDefinition'
|
|
||||||
| 'NewExpression'
|
|
||||||
| 'ThisExpression'
|
|
||||||
| 'UpdateExpression'
|
|
||||||
// | "ArrowFunctionExpression"
|
|
||||||
| 'FunctionExpression'
|
| 'FunctionExpression'
|
||||||
| 'SketchExpression'
|
| 'SketchExpression'
|
||||||
| 'PipeExpression'
|
| 'PipeExpression'
|
||||||
| 'PipeSubstitution'
|
| 'PipeSubstitution'
|
||||||
| 'YieldExpression'
|
|
||||||
| 'AwaitExpression'
|
|
||||||
| 'ImportDeclaration'
|
|
||||||
| 'ImportSpecifier'
|
|
||||||
| 'ImportDefaultSpecifier'
|
|
||||||
| 'ImportNamespaceSpecifier'
|
|
||||||
| 'ExportNamedDeclaration'
|
|
||||||
| 'ExportDefaultDeclaration'
|
|
||||||
| 'ExportAllDeclaration'
|
|
||||||
| 'ExportSpecifier'
|
|
||||||
| 'TaggedTemplateExpression'
|
|
||||||
| 'TemplateLiteral'
|
|
||||||
| 'TemplateElement'
|
|
||||||
| 'SpreadElement'
|
|
||||||
| 'RestElement'
|
|
||||||
| 'SequenceExpression'
|
|
||||||
| 'DebuggerStatement'
|
|
||||||
| 'LabeledStatement'
|
|
||||||
| 'DoWhileStatement'
|
|
||||||
| 'WithStatement'
|
|
||||||
| 'EmptyStatement'
|
|
||||||
| 'Literal'
|
| 'Literal'
|
||||||
| 'ArrayPattern'
|
// | 'NumberLiteral'
|
||||||
| 'ObjectPattern'
|
// | 'StringLiteral'
|
||||||
| 'AssignmentPattern'
|
// | 'IfStatement'
|
||||||
| 'MetaProperty'
|
// | 'WhileStatement'
|
||||||
| 'Super'
|
// | 'FunctionDeclaration'
|
||||||
| 'Import'
|
// | 'AssignmentExpression'
|
||||||
| 'RegExpLiteral'
|
// | 'UnaryExpression'
|
||||||
| 'BooleanLiteral'
|
// | 'Property'
|
||||||
| 'NullLiteral'
|
// | 'LogicalExpression'
|
||||||
| 'TypeAnnotation'
|
// | 'ConditionalExpression'
|
||||||
|
// | 'ForStatement'
|
||||||
|
// | 'ForInStatement'
|
||||||
|
// | 'ForOfStatement'
|
||||||
|
// | 'BreakStatement'
|
||||||
|
// | 'ContinueStatement'
|
||||||
|
// | 'SwitchStatement'
|
||||||
|
// | 'SwitchCase'
|
||||||
|
// | 'ThrowStatement'
|
||||||
|
// | 'TryStatement'
|
||||||
|
// | 'CatchClause'
|
||||||
|
// | 'ClassDeclaration'
|
||||||
|
// | 'ClassBody'
|
||||||
|
// | 'MethodDefinition'
|
||||||
|
// | 'NewExpression'
|
||||||
|
// | 'ThisExpression'
|
||||||
|
// | 'UpdateExpression'
|
||||||
|
// | 'YieldExpression'
|
||||||
|
// | 'AwaitExpression'
|
||||||
|
// | 'ImportDeclaration'
|
||||||
|
// | 'ImportSpecifier'
|
||||||
|
// | 'ImportDefaultSpecifier'
|
||||||
|
// | 'ImportNamespaceSpecifier'
|
||||||
|
// | 'ExportNamedDeclaration'
|
||||||
|
// | 'ExportDefaultDeclaration'
|
||||||
|
// | 'ExportAllDeclaration'
|
||||||
|
// | 'ExportSpecifier'
|
||||||
|
// | 'TaggedTemplateExpression'
|
||||||
|
// | 'TemplateLiteral'
|
||||||
|
// | 'TemplateElement'
|
||||||
|
// | 'SpreadElement'
|
||||||
|
// | 'RestElement'
|
||||||
|
// | 'SequenceExpression'
|
||||||
|
// | 'DebuggerStatement'
|
||||||
|
// | 'LabeledStatement'
|
||||||
|
// | 'DoWhileStatement'
|
||||||
|
// | 'WithStatement'
|
||||||
|
// | 'EmptyStatement'
|
||||||
|
// | 'ArrayPattern'
|
||||||
|
// | 'ObjectPattern'
|
||||||
|
// | 'AssignmentPattern'
|
||||||
|
// | 'MetaProperty'
|
||||||
|
// | 'Super'
|
||||||
|
// | 'Import'
|
||||||
|
// | 'RegExpLiteral'
|
||||||
|
// | 'BooleanLiteral'
|
||||||
|
// | 'NullLiteral'
|
||||||
|
// | 'TypeAnnotation'
|
||||||
|
|
||||||
export interface Program {
|
export interface Program {
|
||||||
type: syntaxType
|
type: syntaxType
|
||||||
@ -1345,27 +1345,37 @@ function debuggerr(tokens: Token[], indexes: number[], msg = ''): string {
|
|||||||
return debugResult
|
return debugResult
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getNodeFromPath(
|
export function getNodeFromPath<T>(
|
||||||
node: Program,
|
node: Program,
|
||||||
path: (string | number)[],
|
path: (string | number)[],
|
||||||
stopAt: string = '',
|
stopAt: string = '',
|
||||||
returnEarly = false
|
returnEarly = false
|
||||||
) {
|
): {
|
||||||
|
node: T
|
||||||
|
path: PathToNode
|
||||||
|
} {
|
||||||
let currentNode = node as any
|
let currentNode = node as any
|
||||||
let stopAtNode = null
|
let stopAtNode = null
|
||||||
let successfulPaths: (string | number)[] = []
|
let successfulPaths: PathToNode = []
|
||||||
|
let pathsExplored: PathToNode = []
|
||||||
for (const pathItem of path) {
|
for (const pathItem of path) {
|
||||||
try {
|
try {
|
||||||
if (typeof currentNode[pathItem] !== 'object')
|
if (typeof currentNode[pathItem] !== 'object')
|
||||||
throw new Error('not an object')
|
throw new Error('not an object')
|
||||||
currentNode = currentNode[pathItem]
|
currentNode = currentNode[pathItem]
|
||||||
successfulPaths.push(pathItem)
|
successfulPaths.push(pathItem)
|
||||||
|
if (!stopAtNode) {
|
||||||
|
pathsExplored.push(pathItem)
|
||||||
|
}
|
||||||
if (currentNode.type === stopAt) {
|
if (currentNode.type === stopAt) {
|
||||||
// it will match the deepest node of the type
|
// it will match the deepest node of the type
|
||||||
// instead of returning at the first match
|
// instead of returning at the first match
|
||||||
stopAtNode = currentNode
|
stopAtNode = currentNode
|
||||||
if (returnEarly) {
|
if (returnEarly) {
|
||||||
return stopAtNode
|
return {
|
||||||
|
node: stopAtNode,
|
||||||
|
path: pathsExplored,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@ -1378,7 +1388,10 @@ export function getNodeFromPath(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return stopAtNode || currentNode
|
return {
|
||||||
|
node: stopAtNode || currentNode,
|
||||||
|
path: pathsExplored,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type Path = (string | number)[]
|
type Path = (string | number)[]
|
||||||
|
@ -21,7 +21,7 @@ describe('testing getNodePathFromSourceRange', () => {
|
|||||||
|
|
||||||
const ast = abstractSyntaxTree(lexer(code))
|
const ast = abstractSyntaxTree(lexer(code))
|
||||||
const nodePath = getNodePathFromSourceRange(ast, sourceRange)
|
const nodePath = getNodePathFromSourceRange(ast, sourceRange)
|
||||||
const node = getNodeFromPath(ast, nodePath)
|
const { node } = getNodeFromPath<any>(ast, nodePath)
|
||||||
|
|
||||||
expect([node.start, node.end]).toEqual(sourceRange)
|
expect([node.start, node.end]).toEqual(sourceRange)
|
||||||
expect(node.type).toBe('CallExpression')
|
expect(node.type).toBe('CallExpression')
|
||||||
|
@ -202,11 +202,11 @@ export function addLine(
|
|||||||
): { modifiedAst: Program; pathToNode: (string | number)[] } {
|
): { modifiedAst: Program; pathToNode: (string | number)[] } {
|
||||||
const _node = { ...node }
|
const _node = { ...node }
|
||||||
const dumbyStartend = { start: 0, end: 0 }
|
const dumbyStartend = { start: 0, end: 0 }
|
||||||
const sketchExpression = getNodeFromPath(
|
const { node: sketchExpression } = getNodeFromPath<SketchExpression>(
|
||||||
_node,
|
_node,
|
||||||
pathToNode,
|
pathToNode,
|
||||||
'SketchExpression'
|
'SketchExpression'
|
||||||
) as SketchExpression
|
)
|
||||||
const line: ExpressionStatement = {
|
const line: ExpressionStatement = {
|
||||||
type: 'ExpressionStatement',
|
type: 'ExpressionStatement',
|
||||||
...dumbyStartend,
|
...dumbyStartend,
|
||||||
@ -251,7 +251,10 @@ export function changeArguments(
|
|||||||
const _node = { ...node }
|
const _node = { ...node }
|
||||||
const dumbyStartend = { start: 0, end: 0 }
|
const dumbyStartend = { start: 0, end: 0 }
|
||||||
// const thePath = getNodePathFromSourceRange(_node, sourceRange)
|
// const thePath = getNodePathFromSourceRange(_node, sourceRange)
|
||||||
const callExpression = getNodeFromPath(_node, pathToNode) as CallExpression
|
const { node: callExpression } = getNodeFromPath<CallExpression>(
|
||||||
|
_node,
|
||||||
|
pathToNode
|
||||||
|
)
|
||||||
const newXArg: CallExpression['arguments'][number] =
|
const newXArg: CallExpression['arguments'][number] =
|
||||||
callExpression.arguments[0].type === 'Literal'
|
callExpression.arguments[0].type === 'Literal'
|
||||||
? {
|
? {
|
||||||
@ -285,24 +288,29 @@ export function extrudeSketch(
|
|||||||
node: Program,
|
node: Program,
|
||||||
pathToNode: (string | number)[],
|
pathToNode: (string | number)[],
|
||||||
shouldPipe = true
|
shouldPipe = true
|
||||||
): { modifiedAst: Program; pathToNode: (string | number)[] } {
|
): {
|
||||||
|
modifiedAst: Program
|
||||||
|
pathToNode: PathToNode
|
||||||
|
pathToExtrudeArg: PathToNode
|
||||||
|
} {
|
||||||
const _node = { ...node }
|
const _node = { ...node }
|
||||||
const dumbyStartend = { start: 0, end: 0 }
|
const dumbyStartend = { start: 0, end: 0 }
|
||||||
const sketchExpression = getNodeFromPath(
|
const { node: sketchExpression } = getNodeFromPath<SketchExpression>(
|
||||||
_node,
|
_node,
|
||||||
pathToNode,
|
pathToNode,
|
||||||
'SketchExpression'
|
'SketchExpression'
|
||||||
) as SketchExpression
|
)
|
||||||
|
|
||||||
// determine if sketchExpression is in a pipeExpression or not
|
// determine if sketchExpression is in a pipeExpression or not
|
||||||
const pipeExpression = getNodeFromPath(_node, pathToNode, 'PipeExpression')
|
const { node: pipeExpression } = getNodeFromPath<PipeExpression>(
|
||||||
const isInPipeExpression = pipeExpression.type === 'PipeExpression'
|
|
||||||
|
|
||||||
const variableDeclorator = getNodeFromPath(
|
|
||||||
_node,
|
_node,
|
||||||
pathToNode,
|
pathToNode,
|
||||||
'VariableDeclarator'
|
'PipeExpression'
|
||||||
) as VariableDeclarator
|
)
|
||||||
|
const isInPipeExpression = pipeExpression.type === 'PipeExpression'
|
||||||
|
|
||||||
|
const { node: variableDeclorator, path: pathToDecleration } =
|
||||||
|
getNodeFromPath<VariableDeclarator>(_node, pathToNode, 'VariableDeclarator')
|
||||||
|
|
||||||
const extrudeCall: CallExpression = {
|
const extrudeCall: CallExpression = {
|
||||||
type: 'CallExpression',
|
type: 'CallExpression',
|
||||||
@ -346,10 +354,19 @@ export function extrudeSketch(
|
|||||||
}
|
}
|
||||||
|
|
||||||
variableDeclorator.init = pipeChain
|
variableDeclorator.init = pipeChain
|
||||||
|
const pathToExtrudeArg = [
|
||||||
|
...pathToDecleration,
|
||||||
|
'init',
|
||||||
|
'body',
|
||||||
|
pipeChain.body.length - 1,
|
||||||
|
'arguments',
|
||||||
|
0,
|
||||||
|
]
|
||||||
|
|
||||||
return {
|
return {
|
||||||
modifiedAst: _node,
|
modifiedAst: _node,
|
||||||
pathToNode,
|
pathToNode,
|
||||||
|
pathToExtrudeArg,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const name = findUniqueName(node, 'part')
|
const name = findUniqueName(node, 'part')
|
||||||
@ -372,9 +389,19 @@ export function extrudeSketch(
|
|||||||
}
|
}
|
||||||
const showCallIndex = getShowIndex(_node)
|
const showCallIndex = getShowIndex(_node)
|
||||||
_node.body.splice(showCallIndex, 0, VariableDeclaration)
|
_node.body.splice(showCallIndex, 0, VariableDeclaration)
|
||||||
|
const pathToExtrudeArg = [
|
||||||
|
'body',
|
||||||
|
showCallIndex,
|
||||||
|
'declarations',
|
||||||
|
0,
|
||||||
|
'init',
|
||||||
|
'arguments',
|
||||||
|
0,
|
||||||
|
]
|
||||||
return {
|
return {
|
||||||
modifiedAst: addToShow(_node, name),
|
modifiedAst: addToShow(_node, name),
|
||||||
pathToNode: [...pathToNode.slice(0, -1), showCallIndex],
|
pathToNode: [...pathToNode.slice(0, -1), showCallIndex],
|
||||||
|
pathToExtrudeArg,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -385,22 +412,27 @@ export function sketchOnExtrudedFace(
|
|||||||
const _node = { ...node }
|
const _node = { ...node }
|
||||||
const dumbyStartend = { start: 0, end: 0 }
|
const dumbyStartend = { start: 0, end: 0 }
|
||||||
const newSketchName = findUniqueName(node, 'part')
|
const newSketchName = findUniqueName(node, 'part')
|
||||||
const oldSketchName = getNodeFromPath(
|
const oldSketchName = getNodeFromPath<VariableDeclarator>(
|
||||||
_node,
|
_node,
|
||||||
pathToNode,
|
pathToNode,
|
||||||
'VariableDeclarator',
|
'VariableDeclarator',
|
||||||
true
|
true
|
||||||
).id.name
|
).node.id.name
|
||||||
const expression = getNodeFromPath(_node, pathToNode, 'CallExpression') as
|
const { node: expression } = getNodeFromPath<
|
||||||
| VariableDeclarator
|
VariableDeclarator | CallExpression
|
||||||
| CallExpression
|
>(_node, pathToNode, 'CallExpression')
|
||||||
|
|
||||||
const pathName =
|
const pathName =
|
||||||
expression.type === 'VariableDeclarator'
|
expression.type === 'VariableDeclarator'
|
||||||
? expression.id.name
|
? expression.id.name
|
||||||
: findUniqueName(node, 'path', 2)
|
: findUniqueName(node, 'path', 2)
|
||||||
|
|
||||||
if (expression.type === 'CallExpression') {
|
if (expression.type === 'CallExpression') {
|
||||||
const block = getNodeFromPath(_node, pathToNode, 'BlockStatement')
|
const { node: block } = getNodeFromPath<BlockStatement>(
|
||||||
|
_node,
|
||||||
|
pathToNode,
|
||||||
|
'BlockStatement'
|
||||||
|
)
|
||||||
const expressionIndex = getLastIndex(pathToNode)
|
const expressionIndex = getLastIndex(pathToNode)
|
||||||
if (expression.callee.name !== 'lineTo')
|
if (expression.callee.name !== 'lineTo')
|
||||||
throw new Error('expected a lineTo call')
|
throw new Error('expected a lineTo call')
|
||||||
|
@ -1,6 +1,10 @@
|
|||||||
import create from 'zustand'
|
import create from 'zustand'
|
||||||
import { addLineHighlight, EditorView } from './editor/highlightextension'
|
import { addLineHighlight, EditorView } from './editor/highlightextension'
|
||||||
import { Program, abstractSyntaxTree } from './lang/abstractSyntaxTree'
|
import {
|
||||||
|
Program,
|
||||||
|
abstractSyntaxTree,
|
||||||
|
getNodeFromPath,
|
||||||
|
} from './lang/abstractSyntaxTree'
|
||||||
import { ProgramMemory, Position, PathToNode, Rotation } from './lang/executor'
|
import { ProgramMemory, Position, PathToNode, Rotation } from './lang/executor'
|
||||||
import { recast } from './lang/recast'
|
import { recast } from './lang/recast'
|
||||||
import { lexer } from './lang/tokeniser'
|
import { lexer } from './lang/tokeniser'
|
||||||
@ -48,7 +52,7 @@ interface StoreState {
|
|||||||
setEditorView: (editorView: EditorView) => void
|
setEditorView: (editorView: EditorView) => void
|
||||||
highlightRange: [number, number]
|
highlightRange: [number, number]
|
||||||
setHighlightRange: (range: Range) => void
|
setHighlightRange: (range: Range) => void
|
||||||
setCursor: (cursor: number) => void
|
setCursor: (start: number, end?: number) => void
|
||||||
selectionRange: [number, number]
|
selectionRange: [number, number]
|
||||||
setSelectionRange: (range: Range) => void
|
setSelectionRange: (range: Range) => void
|
||||||
guiMode: GuiModes
|
guiMode: GuiModes
|
||||||
@ -60,7 +64,7 @@ interface StoreState {
|
|||||||
resetLogs: () => void
|
resetLogs: () => void
|
||||||
ast: Program | null
|
ast: Program | null
|
||||||
setAst: (ast: Program | null) => void
|
setAst: (ast: Program | null) => void
|
||||||
updateAst: (ast: Program) => void
|
updateAst: (ast: Program, focusPath?: PathToNode) => void
|
||||||
code: string
|
code: string
|
||||||
setCode: (code: string) => void
|
setCode: (code: string) => void
|
||||||
formatCode: () => void
|
formatCode: () => void
|
||||||
@ -86,11 +90,11 @@ export const useStore = create<StoreState>()((set, get) => ({
|
|||||||
editorView.dispatch({ effects: addLineHighlight.of(highlightRange) })
|
editorView.dispatch({ effects: addLineHighlight.of(highlightRange) })
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
setCursor: (cursor: number) => {
|
setCursor: (start: number, end: number = start) => {
|
||||||
const editorView = get().editorView
|
const editorView = get().editorView
|
||||||
if (!editorView) return
|
if (!editorView) return
|
||||||
editorView.dispatch({
|
editorView.dispatch({
|
||||||
selection: { anchor: cursor, head: cursor },
|
selection: { anchor: start, head: end },
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
selectionRange: [0, 0],
|
selectionRange: [0, 0],
|
||||||
@ -118,9 +122,19 @@ export const useStore = create<StoreState>()((set, get) => ({
|
|||||||
setAst: (ast) => {
|
setAst: (ast) => {
|
||||||
set({ ast })
|
set({ ast })
|
||||||
},
|
},
|
||||||
updateAst: (ast) => {
|
updateAst: (ast, focusPath) => {
|
||||||
const newCode = recast(ast)
|
const newCode = recast(ast)
|
||||||
set({ ast, code: newCode })
|
const astWithUpdatedSource = abstractSyntaxTree(lexer(newCode))
|
||||||
|
|
||||||
|
set({ ast: astWithUpdatedSource, code: newCode })
|
||||||
|
if (focusPath) {
|
||||||
|
const { node } = getNodeFromPath<any>(astWithUpdatedSource, focusPath)
|
||||||
|
const { start, end } = node
|
||||||
|
if (!start || !end) return
|
||||||
|
setTimeout(() => {
|
||||||
|
get().setCursor(start, end)
|
||||||
|
})
|
||||||
|
}
|
||||||
},
|
},
|
||||||
code: '',
|
code: '',
|
||||||
setCode: (code) => {
|
setCode: (code) => {
|
||||||
|
Reference in New Issue
Block a user