Fix to update the code in the editor before executing (#5976)
* Fix spelling * Fix to update the code in the editor before executing
This commit is contained in:
		@ -123,6 +123,8 @@ import { Node } from '@rust/kcl-lib/bindings/Node'
 | 
			
		||||
import { radToDeg } from 'three/src/math/MathUtils'
 | 
			
		||||
import toast from 'react-hot-toast'
 | 
			
		||||
import { getArtifactFromRange, codeRefFromRange } from 'lang/std/artifactGraph'
 | 
			
		||||
import { updateModelingState } from 'lang/modelingWorkflows'
 | 
			
		||||
import { EXECUTION_TYPE_MOCK } from 'lib/constants'
 | 
			
		||||
 | 
			
		||||
type DraftSegment = 'line' | 'tangentialArcTo'
 | 
			
		||||
 | 
			
		||||
@ -1075,7 +1077,11 @@ export class SceneEntities {
 | 
			
		||||
          return
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        await kclManager.executeAstMock(modifiedAst)
 | 
			
		||||
        await updateModelingState(modifiedAst, EXECUTION_TYPE_MOCK, {
 | 
			
		||||
          kclManager,
 | 
			
		||||
          editorManager,
 | 
			
		||||
          codeManager,
 | 
			
		||||
        })
 | 
			
		||||
 | 
			
		||||
        if (intersectsProfileStart) {
 | 
			
		||||
          sceneInfra.modelingSend({ type: 'Close sketch' })
 | 
			
		||||
@ -1090,8 +1096,6 @@ export class SceneEntities {
 | 
			
		||||
            segmentName
 | 
			
		||||
          )
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        await codeManager.updateEditorWithAstAndWriteToFile(modifiedAst)
 | 
			
		||||
      },
 | 
			
		||||
      onMove: (args) => {
 | 
			
		||||
        const expressionIndex = Number(sketchEntryNodePath[1][0])
 | 
			
		||||
@ -1303,13 +1307,16 @@ export class SceneEntities {
 | 
			
		||||
        _ast = pResult.program
 | 
			
		||||
 | 
			
		||||
        // Update the primary AST and unequip the rectangle tool
 | 
			
		||||
        await kclManager.executeAstMock(_ast)
 | 
			
		||||
        sceneInfra.modelingSend({ type: 'Finish rectangle' })
 | 
			
		||||
 | 
			
		||||
        //
 | 
			
		||||
        // lee: I had this at the bottom of the function, but it's
 | 
			
		||||
        // possible sketchFromKclValue "fails" when sketching on a face,
 | 
			
		||||
        // and this couldn't wouldn't run.
 | 
			
		||||
        await codeManager.updateEditorWithAstAndWriteToFile(_ast)
 | 
			
		||||
        await updateModelingState(_ast, EXECUTION_TYPE_MOCK, {
 | 
			
		||||
          kclManager,
 | 
			
		||||
          editorManager,
 | 
			
		||||
          codeManager,
 | 
			
		||||
        })
 | 
			
		||||
        sceneInfra.modelingSend({ type: 'Finish rectangle' })
 | 
			
		||||
      },
 | 
			
		||||
    })
 | 
			
		||||
    return {
 | 
			
		||||
@ -1493,13 +1500,16 @@ export class SceneEntities {
 | 
			
		||||
          _ast = pResult.program
 | 
			
		||||
 | 
			
		||||
          // Update the primary AST and unequip the rectangle tool
 | 
			
		||||
          await kclManager.executeAstMock(_ast)
 | 
			
		||||
          sceneInfra.modelingSend({ type: 'Finish center rectangle' })
 | 
			
		||||
 | 
			
		||||
          //
 | 
			
		||||
          // lee: I had this at the bottom of the function, but it's
 | 
			
		||||
          // possible sketchFromKclValue "fails" when sketching on a face,
 | 
			
		||||
          // and this couldn't wouldn't run.
 | 
			
		||||
          await codeManager.updateEditorWithAstAndWriteToFile(_ast)
 | 
			
		||||
          await updateModelingState(_ast, EXECUTION_TYPE_MOCK, {
 | 
			
		||||
            kclManager,
 | 
			
		||||
            editorManager,
 | 
			
		||||
            codeManager,
 | 
			
		||||
          })
 | 
			
		||||
          sceneInfra.modelingSend({ type: 'Finish center rectangle' })
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
    })
 | 
			
		||||
@ -1678,9 +1688,12 @@ export class SceneEntities {
 | 
			
		||||
          _ast = pResult.program
 | 
			
		||||
 | 
			
		||||
          // Update the primary AST and unequip the rectangle tool
 | 
			
		||||
          await kclManager.executeAstMock(_ast)
 | 
			
		||||
          await updateModelingState(_ast, EXECUTION_TYPE_MOCK, {
 | 
			
		||||
            kclManager,
 | 
			
		||||
            editorManager,
 | 
			
		||||
            codeManager,
 | 
			
		||||
          })
 | 
			
		||||
          sceneInfra.modelingSend({ type: 'Finish circle three point' })
 | 
			
		||||
          await codeManager.updateEditorWithAstAndWriteToFile(_ast)
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
    })
 | 
			
		||||
@ -1912,9 +1925,12 @@ export class SceneEntities {
 | 
			
		||||
          _ast = pResult.program
 | 
			
		||||
 | 
			
		||||
          // Update the primary AST and unequip the arc tool
 | 
			
		||||
          await kclManager.executeAstMock(_ast)
 | 
			
		||||
          await updateModelingState(_ast, EXECUTION_TYPE_MOCK, {
 | 
			
		||||
            kclManager,
 | 
			
		||||
            editorManager,
 | 
			
		||||
            codeManager,
 | 
			
		||||
          })
 | 
			
		||||
          sceneInfra.modelingSend({ type: 'Finish arc' })
 | 
			
		||||
          await codeManager.updateEditorWithAstAndWriteToFile(_ast)
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
    })
 | 
			
		||||
@ -2166,13 +2182,16 @@ export class SceneEntities {
 | 
			
		||||
          _ast = pResult.program
 | 
			
		||||
 | 
			
		||||
          // Update the primary AST and unequip the arc tool
 | 
			
		||||
          await kclManager.executeAstMock(_ast)
 | 
			
		||||
          await updateModelingState(_ast, EXECUTION_TYPE_MOCK, {
 | 
			
		||||
            kclManager,
 | 
			
		||||
            editorManager,
 | 
			
		||||
            codeManager,
 | 
			
		||||
          })
 | 
			
		||||
          if (intersectsProfileStart) {
 | 
			
		||||
            sceneInfra.modelingSend({ type: 'Close sketch' })
 | 
			
		||||
          } else {
 | 
			
		||||
            sceneInfra.modelingSend({ type: 'Finish arc' })
 | 
			
		||||
          }
 | 
			
		||||
          await codeManager.updateEditorWithAstAndWriteToFile(_ast)
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
    })
 | 
			
		||||
@ -2364,9 +2383,12 @@ export class SceneEntities {
 | 
			
		||||
          _ast = pResult.program
 | 
			
		||||
 | 
			
		||||
          // Update the primary AST and unequip the rectangle tool
 | 
			
		||||
          await kclManager.executeAstMock(_ast)
 | 
			
		||||
          await updateModelingState(_ast, EXECUTION_TYPE_MOCK, {
 | 
			
		||||
            kclManager,
 | 
			
		||||
            editorManager,
 | 
			
		||||
            codeManager,
 | 
			
		||||
          })
 | 
			
		||||
          sceneInfra.modelingSend({ type: 'Finish circle' })
 | 
			
		||||
          await codeManager.updateEditorWithAstAndWriteToFile(_ast)
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
    })
 | 
			
		||||
 | 
			
		||||
@ -119,6 +119,8 @@ import { EXPORT_TOAST_MESSAGES, MAKE_TOAST_MESSAGES } from 'lib/constants'
 | 
			
		||||
import { exportMake } from 'lib/exportMake'
 | 
			
		||||
import { exportSave } from 'lib/exportSave'
 | 
			
		||||
import { Plane } from '@rust/kcl-lib/bindings/Plane'
 | 
			
		||||
import { updateModelingState } from 'lang/modelingWorkflows'
 | 
			
		||||
import { EXECUTION_TYPE_MOCK } from 'lib/constants'
 | 
			
		||||
 | 
			
		||||
export const ModelingMachineContext = createContext(
 | 
			
		||||
  {} as {
 | 
			
		||||
@ -1660,7 +1662,7 @@ export const ModelingMachineProvider = ({
 | 
			
		||||
              sketchDetails.sketchEntryNodePath
 | 
			
		||||
            )
 | 
			
		||||
            if (err(doesNeedSplitting)) return reject(doesNeedSplitting)
 | 
			
		||||
            let moddedAst: Program = structuredClone(kclManager.ast)
 | 
			
		||||
            let moddedAst: Node<Program> = structuredClone(kclManager.ast)
 | 
			
		||||
            let pathToProfile = sketchDetails.sketchEntryNodePath
 | 
			
		||||
            let updatedSketchNodePaths = sketchDetails.sketchNodePaths
 | 
			
		||||
            if (doesNeedSplitting) {
 | 
			
		||||
@ -1722,8 +1724,11 @@ export const ModelingMachineProvider = ({
 | 
			
		||||
              indexToDelete >= 0 ||
 | 
			
		||||
              isLastInPipeThreePointArc
 | 
			
		||||
            ) {
 | 
			
		||||
              await kclManager.executeAstMock(moddedAst)
 | 
			
		||||
              await codeManager.updateEditorWithAstAndWriteToFile(moddedAst)
 | 
			
		||||
              await updateModelingState(moddedAst, EXECUTION_TYPE_MOCK, {
 | 
			
		||||
                kclManager,
 | 
			
		||||
                editorManager,
 | 
			
		||||
                codeManager,
 | 
			
		||||
              })
 | 
			
		||||
            }
 | 
			
		||||
            return {
 | 
			
		||||
              updatedEntryNodePath: pathToProfile,
 | 
			
		||||
 | 
			
		||||
@ -2,12 +2,12 @@ import { executeAst, executeAstMock, lintAst } from 'lang/langHelpers'
 | 
			
		||||
import { handleSelectionBatch, Selections } from 'lib/selections'
 | 
			
		||||
import {
 | 
			
		||||
  KCLError,
 | 
			
		||||
  complilationErrorsToDiagnostics,
 | 
			
		||||
  compilationErrorsToDiagnostics,
 | 
			
		||||
  kclErrorsToDiagnostics,
 | 
			
		||||
} from './errors'
 | 
			
		||||
import { uuidv4 } from 'lib/utils'
 | 
			
		||||
import { EngineCommandManager } from './std/engineConnection'
 | 
			
		||||
import { err } from 'lib/trap'
 | 
			
		||||
import { err, reportRejection } from 'lib/trap'
 | 
			
		||||
import { EXECUTE_AST_INTERRUPT_ERROR_MESSAGE } from 'lib/constants'
 | 
			
		||||
 | 
			
		||||
import {
 | 
			
		||||
@ -295,8 +295,8 @@ export class KclManager {
 | 
			
		||||
    this._astParseFailed = false
 | 
			
		||||
 | 
			
		||||
    if (err(result)) {
 | 
			
		||||
      const kclerror: KCLError = result as KCLError
 | 
			
		||||
      this.diagnostics = kclErrorsToDiagnostics([kclerror])
 | 
			
		||||
      const kclError: KCLError = result as KCLError
 | 
			
		||||
      this.diagnostics = kclErrorsToDiagnostics([kclError])
 | 
			
		||||
      this._astParseFailed = true
 | 
			
		||||
 | 
			
		||||
      await this.checkIfSwitchedFilesShouldClear()
 | 
			
		||||
@ -310,8 +310,8 @@ export class KclManager {
 | 
			
		||||
    this._kclErrorsCallBack([])
 | 
			
		||||
    this._logsCallBack([])
 | 
			
		||||
 | 
			
		||||
    this.addDiagnostics(complilationErrorsToDiagnostics(result.errors))
 | 
			
		||||
    this.addDiagnostics(complilationErrorsToDiagnostics(result.warnings))
 | 
			
		||||
    this.addDiagnostics(compilationErrorsToDiagnostics(result.errors))
 | 
			
		||||
    this.addDiagnostics(compilationErrorsToDiagnostics(result.warnings))
 | 
			
		||||
    if (result.errors.length > 0) {
 | 
			
		||||
      this._astParseFailed = true
 | 
			
		||||
 | 
			
		||||
@ -337,8 +337,8 @@ export class KclManager {
 | 
			
		||||
  private _cancelTokens: Map<number, boolean> = new Map()
 | 
			
		||||
 | 
			
		||||
  // This NEVER updates the code, if you want to update the code DO NOT add to
 | 
			
		||||
  // this function, too many other things that don't want it exist.
 | 
			
		||||
  // just call to codeManager from wherever you want in other files.
 | 
			
		||||
  // this function, too many other things that don't want it exist. For that,
 | 
			
		||||
  // use updateModelingState().
 | 
			
		||||
  async executeAst(args: ExecuteArgs = {}): Promise<void> {
 | 
			
		||||
    if (this.isExecuting) {
 | 
			
		||||
      this.executeIsStale = args
 | 
			
		||||
@ -420,7 +420,7 @@ export class KclManager {
 | 
			
		||||
    this.addDiagnostics(isInterrupted ? [] : kclErrorsToDiagnostics(errors))
 | 
			
		||||
    // Add warnings and non-fatal errors
 | 
			
		||||
    this.addDiagnostics(
 | 
			
		||||
      isInterrupted ? [] : complilationErrorsToDiagnostics(execState.errors)
 | 
			
		||||
      isInterrupted ? [] : compilationErrorsToDiagnostics(execState.errors)
 | 
			
		||||
    )
 | 
			
		||||
    this.execState = execState
 | 
			
		||||
    if (!errors.length) {
 | 
			
		||||
@ -460,7 +460,6 @@ export class KclManager {
 | 
			
		||||
    markOnce('code/endExecuteAst')
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // NOTE: this always updates the code state and editor.
 | 
			
		||||
  // DO NOT CALL THIS from codemirror ever.
 | 
			
		||||
  async executeAstMock(ast: Program) {
 | 
			
		||||
    await this.ensureWasmInit()
 | 
			
		||||
@ -472,7 +471,7 @@ export class KclManager {
 | 
			
		||||
    }
 | 
			
		||||
    const newAst = await this.safeParse(newCode)
 | 
			
		||||
    if (!newAst) {
 | 
			
		||||
      // By clearning the AST we indicate to our callers that there was an issue with execution and
 | 
			
		||||
      // By clearing the AST we indicate to our callers that there was an issue with execution and
 | 
			
		||||
      // the pre-execution state should be restored.
 | 
			
		||||
      this.clearAst()
 | 
			
		||||
      return
 | 
			
		||||
@ -501,7 +500,7 @@ export class KclManager {
 | 
			
		||||
    const ast = await this.safeParse(codeManager.code)
 | 
			
		||||
 | 
			
		||||
    if (!ast) {
 | 
			
		||||
      // By clearning the AST we indicate to our callers that there was an issue with execution and
 | 
			
		||||
      // By clearing the AST we indicate to our callers that there was an issue with execution and
 | 
			
		||||
      // the pre-execution state should be restored.
 | 
			
		||||
      this.clearAst()
 | 
			
		||||
      return
 | 
			
		||||
@ -516,8 +515,8 @@ export class KclManager {
 | 
			
		||||
   * This will override the zoom to fit to zoom into the model if the previous AST was empty.
 | 
			
		||||
   * Workflows this improves,
 | 
			
		||||
   *  When someone comments the entire file then uncomments the entire file it zooms to the model
 | 
			
		||||
   *  When someone CRTL+A and deletes the code then adds the code back it zooms to the model
 | 
			
		||||
   *  When someone CRTL+A and copies new code into the editor it zooms to the model
 | 
			
		||||
   *  When someone CTRL+A and deletes the code then adds the code back it zooms to the model
 | 
			
		||||
   *  When someone CTRL+A and copies new code into the editor it zooms to the model
 | 
			
		||||
   */
 | 
			
		||||
  tryToZoomToFitOnCodeUpdate(
 | 
			
		||||
    ast: Node<Program>,
 | 
			
		||||
@ -555,12 +554,16 @@ export class KclManager {
 | 
			
		||||
    codeManager.updateCodeStateEditor(code)
 | 
			
		||||
 | 
			
		||||
    // Write back to the file system.
 | 
			
		||||
    void codeManager.writeToFile().then(() => this.executeCode())
 | 
			
		||||
    void codeManager
 | 
			
		||||
      .writeToFile()
 | 
			
		||||
      .then(() => this.executeCode())
 | 
			
		||||
      .catch(reportRejection)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // There's overlapping responsibility between updateAst and executeAst.
 | 
			
		||||
  // updateAst was added as it was used a lot before xState migration so makes the port easier.
 | 
			
		||||
  // but should probably have think about which of the function to keep
 | 
			
		||||
  // This always updates the code state and editor and writes to the file system.
 | 
			
		||||
  // This never updates the code state or editor and doesn't write to the file system.
 | 
			
		||||
  async updateAst(
 | 
			
		||||
    ast: Node<Program>,
 | 
			
		||||
    execute: boolean,
 | 
			
		||||
@ -627,7 +630,6 @@ export class KclManager {
 | 
			
		||||
      // When we don't re-execute, we still want to update the program
 | 
			
		||||
      // memory with the new ast. So we will hit the mock executor
 | 
			
		||||
      // instead..
 | 
			
		||||
      // Execute ast mock will update the code state and editor.
 | 
			
		||||
      await this.executeAstMock(astWithUpdatedSource)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -165,10 +165,11 @@ export default class CodeManager {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  async updateEditorWithAstAndWriteToFile(ast: Program) {
 | 
			
		||||
    // We clear the AST when there it cannot be parsed, so if we are trying to write an empty AST, its
 | 
			
		||||
    // probably because of an earlier error. That's a bad state to be in and it's not going to be
 | 
			
		||||
    // pretty, but at the least, lets not permanently delete the user's code.
 | 
			
		||||
    // If you want to clear the scene, call updateCodeStateEditor directly.
 | 
			
		||||
    // We clear the AST when it cannot be parsed. If we are trying to write an
 | 
			
		||||
    // empty AST, it's probably because of an earlier error. That's a bad state
 | 
			
		||||
    // to be in, and it's not going to be pretty, but at the least, let's not
 | 
			
		||||
    // permanently delete the user's code. If you want to clear the scene, call
 | 
			
		||||
    // updateCodeStateEditor directly.
 | 
			
		||||
    if (ast.body.length === 0) return
 | 
			
		||||
    const newCode = recast(ast)
 | 
			
		||||
    if (err(newCode)) return
 | 
			
		||||
 | 
			
		||||
@ -320,7 +320,7 @@ export function kclErrorsToDiagnostics(
 | 
			
		||||
    })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function complilationErrorsToDiagnostics(
 | 
			
		||||
export function compilationErrorsToDiagnostics(
 | 
			
		||||
  errors: CompilationError[]
 | 
			
		||||
): CodeMirrorDiagnostic[] {
 | 
			
		||||
  return errors
 | 
			
		||||
 | 
			
		||||
@ -8,6 +8,12 @@
 | 
			
		||||
 | 
			
		||||
import { Node } from '@rust/kcl-lib/bindings/Node'
 | 
			
		||||
import { KclManager } from 'lang/KclSingleton'
 | 
			
		||||
import { ExecutionType } from 'lib/constants'
 | 
			
		||||
import {
 | 
			
		||||
  EXECUTION_TYPE_MOCK,
 | 
			
		||||
  EXECUTION_TYPE_NONE,
 | 
			
		||||
  EXECUTION_TYPE_REAL,
 | 
			
		||||
} from 'lib/constants'
 | 
			
		||||
import { PathToNode, Program, SourceRange } from 'lang/wasm'
 | 
			
		||||
import EditorManager from 'editor/manager'
 | 
			
		||||
import CodeManager from 'lang/codeManager'
 | 
			
		||||
@ -32,12 +38,13 @@ import CodeManager from 'lang/codeManager'
 | 
			
		||||
 * regardless of geometric validity issues.
 | 
			
		||||
 *
 | 
			
		||||
 * @param ast - AST to commit
 | 
			
		||||
 * @param executionType - How to execute the AST
 | 
			
		||||
 * @param dependencies - Required system components
 | 
			
		||||
 * @param options - Optional parameters for focus, zoom, etc.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
export async function updateModelingState(
 | 
			
		||||
  ast: Node<Program>,
 | 
			
		||||
  executionType: ExecutionType,
 | 
			
		||||
  dependencies: {
 | 
			
		||||
    kclManager: KclManager
 | 
			
		||||
    editorManager: EditorManager
 | 
			
		||||
@ -55,6 +62,7 @@ export async function updateModelingState(
 | 
			
		||||
  // Step 1: Update AST without executing (prepare selections)
 | 
			
		||||
  const updatedAst = await dependencies.kclManager.updateAst(
 | 
			
		||||
    ast,
 | 
			
		||||
    // false == mock execution. Is this what we want?
 | 
			
		||||
    false, // Execution handled separately for error resilience
 | 
			
		||||
    options
 | 
			
		||||
  )
 | 
			
		||||
@ -69,14 +77,20 @@ export async function updateModelingState(
 | 
			
		||||
    dependencies.editorManager.selectRange(updatedAst.selections)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Step 4: Try to execute the new code in the engine
 | 
			
		||||
  // Step 4: Try to execute the new code
 | 
			
		||||
  // and continue regardless of errors
 | 
			
		||||
  try {
 | 
			
		||||
    await dependencies.kclManager.executeAst({
 | 
			
		||||
      ast: updatedAst.newAst,
 | 
			
		||||
      zoomToFit: options?.zoomToFit,
 | 
			
		||||
      zoomOnRangeAndType: options?.zoomOnRangeAndType,
 | 
			
		||||
    })
 | 
			
		||||
    if (executionType === EXECUTION_TYPE_REAL) {
 | 
			
		||||
      await dependencies.kclManager.executeAst({
 | 
			
		||||
        ast: updatedAst.newAst,
 | 
			
		||||
        zoomToFit: options?.zoomToFit,
 | 
			
		||||
        zoomOnRangeAndType: options?.zoomOnRangeAndType,
 | 
			
		||||
      })
 | 
			
		||||
    } else if (executionType === EXECUTION_TYPE_MOCK) {
 | 
			
		||||
      await dependencies.kclManager.executeAstMock(updatedAst.newAst)
 | 
			
		||||
    } else if (executionType === EXECUTION_TYPE_NONE) {
 | 
			
		||||
      // No execution.
 | 
			
		||||
    }
 | 
			
		||||
  } catch (e) {
 | 
			
		||||
    console.error('Engine execution error (UI is still updated):', e)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -673,7 +673,7 @@ export function sketchOnExtrudedFace(
 | 
			
		||||
  sketchPathToNode: PathToNode,
 | 
			
		||||
  extrudePathToNode: PathToNode,
 | 
			
		||||
  info: ExtrudeFacePlane['faceInfo'] = { type: 'wall' }
 | 
			
		||||
): { modifiedAst: Program; pathToNode: PathToNode } | Error {
 | 
			
		||||
): { modifiedAst: Node<Program>; pathToNode: PathToNode } | Error {
 | 
			
		||||
  let _node = { ...node }
 | 
			
		||||
  const newSketchName = findUniqueName(
 | 
			
		||||
    node,
 | 
			
		||||
@ -1375,7 +1375,7 @@ export function moveValueIntoNewVariablePath(
 | 
			
		||||
  pathToNode: PathToNode,
 | 
			
		||||
  variableName: string
 | 
			
		||||
): {
 | 
			
		||||
  modifiedAst: Program
 | 
			
		||||
  modifiedAst: Node<Program>
 | 
			
		||||
  pathToReplacedNode?: PathToNode
 | 
			
		||||
} {
 | 
			
		||||
  const meta = isNodeSafeToReplacePath(ast, pathToNode)
 | 
			
		||||
@ -1975,11 +1975,11 @@ making it safe for later code that uses part001 (the extrude in this example)
 | 
			
		||||
 * 
 | 
			
		||||
 */
 | 
			
		||||
export function splitPipedProfile(
 | 
			
		||||
  ast: Program,
 | 
			
		||||
  ast: Node<Program>,
 | 
			
		||||
  pathToPipe: PathToNode
 | 
			
		||||
):
 | 
			
		||||
  | {
 | 
			
		||||
      modifiedAst: Program
 | 
			
		||||
      modifiedAst: Node<Program>
 | 
			
		||||
      pathToProfile: PathToNode
 | 
			
		||||
      pathToPlane: PathToNode
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -39,6 +39,7 @@ import { Artifact, getSweepArtifactFromSelection } from 'lang/std/artifactGraph'
 | 
			
		||||
import { Node } from '@rust/kcl-lib/bindings/Node'
 | 
			
		||||
import { findKwArg } from 'lang/util'
 | 
			
		||||
import { KclManager } from 'lang/KclSingleton'
 | 
			
		||||
import { EXECUTION_TYPE_REAL } from 'lib/constants'
 | 
			
		||||
import { EngineCommandManager } from 'lang/std/engineConnection'
 | 
			
		||||
import EditorManager from 'editor/manager'
 | 
			
		||||
import CodeManager from 'lang/codeManager'
 | 
			
		||||
@ -86,6 +87,7 @@ export async function applyEdgeTreatmentToSelection(
 | 
			
		||||
  // 2. update ast
 | 
			
		||||
  await updateModelingState(
 | 
			
		||||
    modifiedAst,
 | 
			
		||||
    EXECUTION_TYPE_REAL,
 | 
			
		||||
    {
 | 
			
		||||
      kclManager: dependencies.kclManager,
 | 
			
		||||
      editorManager: dependencies.editorManager,
 | 
			
		||||
 | 
			
		||||
@ -3,12 +3,15 @@ import { getFaceDetails } from 'clientSideScene/sceneEntities'
 | 
			
		||||
import { deleteFromSelection } from 'lang/modifyAst'
 | 
			
		||||
import {
 | 
			
		||||
  codeManager,
 | 
			
		||||
  editorManager,
 | 
			
		||||
  engineCommandManager,
 | 
			
		||||
  kclManager,
 | 
			
		||||
  rustContext,
 | 
			
		||||
} from 'lib/singletons'
 | 
			
		||||
import { err } from 'lib/trap'
 | 
			
		||||
import { executeAstMock } from 'lang/langHelpers'
 | 
			
		||||
import { updateModelingState } from 'lang/modelingWorkflows'
 | 
			
		||||
import { EXECUTION_TYPE_REAL } from 'lib/constants'
 | 
			
		||||
 | 
			
		||||
export const deletionErrorMessage =
 | 
			
		||||
  'Unable to delete selection. Please edit manually in code pane.'
 | 
			
		||||
@ -36,7 +39,9 @@ export async function deleteSelectionPromise(
 | 
			
		||||
  if (testExecute.errors.length) {
 | 
			
		||||
    return new Error(deletionErrorMessage)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  await kclManager.updateAst(modifiedAst, true)
 | 
			
		||||
  await codeManager.updateEditorWithAstAndWriteToFile(modifiedAst)
 | 
			
		||||
  await updateModelingState(modifiedAst, EXECUTION_TYPE_REAL, {
 | 
			
		||||
    kclManager,
 | 
			
		||||
    editorManager,
 | 
			
		||||
    codeManager,
 | 
			
		||||
  })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -167,3 +167,17 @@ export const ZOO_STUDIO_PROTOCOL = 'zoo-studio'
 | 
			
		||||
 * to "open in desktop app" when present in the URL
 | 
			
		||||
 */
 | 
			
		||||
export const ASK_TO_OPEN_QUERY_PARAM = 'ask-open-desktop'
 | 
			
		||||
 | 
			
		||||
/** Real execution. */
 | 
			
		||||
export const EXECUTION_TYPE_REAL = 'real' as const
 | 
			
		||||
/** Mock execution. */
 | 
			
		||||
export const EXECUTION_TYPE_MOCK = 'mock' as const
 | 
			
		||||
/** No execution. */
 | 
			
		||||
export const EXECUTION_TYPE_NONE = 'none' as const
 | 
			
		||||
/**
 | 
			
		||||
 * Enum of engine execution kinds.
 | 
			
		||||
 */
 | 
			
		||||
export type ExecutionType =
 | 
			
		||||
  | typeof EXECUTION_TYPE_REAL
 | 
			
		||||
  | typeof EXECUTION_TYPE_MOCK
 | 
			
		||||
  | typeof EXECUTION_TYPE_NONE
 | 
			
		||||
 | 
			
		||||
@ -102,6 +102,7 @@ import { setAppearance } from 'lang/modifyAst/setAppearance'
 | 
			
		||||
import { DRAFT_DASHED_LINE } from 'clientSideScene/sceneEntities'
 | 
			
		||||
import { Node } from '@rust/kcl-lib/bindings/Node'
 | 
			
		||||
import { updateModelingState } from 'lang/modelingWorkflows'
 | 
			
		||||
import { EXECUTION_TYPE_REAL } from 'lib/constants'
 | 
			
		||||
 | 
			
		||||
export const MODELING_PERSIST_KEY = 'MODELING_PERSIST_KEY'
 | 
			
		||||
 | 
			
		||||
@ -751,20 +752,23 @@ export const modelingMachine = setup({
 | 
			
		||||
        if (trap(revolveSketchRes)) return
 | 
			
		||||
        const { modifiedAst, pathToRevolveArg } = revolveSketchRes
 | 
			
		||||
 | 
			
		||||
        const updatedAst = await kclManager.updateAst(modifiedAst, true, {
 | 
			
		||||
          focusPath: [pathToRevolveArg],
 | 
			
		||||
          zoomToFit: true,
 | 
			
		||||
          zoomOnRangeAndType: {
 | 
			
		||||
            range: selection.graphSelections[0]?.codeRef.range,
 | 
			
		||||
            type: 'path',
 | 
			
		||||
        await updateModelingState(
 | 
			
		||||
          modifiedAst,
 | 
			
		||||
          EXECUTION_TYPE_REAL,
 | 
			
		||||
          {
 | 
			
		||||
            kclManager,
 | 
			
		||||
            editorManager,
 | 
			
		||||
            codeManager,
 | 
			
		||||
          },
 | 
			
		||||
        })
 | 
			
		||||
 | 
			
		||||
        await codeManager.updateEditorWithAstAndWriteToFile(updatedAst.newAst)
 | 
			
		||||
 | 
			
		||||
        if (updatedAst?.selections) {
 | 
			
		||||
          editorManager.selectRange(updatedAst?.selections)
 | 
			
		||||
        }
 | 
			
		||||
          {
 | 
			
		||||
            focusPath: [pathToRevolveArg],
 | 
			
		||||
            zoomToFit: true,
 | 
			
		||||
            zoomOnRangeAndType: {
 | 
			
		||||
              range: selection.graphSelections[0]?.codeRef.range,
 | 
			
		||||
              type: 'path',
 | 
			
		||||
            },
 | 
			
		||||
          }
 | 
			
		||||
        )
 | 
			
		||||
      })().catch(reportRejection)
 | 
			
		||||
    },
 | 
			
		||||
    'set selection filter to curves only': () => {
 | 
			
		||||
@ -1797,20 +1801,23 @@ export const modelingMachine = setup({
 | 
			
		||||
        pathToExtrudeArg[1][0]++
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      const updatedAst = await kclManager.updateAst(modifiedAst, true, {
 | 
			
		||||
        focusPath: [pathToExtrudeArg],
 | 
			
		||||
        zoomToFit: true,
 | 
			
		||||
        zoomOnRangeAndType: {
 | 
			
		||||
          range: selection.graphSelections[0]?.codeRef.range,
 | 
			
		||||
          type: 'path',
 | 
			
		||||
      await updateModelingState(
 | 
			
		||||
        modifiedAst,
 | 
			
		||||
        EXECUTION_TYPE_REAL,
 | 
			
		||||
        {
 | 
			
		||||
          kclManager,
 | 
			
		||||
          editorManager,
 | 
			
		||||
          codeManager,
 | 
			
		||||
        },
 | 
			
		||||
      })
 | 
			
		||||
 | 
			
		||||
      await codeManager.updateEditorWithAstAndWriteToFile(updatedAst.newAst)
 | 
			
		||||
 | 
			
		||||
      if (updatedAst?.selections) {
 | 
			
		||||
        editorManager.selectRange(updatedAst?.selections)
 | 
			
		||||
      }
 | 
			
		||||
        {
 | 
			
		||||
          focusPath: [pathToExtrudeArg],
 | 
			
		||||
          zoomToFit: true,
 | 
			
		||||
          zoomOnRangeAndType: {
 | 
			
		||||
            range: selection.graphSelections[0]?.codeRef.range,
 | 
			
		||||
            type: 'path',
 | 
			
		||||
          },
 | 
			
		||||
        }
 | 
			
		||||
      )
 | 
			
		||||
    }),
 | 
			
		||||
    offsetPlaneAstMod: fromPromise(
 | 
			
		||||
      async ({
 | 
			
		||||
@ -1880,21 +1887,18 @@ export const modelingMachine = setup({
 | 
			
		||||
          offsetPlaneResult.pathToNode[1][0]++
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        const updateAstResult = await kclManager.updateAst(
 | 
			
		||||
        await updateModelingState(
 | 
			
		||||
          offsetPlaneResult.modifiedAst,
 | 
			
		||||
          true,
 | 
			
		||||
          EXECUTION_TYPE_REAL,
 | 
			
		||||
          {
 | 
			
		||||
            kclManager,
 | 
			
		||||
            editorManager,
 | 
			
		||||
            codeManager,
 | 
			
		||||
          },
 | 
			
		||||
          {
 | 
			
		||||
            focusPath: [offsetPlaneResult.pathToNode],
 | 
			
		||||
          }
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        await codeManager.updateEditorWithAstAndWriteToFile(
 | 
			
		||||
          updateAstResult.newAst
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        if (updateAstResult?.selections) {
 | 
			
		||||
          editorManager.selectRange(updateAstResult?.selections)
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    ),
 | 
			
		||||
    helixAstMod: fromPromise(
 | 
			
		||||
@ -1995,6 +1999,7 @@ export const modelingMachine = setup({
 | 
			
		||||
        })
 | 
			
		||||
        await updateModelingState(
 | 
			
		||||
          modifiedAst,
 | 
			
		||||
          EXECUTION_TYPE_REAL,
 | 
			
		||||
          {
 | 
			
		||||
            kclManager,
 | 
			
		||||
            editorManager,
 | 
			
		||||
@ -2088,6 +2093,7 @@ export const modelingMachine = setup({
 | 
			
		||||
        })
 | 
			
		||||
        await updateModelingState(
 | 
			
		||||
          modifiedAst,
 | 
			
		||||
          EXECUTION_TYPE_REAL,
 | 
			
		||||
          {
 | 
			
		||||
            kclManager,
 | 
			
		||||
            editorManager,
 | 
			
		||||
@ -2126,21 +2132,18 @@ export const modelingMachine = setup({
 | 
			
		||||
 | 
			
		||||
        // Perform the loft
 | 
			
		||||
        const loftSketchesRes = loftSketches(ast, declarators)
 | 
			
		||||
        const updateAstResult = await kclManager.updateAst(
 | 
			
		||||
        await updateModelingState(
 | 
			
		||||
          loftSketchesRes.modifiedAst,
 | 
			
		||||
          true,
 | 
			
		||||
          EXECUTION_TYPE_REAL,
 | 
			
		||||
          {
 | 
			
		||||
            kclManager,
 | 
			
		||||
            editorManager,
 | 
			
		||||
            codeManager,
 | 
			
		||||
          },
 | 
			
		||||
          {
 | 
			
		||||
            focusPath: [loftSketchesRes.pathToNode],
 | 
			
		||||
          }
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        await codeManager.updateEditorWithAstAndWriteToFile(
 | 
			
		||||
          updateAstResult.newAst
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        if (updateAstResult?.selections) {
 | 
			
		||||
          editorManager.selectRange(updateAstResult?.selections)
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    ),
 | 
			
		||||
    shellAstMod: fromPromise(
 | 
			
		||||
@ -2306,21 +2309,18 @@ export const modelingMachine = setup({
 | 
			
		||||
          addResult.pathToNode[1][0]++
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        const updateAstResult = await kclManager.updateAst(
 | 
			
		||||
        await updateModelingState(
 | 
			
		||||
          addResult.modifiedAst,
 | 
			
		||||
          true,
 | 
			
		||||
          EXECUTION_TYPE_REAL,
 | 
			
		||||
          {
 | 
			
		||||
            kclManager,
 | 
			
		||||
            editorManager,
 | 
			
		||||
            codeManager,
 | 
			
		||||
          },
 | 
			
		||||
          {
 | 
			
		||||
            focusPath: [addResult.pathToNode],
 | 
			
		||||
          }
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        await codeManager.updateEditorWithAstAndWriteToFile(
 | 
			
		||||
          updateAstResult.newAst
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        if (updateAstResult?.selections) {
 | 
			
		||||
          editorManager.selectRange(updateAstResult?.selections)
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    ),
 | 
			
		||||
    filletAstMod: fromPromise(
 | 
			
		||||
@ -2372,15 +2372,11 @@ export const modelingMachine = setup({
 | 
			
		||||
          node: kclManager.ast,
 | 
			
		||||
          newExpression: value,
 | 
			
		||||
        })
 | 
			
		||||
        const updateAstResult = await kclManager.updateAst(newAst, true)
 | 
			
		||||
 | 
			
		||||
        await codeManager.updateEditorWithAstAndWriteToFile(
 | 
			
		||||
          updateAstResult.newAst
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        if (updateAstResult?.selections) {
 | 
			
		||||
          editorManager.selectRange(updateAstResult?.selections)
 | 
			
		||||
        }
 | 
			
		||||
        await updateModelingState(newAst, EXECUTION_TYPE_REAL, {
 | 
			
		||||
          kclManager,
 | 
			
		||||
          editorManager,
 | 
			
		||||
          codeManager,
 | 
			
		||||
        })
 | 
			
		||||
      }
 | 
			
		||||
    ),
 | 
			
		||||
    'actor.parameter.edit': fromPromise(
 | 
			
		||||
@ -2409,7 +2405,7 @@ export const modelingMachine = setup({
 | 
			
		||||
        // Mutate the variable's value
 | 
			
		||||
        variableNode.node.init = value.valueAst
 | 
			
		||||
 | 
			
		||||
        await updateModelingState(newAst, {
 | 
			
		||||
        await updateModelingState(newAst, EXECUTION_TYPE_REAL, {
 | 
			
		||||
          codeManager,
 | 
			
		||||
          editorManager,
 | 
			
		||||
          kclManager,
 | 
			
		||||
@ -2575,21 +2571,18 @@ export const modelingMachine = setup({
 | 
			
		||||
          return err(result)
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        const updateAstResult = await kclManager.updateAst(
 | 
			
		||||
        await updateModelingState(
 | 
			
		||||
          result.modifiedAst,
 | 
			
		||||
          true,
 | 
			
		||||
          EXECUTION_TYPE_REAL,
 | 
			
		||||
          {
 | 
			
		||||
            kclManager,
 | 
			
		||||
            editorManager,
 | 
			
		||||
            codeManager,
 | 
			
		||||
          },
 | 
			
		||||
          {
 | 
			
		||||
            focusPath: [result.pathToNode],
 | 
			
		||||
          }
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        await codeManager.updateEditorWithAstAndWriteToFile(
 | 
			
		||||
          updateAstResult.newAst
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        if (updateAstResult?.selections) {
 | 
			
		||||
          editorManager.selectRange(updateAstResult?.selections)
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    ),
 | 
			
		||||
    exportFromEngine: fromPromise(
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user