diff --git a/src/components/ModelingSidebar/ModelingPanes/FeatureTreePane.tsx b/src/components/ModelingSidebar/ModelingPanes/FeatureTreePane.tsx
index 9a29f50d6..99bc23527 100644
--- a/src/components/ModelingSidebar/ModelingPanes/FeatureTreePane.tsx
+++ b/src/components/ModelingSidebar/ModelingPanes/FeatureTreePane.tsx
@@ -64,13 +64,28 @@ export const FeatureTreePane = () => {
scrollToError: () => {
editorManager.scrollToFirstErrorDiagnosticIfExists()
},
- sendTranslateCommand: ({ context }) => {
+ sendTranslateCommand: () => {
commandBarActor.send({
type: 'Find and select command',
- data: {
- name: 'Translate',
- groupId: 'modeling',
- },
+ data: { name: 'Translate', groupId: 'modeling' },
+ })
+ },
+ sendRotateCommand: () => {
+ commandBarActor.send({
+ type: 'Find and select command',
+ data: { name: 'Rotate', groupId: 'modeling' },
+ })
+ },
+ sendScaleCommand: () => {
+ commandBarActor.send({
+ type: 'Find and select command',
+ data: { name: 'Scale', groupId: 'modeling' },
+ })
+ },
+ sendCloneCommand: () => {
+ commandBarActor.send({
+ type: 'Find and select command',
+ data: { name: 'Clone', groupId: 'modeling' },
})
},
sendSelectionEvent: ({ context }) => {
@@ -537,7 +552,7 @@ const OperationItem = (props: {
!stdLibMap[props.item.name]?.supportsTransform
}
>
- Set translate
+ Translate
,
- Set rotate
+ Rotate
,
- Set scale
+ Scale
,
- geometryName: string
- variableName: string
-}): { modifiedAst: Node; pathToNode: PathToNode } {
- const modifiedAst = structuredClone(ast)
- const variable = createVariableDeclaration(
- variableName,
- createCallExpressionStdLibKw('clone', createLocalName(geometryName), [])
- )
-
- modifiedAst.body.push(variable)
- const insertAt = modifiedAst.body.length - 1
- const pathToNode: PathToNode = [
- ['body', ''],
- [insertAt, 'index'],
- ['declaration', 'VariableDeclaration'],
- ['init', 'VariableDeclarator'],
- ]
-
- return {
- modifiedAst,
- pathToNode,
- }
-}
-
/**
* Return a modified clone of an AST with a named constant inserted into the body
*/
@@ -1252,7 +1219,8 @@ export function setCallInAst(
ast: Node,
call: Node,
nodeToEdit?: PathToNode,
- lastPathToNode?: PathToNode
+ lastPathToNode?: PathToNode,
+ toFirstKwarg?: boolean
): Error | PathToNode {
let pathToNode: PathToNode | undefined
if (nodeToEdit) {
@@ -1283,7 +1251,7 @@ export function setCallInAst(
const name = findUniqueName(ast, call.callee.name.name)
const declaration = createVariableDeclaration(name, call)
ast.body.push(declaration)
- pathToNode = createPathToNodeForLastVariable(ast)
+ pathToNode = createPathToNodeForLastVariable(ast, toFirstKwarg)
}
}
diff --git a/src/lang/modifyAst/transforms.ts b/src/lang/modifyAst/transforms.ts
index 3f4d8584c..ccee81046 100644
--- a/src/lang/modifyAst/transforms.ts
+++ b/src/lang/modifyAst/transforms.ts
@@ -11,10 +11,6 @@ import {
} from '@src/lang/queryAst'
import type { ArtifactGraph, PathToNode, Program } from '@src/lang/wasm'
import { err } from '@src/lib/trap'
-import {
- findAllChildrenAndOrderByPlaceInCode,
- getLastVariable,
-} from '@src/lang/modifyAst/boolean'
import type { Selections } from '@src/lib/selections'
import type { KclCommandValue } from '@src/lib/commandTypes'
import {
@@ -208,33 +204,53 @@ export function addScale({
})
}
-export function retrievePathToNodeFromTransformSelection(
- selection: Selections,
- artifactGraph: ArtifactGraph,
+export function addClone({
+ ast,
+ artifactGraph,
+ objects,
+ nodeToEdit,
+}: {
ast: Node
-): PathToNode | Error {
- const error = new Error(
- "Couldn't retrieve selection. If you're trying to transform an import, use the feature tree."
- )
- const hasPathToNode = !!selection.graphSelections[0].codeRef.pathToNode.length
- const artifact = selection.graphSelections[0].artifact
- let pathToNode: PathToNode | undefined
- if (hasPathToNode && artifact) {
- const children = findAllChildrenAndOrderByPlaceInCode(
- artifact,
- artifactGraph
- )
- const variable = getLastVariable(children, ast)
- if (!variable) {
- return error
- }
+ artifactGraph: ArtifactGraph
+ objects: Selections
+ nodeToEdit?: PathToNode
+}): Error | { modifiedAst: Node; pathToNode: PathToNode } {
+ // 1. Clone the ast so we can edit it
+ const modifiedAst = structuredClone(ast)
- pathToNode = variable.pathToNode
- } else if (hasPathToNode) {
- pathToNode = selection.graphSelections[0].codeRef.pathToNode
- } else {
- return error
+ // 2. Prepare unlabeled arguments
+ // Map the sketches selection into a list of kcl expressions to be passed as unlabelled argument
+ const variableExpressions = getVariableExprsFromSelection(
+ objects,
+ modifiedAst,
+ nodeToEdit,
+ true,
+ artifactGraph
+ )
+ if (err(variableExpressions)) {
+ return variableExpressions
}
- return pathToNode
+ const objectsExpr = createVariableExpressionsArray(variableExpressions.exprs)
+ const call = createCallExpressionStdLibKw('clone', objectsExpr, [])
+
+ // 3. If edit, we assign the new function call declaration to the existing node,
+ // otherwise just push to the end
+ const lastPath = variableExpressions.paths.pop() // TODO: check if this is correct
+ const toFirstKwarg = false
+ const pathToNode = setCallInAst(
+ modifiedAst,
+ call,
+ nodeToEdit,
+ lastPath,
+ toFirstKwarg
+ )
+ if (err(pathToNode)) {
+ return pathToNode
+ }
+
+ return {
+ modifiedAst,
+ pathToNode,
+ }
}
diff --git a/src/lib/commandBarConfigs/modelingCommandConfig.ts b/src/lib/commandBarConfigs/modelingCommandConfig.ts
index a8744a485..ea7c225a4 100644
--- a/src/lib/commandBarConfigs/modelingCommandConfig.ts
+++ b/src/lib/commandBarConfigs/modelingCommandConfig.ts
@@ -1,7 +1,6 @@
import type { Models } from '@kittycad/lib'
import { angleLengthInfo } from '@src/components/Toolbar/angleLengthInfo'
-import { findUniqueName } from '@src/lang/create'
import { getNodeFromPath } from '@src/lang/queryAst'
import { getVariableDeclaration } from '@src/lang/queryAst/getVariableDeclaration'
import { getNodePathFromSourceRange } from '@src/lang/queryAstNodePathUtils'
@@ -19,7 +18,6 @@ import type {
} from '@src/lib/commandTypes'
import {
IS_ML_EXPERIMENTAL,
- KCL_DEFAULT_CONSTANT_PREFIXES,
KCL_DEFAULT_DEGREE,
KCL_DEFAULT_LENGTH,
KCL_DEFAULT_TRANSFORM,
@@ -210,8 +208,7 @@ export type ModelingCommandSchema = {
}
Clone: {
nodeToEdit?: PathToNode
- selection: Selections
- variableName: string
+ objects: Selections
}
'Boolean Subtract': {
solids: Selections
@@ -1211,39 +1208,14 @@ export const modelingMachineCommandConfig: StateMachineCommandSetConfig<
nodeToEdit: {
...nodeToEditProps,
},
- selection: {
+ objects: {
// selectionMixed allows for feature tree selection of module imports
inputType: 'selectionMixed',
- multiple: false,
- required: true,
- skip: true,
- selectionTypes: ['path'],
+ selectionTypes: ['path', 'sweep'],
selectionFilter: ['object'],
- hidden: (context) => Boolean(context.argumentsToSubmit.nodeToEdit),
- },
- variableName: {
- inputType: 'string',
+ multiple: true,
required: true,
- defaultValue: () => {
- return findUniqueName(
- kclManager.ast,
- KCL_DEFAULT_CONSTANT_PREFIXES.CLONE
- )
- },
- validation: async ({
- data,
- }: {
- data: string
- }) => {
- // Be conservative and error out if there is an item or module with the same name.
- const variableExists =
- kclManager.variables[data] || kclManager.variables['__mod_' + data]
- if (variableExists) {
- return 'This variable name is already in use.'
- }
-
- return true
- },
+ hidden: (context) => Boolean(context.argumentsToSubmit.nodeToEdit),
},
},
},
diff --git a/src/lib/kclHelpers.ts b/src/lib/kclHelpers.ts
index aaec329c8..a62fd7573 100644
--- a/src/lib/kclHelpers.ts
+++ b/src/lib/kclHelpers.ts
@@ -1,11 +1,6 @@
import { executeAstMock } from '@src/lang/langHelpers'
-import {
- type CallExpressionKw,
- formatNumberValue,
- parse,
- resultIsOk,
-} from '@src/lang/wasm'
-import type { KclCommandValue, KclExpression } from '@src/lib/commandTypes'
+import { formatNumberValue, parse, resultIsOk } from '@src/lang/wasm'
+import type { KclExpression } from '@src/lib/commandTypes'
import { rustContext } from '@src/lib/singletons'
import { err } from '@src/lib/trap'
diff --git a/src/lib/operations.ts b/src/lib/operations.ts
index b07fc061b..147a0d89a 100644
--- a/src/lib/operations.ts
+++ b/src/lib/operations.ts
@@ -1525,11 +1525,10 @@ async function prepareToEditTranslate({ operation }: EnterEditFlowProps) {
name: 'Translate',
groupId: 'modeling',
}
- const isModuleImport = operation.type === 'GroupBegin'
const isSupportedStdLibCall =
operation.type === 'StdLibCall' &&
stdLibMap[operation.name]?.supportsTransform
- if (!isModuleImport && !isSupportedStdLibCall) {
+ if (!isSupportedStdLibCall) {
return {
reason: 'Unsupported operation type. Please edit in the code editor.',
}
@@ -1549,53 +1548,51 @@ async function prepareToEditTranslate({ operation }: EnterEditFlowProps) {
let y: KclCommandValue | undefined = undefined
let z: KclCommandValue | undefined = undefined
let global: boolean | undefined
- if (isSupportedStdLibCall) {
- if (operation.labeledArgs.x) {
- const result = await stringToKclExpression(
- codeManager.code.slice(
- operation.labeledArgs.x.sourceRange[0],
- operation.labeledArgs.x.sourceRange[1]
- )
+ if (operation.labeledArgs.x) {
+ const result = await stringToKclExpression(
+ codeManager.code.slice(
+ operation.labeledArgs.x.sourceRange[0],
+ operation.labeledArgs.x.sourceRange[1]
)
- if (err(result) || 'errors' in result) {
- return { reason: "Couldn't retrieve x argument" }
- }
- x = result
+ )
+ if (err(result) || 'errors' in result) {
+ return { reason: "Couldn't retrieve x argument" }
}
+ x = result
+ }
- if (operation.labeledArgs.y) {
- const result = await stringToKclExpression(
- codeManager.code.slice(
- operation.labeledArgs.y.sourceRange[0],
- operation.labeledArgs.y.sourceRange[1]
- )
+ if (operation.labeledArgs.y) {
+ const result = await stringToKclExpression(
+ codeManager.code.slice(
+ operation.labeledArgs.y.sourceRange[0],
+ operation.labeledArgs.y.sourceRange[1]
)
- if (err(result) || 'errors' in result) {
- return { reason: "Couldn't retrieve y argument" }
- }
- y = result
+ )
+ if (err(result) || 'errors' in result) {
+ return { reason: "Couldn't retrieve y argument" }
}
+ y = result
+ }
- if (operation.labeledArgs.z) {
- const result = await stringToKclExpression(
- codeManager.code.slice(
- operation.labeledArgs.z.sourceRange[0],
- operation.labeledArgs.z.sourceRange[1]
- )
+ if (operation.labeledArgs.z) {
+ const result = await stringToKclExpression(
+ codeManager.code.slice(
+ operation.labeledArgs.z.sourceRange[0],
+ operation.labeledArgs.z.sourceRange[1]
)
- if (err(result) || 'errors' in result) {
- return { reason: "Couldn't retrieve z argument" }
- }
- z = result
+ )
+ if (err(result) || 'errors' in result) {
+ return { reason: "Couldn't retrieve z argument" }
}
+ z = result
+ }
- if (operation.labeledArgs.global) {
- global =
- codeManager.code.slice(
- operation.labeledArgs.global.sourceRange[0],
- operation.labeledArgs.global.sourceRange[1]
- ) === 'true'
- }
+ if (operation.labeledArgs.global) {
+ global =
+ codeManager.code.slice(
+ operation.labeledArgs.global.sourceRange[0],
+ operation.labeledArgs.global.sourceRange[1]
+ ) === 'true'
}
// 3. Assemble the default argument values for the command,
@@ -1615,30 +1612,15 @@ async function prepareToEditTranslate({ operation }: EnterEditFlowProps) {
}
}
-export async function enterTranslateFlow({
- operation,
-}: EnterEditFlowProps): Promise {
- const data = await prepareToEditTranslate({ operation })
- if ('reason' in data) {
- return new Error(data.reason)
- }
-
- return {
- type: 'Find and select command',
- data,
- }
-}
-
async function prepareToEditScale({ operation }: EnterEditFlowProps) {
const baseCommand = {
name: 'Scale',
groupId: 'modeling',
}
- const isModuleImport = operation.type === 'GroupBegin'
const isSupportedStdLibCall =
operation.type === 'StdLibCall' &&
stdLibMap[operation.name]?.supportsTransform
- if (!isModuleImport && !isSupportedStdLibCall) {
+ if (!isSupportedStdLibCall) {
return {
reason: 'Unsupported operation type. Please edit in the code editor.',
}
@@ -1658,53 +1640,51 @@ async function prepareToEditScale({ operation }: EnterEditFlowProps) {
let y: KclCommandValue | undefined = undefined
let z: KclCommandValue | undefined = undefined
let global: boolean | undefined
- if (isSupportedStdLibCall) {
- if (operation.labeledArgs.x) {
- const result = await stringToKclExpression(
- codeManager.code.slice(
- operation.labeledArgs.x.sourceRange[0],
- operation.labeledArgs.x.sourceRange[1]
- )
+ if (operation.labeledArgs.x) {
+ const result = await stringToKclExpression(
+ codeManager.code.slice(
+ operation.labeledArgs.x.sourceRange[0],
+ operation.labeledArgs.x.sourceRange[1]
)
- if (err(result) || 'errors' in result) {
- return { reason: "Couldn't retrieve x argument" }
- }
- x = result
+ )
+ if (err(result) || 'errors' in result) {
+ return { reason: "Couldn't retrieve x argument" }
}
+ x = result
+ }
- if (operation.labeledArgs.y) {
- const result = await stringToKclExpression(
- codeManager.code.slice(
- operation.labeledArgs.y.sourceRange[0],
- operation.labeledArgs.y.sourceRange[1]
- )
+ if (operation.labeledArgs.y) {
+ const result = await stringToKclExpression(
+ codeManager.code.slice(
+ operation.labeledArgs.y.sourceRange[0],
+ operation.labeledArgs.y.sourceRange[1]
)
- if (err(result) || 'errors' in result) {
- return { reason: "Couldn't retrieve y argument" }
- }
- y = result
+ )
+ if (err(result) || 'errors' in result) {
+ return { reason: "Couldn't retrieve y argument" }
}
+ y = result
+ }
- if (operation.labeledArgs.z) {
- const result = await stringToKclExpression(
- codeManager.code.slice(
- operation.labeledArgs.z.sourceRange[0],
- operation.labeledArgs.z.sourceRange[1]
- )
+ if (operation.labeledArgs.z) {
+ const result = await stringToKclExpression(
+ codeManager.code.slice(
+ operation.labeledArgs.z.sourceRange[0],
+ operation.labeledArgs.z.sourceRange[1]
)
- if (err(result) || 'errors' in result) {
- return { reason: "Couldn't retrieve z argument" }
- }
- z = result
+ )
+ if (err(result) || 'errors' in result) {
+ return { reason: "Couldn't retrieve z argument" }
}
+ z = result
+ }
- if (operation.labeledArgs.global) {
- global =
- codeManager.code.slice(
- operation.labeledArgs.global.sourceRange[0],
- operation.labeledArgs.global.sourceRange[1]
- ) === 'true'
- }
+ if (operation.labeledArgs.global) {
+ global =
+ codeManager.code.slice(
+ operation.labeledArgs.global.sourceRange[0],
+ operation.labeledArgs.global.sourceRange[1]
+ ) === 'true'
}
// 3. Assemble the default argument values for the command,
@@ -1724,30 +1704,15 @@ async function prepareToEditScale({ operation }: EnterEditFlowProps) {
}
}
-export async function enterScaleFlow({
- operation,
-}: EnterEditFlowProps): Promise {
- const data = await prepareToEditScale({ operation })
- if ('reason' in data) {
- return new Error(data.reason)
- }
-
- return {
- type: 'Find and select command',
- data,
- }
-}
-
async function prepareToEditRotate({ operation }: EnterEditFlowProps) {
const baseCommand = {
name: 'Rotate',
groupId: 'modeling',
}
- const isModuleImport = operation.type === 'GroupBegin'
const isSupportedStdLibCall =
operation.type === 'StdLibCall' &&
stdLibMap[operation.name]?.supportsTransform
- if (!isModuleImport && !isSupportedStdLibCall) {
+ if (!isSupportedStdLibCall) {
return {
reason: 'Unsupported operation type. Please edit in the code editor.',
}
@@ -1767,53 +1732,51 @@ async function prepareToEditRotate({ operation }: EnterEditFlowProps) {
let pitch: KclCommandValue | undefined = undefined
let yaw: KclCommandValue | undefined = undefined
let global: boolean | undefined
- if (isSupportedStdLibCall) {
- if (operation.labeledArgs.roll) {
- const result = await stringToKclExpression(
- codeManager.code.slice(
- operation.labeledArgs.roll.sourceRange[0],
- operation.labeledArgs.roll.sourceRange[1]
- )
+ if (operation.labeledArgs.roll) {
+ const result = await stringToKclExpression(
+ codeManager.code.slice(
+ operation.labeledArgs.roll.sourceRange[0],
+ operation.labeledArgs.roll.sourceRange[1]
)
- if (err(result) || 'errors' in result) {
- return { reason: "Couldn't retrieve roll argument" }
- }
- roll = result
+ )
+ if (err(result) || 'errors' in result) {
+ return { reason: "Couldn't retrieve roll argument" }
}
+ roll = result
+ }
- if (operation.labeledArgs.pitch) {
- const result = await stringToKclExpression(
- codeManager.code.slice(
- operation.labeledArgs.pitch.sourceRange[0],
- operation.labeledArgs.pitch.sourceRange[1]
- )
+ if (operation.labeledArgs.pitch) {
+ const result = await stringToKclExpression(
+ codeManager.code.slice(
+ operation.labeledArgs.pitch.sourceRange[0],
+ operation.labeledArgs.pitch.sourceRange[1]
)
- if (err(result) || 'errors' in result) {
- return { reason: "Couldn't retrieve pitch argument" }
- }
- pitch = result
+ )
+ if (err(result) || 'errors' in result) {
+ return { reason: "Couldn't retrieve pitch argument" }
}
+ pitch = result
+ }
- if (operation.labeledArgs.yaw) {
- const result = await stringToKclExpression(
- codeManager.code.slice(
- operation.labeledArgs.yaw.sourceRange[0],
- operation.labeledArgs.yaw.sourceRange[1]
- )
+ if (operation.labeledArgs.yaw) {
+ const result = await stringToKclExpression(
+ codeManager.code.slice(
+ operation.labeledArgs.yaw.sourceRange[0],
+ operation.labeledArgs.yaw.sourceRange[1]
)
- if (err(result) || 'errors' in result) {
- return { reason: "Couldn't retrieve yaw argument" }
- }
- yaw = result
+ )
+ if (err(result) || 'errors' in result) {
+ return { reason: "Couldn't retrieve yaw argument" }
}
+ yaw = result
+ }
- if (operation.labeledArgs.global) {
- global =
- codeManager.code.slice(
- operation.labeledArgs.global.sourceRange[0],
- operation.labeledArgs.global.sourceRange[1]
- ) === 'true'
- }
+ if (operation.labeledArgs.global) {
+ global =
+ codeManager.code.slice(
+ operation.labeledArgs.global.sourceRange[0],
+ operation.labeledArgs.global.sourceRange[1]
+ ) === 'true'
}
// 3. Assemble the default argument values for the command,
@@ -1832,45 +1795,3 @@ async function prepareToEditRotate({ operation }: EnterEditFlowProps) {
argDefaultValues,
}
}
-
-export async function enterRotateFlow({
- operation,
-}: EnterEditFlowProps): Promise {
- const data = await prepareToEditRotate({ operation })
- if ('reason' in data) {
- return new Error(data.reason)
- }
-
- return {
- type: 'Find and select command',
- data,
- }
-}
-
-export async function enterCloneFlow({
- operation,
-}: EnterEditFlowProps): Promise {
- const isModuleImport = operation.type === 'GroupBegin'
- const isSupportedStdLibCall =
- operation.type === 'StdLibCall' &&
- stdLibMap[operation.name]?.supportsTransform
- if (!isModuleImport && !isSupportedStdLibCall) {
- return new Error(
- 'Unsupported operation type. Please edit in the code editor.'
- )
- }
-
- const nodeToEdit = pathToNodeFromRustNodePath(operation.nodePath)
-
- // Won't be used since we provide nodeToEdit
- const selection: Selections = { graphSelections: [], otherSelections: [] }
- const argDefaultValues = { nodeToEdit, selection }
- return {
- type: 'Find and select command',
- data: {
- name: 'Clone',
- groupId: 'modeling',
- argDefaultValues,
- },
- }
-}
diff --git a/src/machines/featureTreeMachine.ts b/src/machines/featureTreeMachine.ts
index 42f17ce1b..0320c9207 100644
--- a/src/machines/featureTreeMachine.ts
+++ b/src/machines/featureTreeMachine.ts
@@ -12,14 +12,7 @@ import type { Artifact } from '@src/lang/std/artifactGraph'
import { getArtifactFromRange } from '@src/lang/std/artifactGraph'
import type { SourceRange } from '@src/lang/wasm'
import type { EnterEditFlowProps } from '@src/lib/operations'
-import {
- enterAppearanceFlow,
- enterCloneFlow,
- enterEditFlow,
- enterTranslateFlow,
- enterRotateFlow,
- enterScaleFlow,
-} from '@src/lib/operations'
+import { enterAppearanceFlow, enterEditFlow } from '@src/lib/operations'
import { kclManager } from '@src/lib/singletons'
import { err } from '@src/lib/trap'
import { commandBarActor } from '@src/lib/singletons'
@@ -131,98 +124,6 @@ export const featureTreeMachine = setup({
})
}
),
- prepareTranslateCommand: fromPromise(
- ({
- input,
- }: {
- input: EnterEditFlowProps & {
- commandBarSend: (typeof commandBarActor)['send']
- }
- }) => {
- return new Promise((resolve, reject) => {
- const { commandBarSend, ...editFlowProps } = input
- enterTranslateFlow(editFlowProps)
- .then((result) => {
- if (err(result)) {
- reject(result)
- return
- }
- input.commandBarSend(result)
- resolve(result)
- })
- .catch(reject)
- })
- }
- ),
- prepareRotateCommand: fromPromise(
- ({
- input,
- }: {
- input: EnterEditFlowProps & {
- commandBarSend: (typeof commandBarActor)['send']
- }
- }) => {
- return new Promise((resolve, reject) => {
- const { commandBarSend, ...editFlowProps } = input
- enterRotateFlow(editFlowProps)
- .then((result) => {
- if (err(result)) {
- reject(result)
- return
- }
- input.commandBarSend(result)
- resolve(result)
- })
- .catch(reject)
- })
- }
- ),
- prepareScaleCommand: fromPromise(
- ({
- input,
- }: {
- input: EnterEditFlowProps & {
- commandBarSend: (typeof commandBarActor)['send']
- }
- }) => {
- return new Promise((resolve, reject) => {
- const { commandBarSend, ...editFlowProps } = input
- enterScaleFlow(editFlowProps)
- .then((result) => {
- if (err(result)) {
- reject(result)
- return
- }
- input.commandBarSend(result)
- resolve(result)
- })
- .catch(reject)
- })
- }
- ),
- prepareCloneCommand: fromPromise(
- ({
- input,
- }: {
- input: EnterEditFlowProps & {
- commandBarSend: (typeof commandBarActor)['send']
- }
- }) => {
- return new Promise((resolve, reject) => {
- const { commandBarSend, ...editFlowProps } = input
- enterCloneFlow(editFlowProps)
- .then((result) => {
- if (err(result)) {
- reject(result)
- return
- }
- input.commandBarSend(result)
- resolve(result)
- })
- .catch(reject)
- })
- }
- ),
sendDeleteCommand: fromPromise(
({
input,
@@ -281,6 +182,9 @@ export const featureTreeMachine = setup({
}),
sendSelectionEvent: () => {},
sendTranslateCommand: () => {},
+ sendRotateCommand: () => {},
+ sendScaleCommand: () => {},
+ sendCloneCommand: () => {},
openCodePane: () => {},
scrollToError: () => {},
},
@@ -313,7 +217,7 @@ export const featureTreeMachine = setup({
},
enterTranslateFlow: {
- target: 'enteringTranslateFlow2',
+ target: 'enteringTranslateFlow',
actions: [
'saveTargetSourceRange',
'saveCurrentOperation',
@@ -323,17 +227,29 @@ export const featureTreeMachine = setup({
enterRotateFlow: {
target: 'enteringRotateFlow',
- actions: ['saveTargetSourceRange', 'saveCurrentOperation'],
+ actions: [
+ 'saveTargetSourceRange',
+ 'saveCurrentOperation',
+ 'sendSelectionEvent',
+ ],
},
enterScaleFlow: {
target: 'enteringScaleFlow',
- actions: ['saveTargetSourceRange', 'saveCurrentOperation'],
+ actions: [
+ 'saveTargetSourceRange',
+ 'saveCurrentOperation',
+ 'sendSelectionEvent',
+ ],
},
enterCloneFlow: {
target: 'enteringCloneFlow',
- actions: ['saveTargetSourceRange', 'saveCurrentOperation'],
+ actions: [
+ 'saveTargetSourceRange',
+ 'saveCurrentOperation',
+ 'sendSelectionEvent',
+ ],
},
deleteOperation: {
@@ -393,9 +309,9 @@ export const featureTreeMachine = setup({
initial: 'selecting',
},
- enteringTranslateFlow2: {
+ enteringTranslateFlow: {
states: {
- enteringTranslateFlow2: {
+ enteringTranslateFlow: {
on: {
selected: 'done',
},
@@ -409,7 +325,64 @@ export const featureTreeMachine = setup({
},
},
- initial: 'enteringTranslateFlow2',
+ initial: 'enteringTranslateFlow',
+ },
+
+ enteringRotateFlow: {
+ states: {
+ enteringRotateFlow: {
+ on: {
+ selected: 'done',
+ },
+
+ entry: 'sendRotateCommand',
+ },
+
+ done: {
+ always: '#featureTree.idle',
+ entry: 'clearContext',
+ },
+ },
+
+ initial: 'enteringRotateFlow',
+ },
+
+ enteringScaleFlow: {
+ states: {
+ enteringScaleFlow: {
+ on: {
+ selected: 'done',
+ },
+
+ entry: 'sendScaleCommand',
+ },
+
+ done: {
+ always: '#featureTree.idle',
+ entry: 'clearContext',
+ },
+ },
+
+ initial: 'enteringScaleFlow',
+ },
+
+ enteringCloneFlow: {
+ states: {
+ enteringCloneFlow: {
+ on: {
+ selected: 'done',
+ },
+
+ entry: 'sendCloneCommand',
+ },
+
+ done: {
+ always: '#featureTree.idle',
+ entry: 'clearContext',
+ },
+ },
+
+ initial: 'enteringCloneFlow',
},
enteringEditFlow: {
@@ -520,222 +493,6 @@ export const featureTreeMachine = setup({
exit: ['clearContext'],
},
- enteringTranslateFlow: {
- states: {
- selecting: {
- on: {
- selected: {
- target: 'prepareTranslateCommand',
- reenter: true,
- },
- },
- },
-
- done: {
- always: '#featureTree.idle',
- },
-
- prepareTranslateCommand: {
- invoke: {
- src: 'prepareTranslateCommand',
- input: ({ context }) => {
- const artifact = context.targetSourceRange
- ? (getArtifactFromRange(
- context.targetSourceRange,
- kclManager.artifactGraph
- ) ?? undefined)
- : undefined
- return {
- // currentOperation is guaranteed to be defined here
- operation: context.currentOperation!,
- artifact,
- commandBarSend: commandBarActor.send,
- }
- },
- onDone: {
- target: 'done',
- reenter: true,
- },
- onError: {
- target: 'done',
- reenter: true,
- actions: ({ event }) => {
- if ('error' in event && err(event.error)) {
- toast.error(event.error.message)
- }
- },
- },
- },
- },
- },
-
- initial: 'selecting',
- entry: 'sendSelectionEvent',
- exit: ['clearContext'],
- },
-
- enteringRotateFlow: {
- states: {
- selecting: {
- on: {
- selected: {
- target: 'prepareRotateCommand',
- reenter: true,
- },
- },
- },
-
- done: {
- always: '#featureTree.idle',
- },
-
- prepareRotateCommand: {
- invoke: {
- src: 'prepareRotateCommand',
- input: ({ context }) => {
- const artifact = context.targetSourceRange
- ? (getArtifactFromRange(
- context.targetSourceRange,
- kclManager.artifactGraph
- ) ?? undefined)
- : undefined
- return {
- // currentOperation is guaranteed to be defined here
- operation: context.currentOperation!,
- artifact,
- commandBarSend: commandBarActor.send,
- }
- },
- onDone: {
- target: 'done',
- reenter: true,
- },
- onError: {
- target: 'done',
- reenter: true,
- actions: ({ event }) => {
- if ('error' in event && err(event.error)) {
- toast.error(event.error.message)
- }
- },
- },
- },
- },
- },
-
- initial: 'selecting',
- entry: 'sendSelectionEvent',
- exit: ['clearContext'],
- },
-
- enteringScaleFlow: {
- states: {
- selecting: {
- on: {
- selected: {
- target: 'prepareScaleCommand',
- reenter: true,
- },
- },
- },
-
- done: {
- always: '#featureTree.idle',
- },
-
- prepareScaleCommand: {
- invoke: {
- src: 'prepareScaleCommand',
- input: ({ context }) => {
- const artifact = context.targetSourceRange
- ? (getArtifactFromRange(
- context.targetSourceRange,
- kclManager.artifactGraph
- ) ?? undefined)
- : undefined
- return {
- // currentOperation is guaranteed to be defined here
- operation: context.currentOperation!,
- artifact,
- commandBarSend: commandBarActor.send,
- }
- },
- onDone: {
- target: 'done',
- reenter: true,
- },
- onError: {
- target: 'done',
- reenter: true,
- actions: ({ event }) => {
- if ('error' in event && err(event.error)) {
- toast.error(event.error.message)
- }
- },
- },
- },
- },
- },
-
- initial: 'selecting',
- entry: 'sendSelectionEvent',
- exit: ['clearContext'],
- },
-
- enteringCloneFlow: {
- states: {
- selecting: {
- on: {
- selected: {
- target: 'prepareCloneCommand',
- reenter: true,
- },
- },
- },
-
- done: {
- always: '#featureTree.idle',
- },
-
- prepareCloneCommand: {
- invoke: {
- src: 'prepareCloneCommand',
- input: ({ context }) => {
- const artifact = context.targetSourceRange
- ? (getArtifactFromRange(
- context.targetSourceRange,
- kclManager.artifactGraph
- ) ?? undefined)
- : undefined
- return {
- // currentOperation is guaranteed to be defined here
- operation: context.currentOperation!,
- artifact,
- commandBarSend: commandBarActor.send,
- }
- },
- onDone: {
- target: 'done',
- reenter: true,
- },
- onError: {
- target: 'done',
- reenter: true,
- actions: ({ event }) => {
- if ('error' in event && err(event.error)) {
- toast.error(event.error.message)
- }
- },
- },
- },
- },
- },
-
- initial: 'selecting',
- entry: 'sendSelectionEvent',
- exit: ['clearContext'],
- },
-
deletingOperation: {
states: {
selecting: {
diff --git a/src/machines/modelingMachine.ts b/src/machines/modelingMachine.ts
index 710b53d33..eedfcd5af 100644
--- a/src/machines/modelingMachine.ts
+++ b/src/machines/modelingMachine.ts
@@ -47,7 +47,6 @@ import { angleLengthInfo } from '@src/components/Toolbar/angleLengthInfo'
import { createLiteral, createLocalName } from '@src/lang/create'
import { updateModelingState } from '@src/lang/modelingWorkflows'
import {
- addClone,
addHelix,
addOffsetPlane,
addShell,
@@ -86,7 +85,7 @@ import {
addTranslate,
addRotate,
addScale,
- retrievePathToNodeFromTransformSelection,
+ addClone,
} from '@src/lang/modifyAst/transforms'
import {
getNodeFromPath,
@@ -112,7 +111,6 @@ import type {
Literal,
Name,
PathToNode,
- PipeExpression,
Program,
VariableDeclaration,
VariableDeclarator,
@@ -140,7 +138,6 @@ import {
import type { ToolbarModeName } from '@src/lib/toolbar'
import { err, reportRejection, trap } from '@src/lib/trap'
import { uuidv4 } from '@src/lib/utils'
-import type { ImportStatement } from '@rust/kcl-lib/bindings/ImportStatement'
import { isDesktop } from '@src/lib/isDesktop'
import {
crossProduct,
@@ -3420,58 +3417,14 @@ export const modelingMachine = setup({
}
const ast = kclManager.ast
- const { nodeToEdit, selection, variableName } = input
- let pathToNode = nodeToEdit
- if (!(pathToNode && typeof pathToNode[1][0] === 'number')) {
- const result = retrievePathToNodeFromTransformSelection(
- selection,
- kclManager.artifactGraph,
- ast
- )
- if (err(result)) {
- return Promise.reject(result)
- }
-
- pathToNode = result
- }
-
- const returnEarly = true
- const geometryNode = getNodeFromPath<
- VariableDeclaration | ImportStatement | PipeExpression
- >(
- ast,
- pathToNode,
- ['VariableDeclaration', 'ImportStatement', 'PipeExpression'],
- returnEarly
- )
- if (err(geometryNode)) {
- return Promise.reject(
- new Error("Couldn't find corresponding path to node")
- )
- }
-
- let geometryName: string | undefined
- if (geometryNode.node.type === 'VariableDeclaration') {
- geometryName = geometryNode.node.declaration.id.name
- } else if (
- geometryNode.node.type === 'ImportStatement' &&
- geometryNode.node.selector.type === 'None' &&
- geometryNode.node.selector.alias
- ) {
- geometryName = geometryNode.node.selector.alias?.name
- } else {
- return Promise.reject(
- new Error("Couldn't find corresponding geometry")
- )
- }
-
+ const artifactGraph = kclManager.artifactGraph
const result = addClone({
+ ...input,
ast,
- geometryName,
- variableName,
+ artifactGraph,
})
if (err(result)) {
- return Promise.reject(err(result))
+ return Promise.reject(result)
}
await updateModelingState(