Replace values with variable helper (#84)

* Refactor getNodePathFromSourceRange

getNodePathFromSourceRange wouldn't go as deep as it should have,
stopping at pipe expressions, when it should have followed as deep
into the ast as possible.

The fact that it stopped early then had other part of the code base that
expected this behaviour and it effected a lot, so a rather large refactor

* overhaul of getNodePathFromSourceRange

* quick fix for moreNodePathFromSourceRange

* minor bugs in moreNodePathFromSourceRange

* couple more tests

* add moveValueIntoNewVariable

* add UI for replacing valuse with variable

* update button text
This commit is contained in:
Kurt Hutten
2023-04-01 16:47:00 +11:00
committed by GitHub
parent 42eb3506bb
commit 0593afc4ff
16 changed files with 936 additions and 168 deletions

View File

@ -0,0 +1,61 @@
import { useState, useEffect } from 'react'
import { create } from 'react-modal-promise'
import { useStore } from '../../useStore'
import { isNodeSafeToReplace } from '../../lang/queryAst'
import { SetVarNameModal } from '../SetVarNameModal'
import { moveValueIntoNewVariable } from '../../lang/modifyAst'
const getModalInfo = create(SetVarNameModal as any)
export const ConvertToVariable = () => {
const { guiMode, selectionRanges, ast, programMemory, updateAst } = useStore(
(s) => ({
guiMode: s.guiMode,
ast: s.ast,
updateAst: s.updateAst,
selectionRanges: s.selectionRanges,
programMemory: s.programMemory,
})
)
const [enableAngLen, setEnableAngLen] = useState(false)
useEffect(() => {
if (!ast) return
const { isSafe, value } = isNodeSafeToReplace(ast, selectionRanges[0])
const canReplace = isSafe && value.type !== 'Identifier'
const isOnlyOneSelection = selectionRanges.length === 1
const _enableHorz = canReplace && isOnlyOneSelection
setEnableAngLen(_enableHorz)
}, [guiMode, selectionRanges])
return (
<button
onClick={async () => {
if (!ast) return
try {
const { variableName } = await getModalInfo({
valueName: 'var',
} as any)
const { modifiedAst: _modifiedAst } = moveValueIntoNewVariable(
ast,
programMemory,
selectionRanges[0],
variableName
)
updateAst(_modifiedAst)
} catch (e) {
console.log('e', e)
}
}}
className={`border m-1 px-1 rounded text-xs ${
enableAngLen ? 'bg-gray-50 text-gray-800' : 'bg-gray-200 text-gray-400'
}`}
disabled={!enableAngLen}
>
ConvertToVariable
</button>
)
}

View File

@ -34,7 +34,7 @@ export const SetAngleLength = ({
programMemory: s.programMemory,
})
)
const [enableHorz, setEnableHorz] = useState(false)
const [enableAngLen, setEnableAngLen] = useState(false)
const [transformInfos, setTransformInfos] = useState<TransformInfo[]>()
useEffect(() => {
if (!ast) return
@ -42,7 +42,8 @@ export const SetAngleLength = ({
getNodePathFromSourceRange(ast, selectionRange)
)
const nodes = paths.map(
(pathToNode) => getNodeFromPath<Value>(ast, pathToNode).node
(pathToNode) =>
getNodeFromPath<Value>(ast, pathToNode, 'CallExpression').node
)
const isAllTooltips = nodes.every(
(node) =>
@ -54,7 +55,7 @@ export const SetAngleLength = ({
setTransformInfos(theTransforms)
const _enableHorz = isAllTooltips && theTransforms.every(Boolean)
setEnableHorz(_enableHorz)
setEnableAngLen(_enableHorz)
}, [guiMode, selectionRanges])
if (guiMode.mode !== 'sketch') return null
@ -102,9 +103,9 @@ export const SetAngleLength = ({
}
}}
className={`border m-1 px-1 rounded text-xs ${
enableHorz ? 'bg-gray-50 text-gray-800' : 'bg-gray-200 text-gray-400'
enableAngLen ? 'bg-gray-50 text-gray-800' : 'bg-gray-200 text-gray-400'
}`}
disabled={!enableHorz}
disabled={!enableAngLen}
>
{angleOrLength}
</button>