Compare commits
	
		
			7 Commits
		
	
	
		
			achalmers/
			...
			migrate-to
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 6717543305 | |||
| d822593f35 | |||
| 5a236577bb | |||
| 96346cfedf | |||
| 866dffbb46 | |||
| e86c628118 | |||
| 28cd330fc2 | 
| @ -1189,7 +1189,7 @@ fn yohey = (pos) => { | |||||||
|     }, |     }, | ||||||
|     selectionsSnippets |     selectionsSnippets | ||||||
|   ) |   ) | ||||||
|   await page.setViewportSize({ width: 1200, height: 500 }) |   await page.setViewportSize({ width: 1200, height: 1000 }) | ||||||
|   await page.goto('/') |   await page.goto('/') | ||||||
|   await u.waitForAuthSkipAppStart() |   await u.waitForAuthSkipAppStart() | ||||||
|  |  | ||||||
|  | |||||||
| @ -35,7 +35,7 @@ test('exports of each format should work', async ({ page, context }) => { | |||||||
|   // FYI this test doesn't work with only engine running locally |   // FYI this test doesn't work with only engine running locally | ||||||
|   // And you will need to have the KittyCAD CLI installed |   // And you will need to have the KittyCAD CLI installed | ||||||
|   const u = getUtils(page) |   const u = getUtils(page) | ||||||
|   await context.addInitScript(async () => { |   await page.addInitScript(async () => { | ||||||
|     ;(window as any).playwrightSkipFilePicker = true |     ;(window as any).playwrightSkipFilePicker = true | ||||||
|     localStorage.setItem( |     localStorage.setItem( | ||||||
|       'persistCode', |       'persistCode', | ||||||
| @ -79,6 +79,7 @@ const part001 = startSketchOn('-XZ') | |||||||
|   |> extrude(4, %)` |   |> extrude(4, %)` | ||||||
|     ) |     ) | ||||||
|   }) |   }) | ||||||
|  |  | ||||||
|   await page.setViewportSize({ width: 1200, height: 500 }) |   await page.setViewportSize({ width: 1200, height: 500 }) | ||||||
|   await page.goto('/') |   await page.goto('/') | ||||||
|   await u.waitForAuthSkipAppStart() |   await u.waitForAuthSkipAppStart() | ||||||
|  | |||||||
| @ -171,7 +171,7 @@ const FileTreeItem = ({ | |||||||
|  |  | ||||||
|     if (fileOrDir.name?.endsWith(FILE_EXT) === false && project?.path) { |     if (fileOrDir.name?.endsWith(FILE_EXT) === false && project?.path) { | ||||||
|       // Import non-kcl files |       // Import non-kcl files | ||||||
|       kclManager.setCodeAndExecute( |       kclManager.setCode( | ||||||
|         `import("${fileOrDir.path.replace(project.path, '.')}")\n` + |         `import("${fileOrDir.path.replace(project.path, '.')}")\n` + | ||||||
|           kclManager.code |           kclManager.code | ||||||
|       ) |       ) | ||||||
|  | |||||||
| @ -21,6 +21,7 @@ import { | |||||||
| } from './Toolbar/SetAngleBetween' | } from './Toolbar/SetAngleBetween' | ||||||
| import { applyConstraintAngleLength } from './Toolbar/setAngleLength' | import { applyConstraintAngleLength } from './Toolbar/setAngleLength' | ||||||
| import { pathMapToSelections } from 'lang/util' | import { pathMapToSelections } from 'lang/util' | ||||||
|  | import { useLspContext } from 'components/LspProvider' | ||||||
| import { useStore } from 'useStore' | import { useStore } from 'useStore' | ||||||
| import { | import { | ||||||
|   Selections, |   Selections, | ||||||
| @ -86,6 +87,7 @@ export const ModelingMachineProvider = ({ | |||||||
|     htmlRef, |     htmlRef, | ||||||
|     token |     token | ||||||
|   ) |   ) | ||||||
|  |   const { lspClients } = useLspContext() | ||||||
|   useHotkeys('meta + shift + .', () => coreDump(coreDumpManager, true)) |   useHotkeys('meta + shift + .', () => coreDump(coreDumpManager, true)) | ||||||
|  |  | ||||||
|   const { |   const { | ||||||
| @ -116,6 +118,24 @@ export const ModelingMachineProvider = ({ | |||||||
|     modelingMachine, |     modelingMachine, | ||||||
|     { |     { | ||||||
|       actions: { |       actions: { | ||||||
|  |         'disable lsp execution': async () => { | ||||||
|  |           // Update the lsp server that we are in sketch mode, so we can turn off lsp execution. | ||||||
|  |           for (const lspClient of lspClients) { | ||||||
|  |             for (const plugin of lspClient.plugins) { | ||||||
|  |               await plugin.updateCanExecute(false) | ||||||
|  |             } | ||||||
|  |           } | ||||||
|  |           await kclManager.enterEditMode() | ||||||
|  |           console.log('done with disabling lsp execution') | ||||||
|  |         }, | ||||||
|  |         'enable lsp execution': async () => { | ||||||
|  |           // Update the lsp server that we are done with sketch mode, so we can turn back on lsp execution. | ||||||
|  |           for (const lspClient of lspClients) { | ||||||
|  |             for (const plugin of lspClient.plugins) { | ||||||
|  |               await plugin.updateCanExecute(true) | ||||||
|  |             } | ||||||
|  |           } | ||||||
|  |         }, | ||||||
|         'sketch exit execute': () => { |         'sketch exit execute': () => { | ||||||
|           try { |           try { | ||||||
|             kclManager.executeAst(parse(kclManager.code)) |             kclManager.executeAst(parse(kclManager.code)) | ||||||
|  | |||||||
| @ -5,7 +5,7 @@ import { useCommandsContext } from 'hooks/useCommandsContext' | |||||||
| import { useSettingsAuthContext } from 'hooks/useSettingsAuthContext' | import { useSettingsAuthContext } from 'hooks/useSettingsAuthContext' | ||||||
| import { useConvertToVariable } from 'hooks/useToolbarGuards' | import { useConvertToVariable } from 'hooks/useToolbarGuards' | ||||||
| import { Themes, getSystemTheme } from 'lib/theme' | import { Themes, getSystemTheme } from 'lib/theme' | ||||||
| import { useEffect, useMemo, useRef } from 'react' | import { useMemo, useRef } from 'react' | ||||||
| import { useStore } from 'useStore' | import { useStore } from 'useStore' | ||||||
| import { processCodeMirrorRanges } from 'lib/selections' | import { processCodeMirrorRanges } from 'lib/selections' | ||||||
| import { highlightSelectionMatches, searchKeymap } from '@codemirror/search' | import { highlightSelectionMatches, searchKeymap } from '@codemirror/search' | ||||||
| @ -29,7 +29,7 @@ import { | |||||||
|   historyKeymap, |   historyKeymap, | ||||||
|   history, |   history, | ||||||
| } from '@codemirror/commands' | } from '@codemirror/commands' | ||||||
| import { lintGutter, lintKeymap, linter } from '@codemirror/lint' | import { lintGutter, lintKeymap } from '@codemirror/lint' | ||||||
| import { | import { | ||||||
|   foldGutter, |   foldGutter, | ||||||
|   foldKeymap, |   foldKeymap, | ||||||
| @ -57,11 +57,6 @@ import { | |||||||
|   completionKeymap, |   completionKeymap, | ||||||
|   hasNextSnippetField, |   hasNextSnippetField, | ||||||
| } from '@codemirror/autocomplete' | } from '@codemirror/autocomplete' | ||||||
| import { |  | ||||||
|   NetworkHealthState, |  | ||||||
|   useNetworkStatus, |  | ||||||
| } from 'components/NetworkHealthIndicator' |  | ||||||
| import { kclErrorsToDiagnostics } from 'lang/errors' |  | ||||||
|  |  | ||||||
| export const editorShortcutMeta = { | export const editorShortcutMeta = { | ||||||
|   formatCode: { |   formatCode: { | ||||||
| @ -86,20 +81,11 @@ export const KclEditorPane = () => { | |||||||
|     setEditorView: s.setEditorView, |     setEditorView: s.setEditorView, | ||||||
|     isShiftDown: s.isShiftDown, |     isShiftDown: s.isShiftDown, | ||||||
|   })) |   })) | ||||||
|   const { code, errors } = useKclContext() |   const { code } = useKclContext() | ||||||
|   const lastEvent = useRef({ event: '', time: Date.now() }) |   const lastEvent = useRef({ event: '', time: Date.now() }) | ||||||
|   const { copilotLSP, kclLSP } = useLspContext() |   const { copilotLSP, kclLSP } = useLspContext() | ||||||
|   const { overallState } = useNetworkStatus() |  | ||||||
|   const isNetworkOkay = overallState === NetworkHealthState.Ok |  | ||||||
|   const navigate = useNavigate() |   const navigate = useNavigate() | ||||||
|  |  | ||||||
|   useEffect(() => { |  | ||||||
|     if (typeof window === 'undefined') return |  | ||||||
|     const onlineCallback = () => kclManager.setCodeAndExecute(kclManager.code) |  | ||||||
|     window.addEventListener('online', onlineCallback) |  | ||||||
|     return () => window.removeEventListener('online', onlineCallback) |  | ||||||
|   }, []) |  | ||||||
|  |  | ||||||
|   useHotkeys('mod+z', (e) => { |   useHotkeys('mod+z', (e) => { | ||||||
|     e.preventDefault() |     e.preventDefault() | ||||||
|     if (editorView) { |     if (editorView) { | ||||||
| @ -136,8 +122,7 @@ export const KclEditorPane = () => { | |||||||
|       return |       return | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     if (isNetworkOkay) kclManager.setCodeAndExecute(newCode) |     kclManager.setCode(newCode) | ||||||
|     else kclManager.setCode(newCode) |  | ||||||
|   } |   } | ||||||
|   const lastSelection = useRef('') |   const lastSelection = useRef('') | ||||||
|   const onUpdate = (viewUpdate: ViewUpdate) => { |   const onUpdate = (viewUpdate: ViewUpdate) => { | ||||||
| @ -252,9 +237,6 @@ export const KclEditorPane = () => { | |||||||
|     if (!TEST) { |     if (!TEST) { | ||||||
|       extensions.push( |       extensions.push( | ||||||
|         lintGutter(), |         lintGutter(), | ||||||
|         linter((_view: EditorView) => { |  | ||||||
|           return kclErrorsToDiagnostics(errors) |  | ||||||
|         }), |  | ||||||
|         lineNumbers(), |         lineNumbers(), | ||||||
|         highlightActiveLineGutter(), |         highlightActiveLineGutter(), | ||||||
|         highlightSpecialChars(), |         highlightSpecialChars(), | ||||||
|  | |||||||
| @ -18,7 +18,7 @@ import { | |||||||
| } from 'xstate' | } from 'xstate' | ||||||
| import { isTauri } from 'lib/isTauri' | import { isTauri } from 'lib/isTauri' | ||||||
| import { authCommandBarConfig } from 'lib/commandBarConfigs/authCommandConfig' | import { authCommandBarConfig } from 'lib/commandBarConfigs/authCommandConfig' | ||||||
| import { kclManager, sceneInfra, engineCommandManager } from 'lib/singletons' | import { sceneInfra, engineCommandManager } from 'lib/singletons' | ||||||
| import { uuidv4 } from 'lib/utils' | import { uuidv4 } from 'lib/utils' | ||||||
| import { IndexLoaderData } from 'lib/types' | import { IndexLoaderData } from 'lib/types' | ||||||
| import { settings } from 'lib/settings/initialSettings' | import { settings } from 'lib/settings/initialSettings' | ||||||
| @ -138,7 +138,6 @@ export const SettingsAuthProviderBase = ({ | |||||||
|             id: `${event.type}.success`, |             id: `${event.type}.success`, | ||||||
|           }) |           }) | ||||||
|         }, |         }, | ||||||
|         'Execute AST': () => kclManager.executeAst(), |  | ||||||
|         persistSettings: (context) => |         persistSettings: (context) => | ||||||
|           saveSettings(context, loadedProject?.project?.path), |           saveSettings(context, loadedProject?.project?.path), | ||||||
|       }, |       }, | ||||||
|  | |||||||
| @ -12,7 +12,6 @@ import { | |||||||
|   CompletionTriggerKind, |   CompletionTriggerKind, | ||||||
| } from 'vscode-languageserver-protocol' | } from 'vscode-languageserver-protocol' | ||||||
|  |  | ||||||
| import { deferExecution } from 'lib/utils' |  | ||||||
| import type { | import type { | ||||||
|   Completion, |   Completion, | ||||||
|   CompletionContext, |   CompletionContext, | ||||||
| @ -43,8 +42,6 @@ const CompletionItemKindMap = Object.fromEntries( | |||||||
|   Object.entries(CompletionItemKind).map(([key, value]) => [value, key]) |   Object.entries(CompletionItemKind).map(([key, value]) => [value, key]) | ||||||
| ) as Record<CompletionItemKind, string> | ) as Record<CompletionItemKind, string> | ||||||
|  |  | ||||||
| const changesDelay = 600 |  | ||||||
|  |  | ||||||
| export class LanguageServerPlugin implements PluginValue { | export class LanguageServerPlugin implements PluginValue { | ||||||
|   public client: LanguageServerClient |   public client: LanguageServerClient | ||||||
|   public documentUri: string |   public documentUri: string | ||||||
| @ -52,19 +49,6 @@ export class LanguageServerPlugin implements PluginValue { | |||||||
|   public workspaceFolders: LSP.WorkspaceFolder[] |   public workspaceFolders: LSP.WorkspaceFolder[] | ||||||
|   private documentVersion: number |   private documentVersion: number | ||||||
|   private foldingRanges: LSP.FoldingRange[] | null = null |   private foldingRanges: LSP.FoldingRange[] | null = null | ||||||
|   private _defferer = deferExecution((code: string) => { |  | ||||||
|     try { |  | ||||||
|       this.client.textDocumentDidChange({ |  | ||||||
|         textDocument: { |  | ||||||
|           uri: this.documentUri, |  | ||||||
|           version: this.documentVersion++, |  | ||||||
|         }, |  | ||||||
|         contentChanges: [{ text: code }], |  | ||||||
|       }) |  | ||||||
|     } catch (e) { |  | ||||||
|       console.error(e) |  | ||||||
|     } |  | ||||||
|   }, changesDelay) |  | ||||||
|  |  | ||||||
|   constructor( |   constructor( | ||||||
|     client: LanguageServerClient, |     client: LanguageServerClient, | ||||||
| @ -134,7 +118,17 @@ export class LanguageServerPlugin implements PluginValue { | |||||||
|       documentText = '' |       documentText = '' | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     this._defferer(documentText) |     try { | ||||||
|  |       this.client.textDocumentDidChange({ | ||||||
|  |         textDocument: { | ||||||
|  |           uri: this.documentUri, | ||||||
|  |           version: this.documentVersion++, | ||||||
|  |         }, | ||||||
|  |         contentChanges: [{ text: documentText }], | ||||||
|  |       }) | ||||||
|  |     } catch (e) { | ||||||
|  |       console.error(e) | ||||||
|  |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   requestDiagnostics(view: EditorView) { |   requestDiagnostics(view: EditorView) { | ||||||
| @ -380,10 +374,10 @@ export class LanguageServerPlugin implements PluginValue { | |||||||
|           const params = notification.params as PublishDiagnosticsParams |           const params = notification.params as PublishDiagnosticsParams | ||||||
|           this.processDiagnostics(params) |           this.processDiagnostics(params) | ||||||
|           // Update the kcl errors pane. |           // Update the kcl errors pane. | ||||||
|           /*kclManager.kclErrors = lspDiagnosticsToKclErrors( |           kclManager.kclErrors = lspDiagnosticsToKclErrors( | ||||||
|             this.view.state.doc, |             this.view.state.doc, | ||||||
|             params.diagnostics |             params.diagnostics | ||||||
|           )*/ |           ) | ||||||
|           break |           break | ||||||
|         case 'window/logMessage': |         case 'window/logMessage': | ||||||
|           console.log( |           console.log( | ||||||
|  | |||||||
| @ -3,7 +3,7 @@ import { useStore } from '../useStore' | |||||||
| import { engineCommandManager, kclManager } from 'lib/singletons' | import { engineCommandManager, kclManager } from 'lib/singletons' | ||||||
| import { deferExecution } from 'lib/utils' | import { deferExecution } from 'lib/utils' | ||||||
| import { Themes } from 'lib/theme' | import { Themes } from 'lib/theme' | ||||||
| import { makeDefaultPlanes, parse } from 'lang/wasm' | import { makeDefaultPlanes } from 'lang/wasm' | ||||||
|  |  | ||||||
| export function useSetupEngineManager( | export function useSetupEngineManager( | ||||||
|   streamRef: React.RefObject<HTMLDivElement>, |   streamRef: React.RefObject<HTMLDivElement>, | ||||||
| @ -40,10 +40,6 @@ export function useSetupEngineManager( | |||||||
|         setIsStreamReady, |         setIsStreamReady, | ||||||
|         width: quadWidth, |         width: quadWidth, | ||||||
|         height: quadHeight, |         height: quadHeight, | ||||||
|         executeCode: (code?: string) => { |  | ||||||
|           const _ast = parse(code || kclManager.code) |  | ||||||
|           return kclManager.executeAst(_ast, true) |  | ||||||
|         }, |  | ||||||
|         token, |         token, | ||||||
|         theme, |         theme, | ||||||
|         makeDefaultPlanes: () => { |         makeDefaultPlanes: () => { | ||||||
|  | |||||||
| @ -1,10 +1,9 @@ | |||||||
| import { executeAst, executeCode } from 'useStore' | import { executeAst } from 'useStore' | ||||||
| import { Selections } from 'lib/selections' | import { Selections } from 'lib/selections' | ||||||
| import { KCLError } from './errors' | import { KCLError } from './errors' | ||||||
| import { uuidv4 } from 'lib/utils' | import { uuidv4 } from 'lib/utils' | ||||||
| import { EngineCommandManager } from './std/engineConnection' | import { EngineCommandManager } from './std/engineConnection' | ||||||
|  |  | ||||||
| import { deferExecution } from 'lib/utils' |  | ||||||
| import { | import { | ||||||
|   CallExpression, |   CallExpression, | ||||||
|   initPromise, |   initPromise, | ||||||
| @ -47,19 +46,6 @@ export class KclManager { | |||||||
|   private _params: Params<string> = {} |   private _params: Params<string> = {} | ||||||
|  |  | ||||||
|   engineCommandManager: EngineCommandManager |   engineCommandManager: EngineCommandManager | ||||||
|   private _defferer = deferExecution((code: string) => { |  | ||||||
|     const ast = this.safeParse(code) |  | ||||||
|     if (!ast) return |  | ||||||
|     try { |  | ||||||
|       const fmtAndStringify = (ast: Program) => |  | ||||||
|         JSON.stringify(parse(recast(ast))) |  | ||||||
|       const isAstTheSame = fmtAndStringify(ast) === fmtAndStringify(this._ast) |  | ||||||
|       if (isAstTheSame) return |  | ||||||
|     } catch (e) { |  | ||||||
|       console.error(e) |  | ||||||
|     } |  | ||||||
|     this.executeAst(ast) |  | ||||||
|   }, 600) |  | ||||||
|  |  | ||||||
|   private _isExecutingCallback: (arg: boolean) => void = () => {} |   private _isExecutingCallback: (arg: boolean) => void = () => {} | ||||||
|   private _codeCallBack: (arg: string) => void = () => {} |   private _codeCallBack: (arg: string) => void = () => {} | ||||||
| @ -81,6 +67,9 @@ export class KclManager { | |||||||
|   get code() { |   get code() { | ||||||
|     return this._code |     return this._code | ||||||
|   } |   } | ||||||
|  |   // Calling set code will update the code in the codemirror editor. | ||||||
|  |   // That will then trigger the lsp to update the ast and execute the code. | ||||||
|  |   // DO NOT ALSO CALL execute/parseCode here, as that will cause the code to be executed twice. | ||||||
|   set code(code) { |   set code(code) { | ||||||
|     this._code = code |     this._code = code | ||||||
|     this._codeCallBack(code) |     this._codeCallBack(code) | ||||||
| @ -106,6 +95,12 @@ export class KclManager { | |||||||
|   set programMemory(programMemory) { |   set programMemory(programMemory) { | ||||||
|     this._programMemory = programMemory |     this._programMemory = programMemory | ||||||
|     this._programMemoryCallBack(programMemory) |     this._programMemoryCallBack(programMemory) | ||||||
|  |     // We only do this to help the playwright testes otherwise I would remove | ||||||
|  |     // it. (@jessfraz wrote this comment) | ||||||
|  |     this.engineCommandManager.addCommandLog({ | ||||||
|  |       type: 'execution-done', | ||||||
|  |       data: null, | ||||||
|  |     }) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   get logs() { |   get logs() { | ||||||
| @ -208,7 +203,6 @@ export class KclManager { | |||||||
|       console.error('error parsing code', e) |       console.error('error parsing code', e) | ||||||
|       if (e instanceof KCLError) { |       if (e instanceof KCLError) { | ||||||
|         this.kclErrors = [e] |         this.kclErrors = [e] | ||||||
|         if (e.msg === 'file is empty') this.engineCommandManager?.endSession() |  | ||||||
|       } |       } | ||||||
|       return null |       return null | ||||||
|     } |     } | ||||||
| @ -220,8 +214,9 @@ export class KclManager { | |||||||
|       if (this.wasmInitFailed) { |       if (this.wasmInitFailed) { | ||||||
|         this.wasmInitFailed = false |         this.wasmInitFailed = false | ||||||
|       } |       } | ||||||
|     } catch (e) { |     } catch (e: any) { | ||||||
|       this.wasmInitFailed = true |       this.wasmInitFailed = true | ||||||
|  |       throw new Error('error initializing wasm: ' + e.toString()) | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @ -241,7 +236,7 @@ export class KclManager { | |||||||
|       ast, |       ast, | ||||||
|       engineCommandManager: this.engineCommandManager, |       engineCommandManager: this.engineCommandManager, | ||||||
|     }) |     }) | ||||||
|     enterEditMode(programMemory, this.engineCommandManager) |     await enterEditMode(programMemory, this.engineCommandManager) | ||||||
|     this.isExecuting = false |     this.isExecuting = false | ||||||
|     // Check the cancellation token for this execution before applying side effects |     // Check the cancellation token for this execution before applying side effects | ||||||
|     if (this._cancelTokens.get(currentExecutionId)) { |     if (this._cancelTokens.get(currentExecutionId)) { | ||||||
| @ -276,7 +271,7 @@ export class KclManager { | |||||||
|     if (!newAst) return |     if (!newAst) return | ||||||
|     await this?.engineCommandManager?.waitForReady |     await this?.engineCommandManager?.waitForReady | ||||||
|     if (updates !== 'none') { |     if (updates !== 'none') { | ||||||
|       this.setCode(recast(ast)) |       this.setCode(newCode) | ||||||
|     } |     } | ||||||
|     this._ast = { ...newAst } |     this._ast = { ...newAst } | ||||||
|  |  | ||||||
| @ -308,41 +303,14 @@ export class KclManager { | |||||||
|       } |       } | ||||||
|     ) |     ) | ||||||
|   } |   } | ||||||
|   executeCode = async (code?: string, executionId?: number) => { |  | ||||||
|     const currentExecutionId = executionId || Date.now() |  | ||||||
|     this._cancelTokens.set(currentExecutionId, false) |  | ||||||
|     if (this._cancelTokens.get(currentExecutionId)) { |  | ||||||
|       this._cancelTokens.delete(currentExecutionId) |  | ||||||
|       return |  | ||||||
|     } |  | ||||||
|     await this.ensureWasmInit() |  | ||||||
|     await this?.engineCommandManager?.waitForReady |  | ||||||
|     const result = await executeCode({ |  | ||||||
|       engineCommandManager: this.engineCommandManager, |  | ||||||
|       code: code || this._code, |  | ||||||
|       lastAst: this._ast, |  | ||||||
|       force: false, |  | ||||||
|     }) |  | ||||||
|     // Check the cancellation token for this execution before applying side effects |  | ||||||
|     if (this._cancelTokens.get(currentExecutionId)) { |  | ||||||
|       this._cancelTokens.delete(currentExecutionId) |  | ||||||
|       return |  | ||||||
|     } |  | ||||||
|     if (!result.isChange) return |  | ||||||
|     const { logs, errors, programMemory, ast } = result |  | ||||||
|     enterEditMode(programMemory, this.engineCommandManager) |  | ||||||
|     this.logs = logs |  | ||||||
|     this.kclErrors = errors |  | ||||||
|     this.programMemory = programMemory |  | ||||||
|     this.ast = ast |  | ||||||
|     if (code) this.code = code |  | ||||||
|     this._cancelTokens.delete(currentExecutionId) |  | ||||||
|   } |  | ||||||
|   cancelAllExecutions() { |   cancelAllExecutions() { | ||||||
|     this._cancelTokens.forEach((_, key) => { |     this._cancelTokens.forEach((_, key) => { | ||||||
|       this._cancelTokens.set(key, true) |       this._cancelTokens.set(key, true) | ||||||
|     }) |     }) | ||||||
|   } |   } | ||||||
|  |   // Calling set code will update the code in the codemirror editor. | ||||||
|  |   // That will then trigger the lsp to update the ast and execute the code. | ||||||
|  |   // DO NOT ALSO CALL execute/parseCode here, as that will cause the code to be executed twice. | ||||||
|   setCode(code: string, shouldWriteFile = true) { |   setCode(code: string, shouldWriteFile = true) { | ||||||
|     if (shouldWriteFile) { |     if (shouldWriteFile) { | ||||||
|       // use the normal code setter |       // use the normal code setter | ||||||
| @ -352,27 +320,6 @@ export class KclManager { | |||||||
|     this._code = code |     this._code = code | ||||||
|     this._codeCallBack(code) |     this._codeCallBack(code) | ||||||
|   } |   } | ||||||
|   setCodeAndExecute(code: string, shouldWriteFile = true) { |  | ||||||
|     this.setCode(code, shouldWriteFile) |  | ||||||
|     if (code.trim()) { |  | ||||||
|       this._defferer(code) |  | ||||||
|       return |  | ||||||
|     } |  | ||||||
|     this._ast = { |  | ||||||
|       body: [], |  | ||||||
|       start: 0, |  | ||||||
|       end: 0, |  | ||||||
|       nonCodeMeta: { |  | ||||||
|         nonCodeNodes: {}, |  | ||||||
|         start: [], |  | ||||||
|       }, |  | ||||||
|     } |  | ||||||
|     this._programMemory = { |  | ||||||
|       root: {}, |  | ||||||
|       return: null, |  | ||||||
|     } |  | ||||||
|     this.engineCommandManager.endSession() |  | ||||||
|   } |  | ||||||
|   format() { |   format() { | ||||||
|     const ast = this.safeParse(this.code) |     const ast = this.safeParse(this.code) | ||||||
|     if (!ast) return |     if (!ast) return | ||||||
| @ -440,6 +387,10 @@ export class KclManager { | |||||||
|     void this.engineCommandManager.setPlaneHidden(this.defaultPlanes.yz, true) |     void this.engineCommandManager.setPlaneHidden(this.defaultPlanes.yz, true) | ||||||
|     void this.engineCommandManager.setPlaneHidden(this.defaultPlanes.xz, true) |     void this.engineCommandManager.setPlaneHidden(this.defaultPlanes.xz, true) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   async enterEditMode() { | ||||||
|  |     await enterEditMode(this.programMemory, this.engineCommandManager) | ||||||
|  |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| function safeLSGetItem(key: string) { | function safeLSGetItem(key: string) { | ||||||
| @ -452,7 +403,7 @@ function safteLSSetItem(key: string, value: string) { | |||||||
|   localStorage?.setItem(key, value) |   localStorage?.setItem(key, value) | ||||||
| } | } | ||||||
|  |  | ||||||
| function enterEditMode( | async function enterEditMode( | ||||||
|   programMemory: ProgramMemory, |   programMemory: ProgramMemory, | ||||||
|   engineCommandManager: EngineCommandManager |   engineCommandManager: EngineCommandManager | ||||||
| ) { | ) { | ||||||
| @ -460,7 +411,7 @@ function enterEditMode( | |||||||
|     (node) => node.type === 'ExtrudeGroup' || node.type === 'SketchGroup' |     (node) => node.type === 'ExtrudeGroup' || node.type === 'SketchGroup' | ||||||
|   ) as SketchGroup | ExtrudeGroup |   ) as SketchGroup | ExtrudeGroup | ||||||
|   firstSketchOrExtrudeGroup && |   firstSketchOrExtrudeGroup && | ||||||
|     engineCommandManager.sendSceneCommand({ |     (await engineCommandManager.sendSceneCommand({ | ||||||
|       type: 'modeling_cmd_batch_req', |       type: 'modeling_cmd_batch_req', | ||||||
|       batch_id: uuidv4(), |       batch_id: uuidv4(), | ||||||
|       requests: [ |       requests: [ | ||||||
| @ -479,5 +430,5 @@ function enterEditMode( | |||||||
|           }, |           }, | ||||||
|         }, |         }, | ||||||
|       ], |       ], | ||||||
|     }) |     })) | ||||||
| } | } | ||||||
|  | |||||||
| @ -921,7 +921,6 @@ export class EngineCommandManager { | |||||||
|     setIsStreamReady, |     setIsStreamReady, | ||||||
|     width, |     width, | ||||||
|     height, |     height, | ||||||
|     executeCode, |  | ||||||
|     token, |     token, | ||||||
|     makeDefaultPlanes, |     makeDefaultPlanes, | ||||||
|     theme = Themes.Dark, |     theme = Themes.Dark, | ||||||
| @ -930,7 +929,6 @@ export class EngineCommandManager { | |||||||
|     setIsStreamReady: (isStreamReady: boolean) => void |     setIsStreamReady: (isStreamReady: boolean) => void | ||||||
|     width: number |     width: number | ||||||
|     height: number |     height: number | ||||||
|     executeCode: (code?: string, force?: boolean) => void |  | ||||||
|     token?: string |     token?: string | ||||||
|     makeDefaultPlanes: () => Promise<DefaultPlanes> |     makeDefaultPlanes: () => Promise<DefaultPlanes> | ||||||
|     theme?: Themes |     theme?: Themes | ||||||
| @ -1005,7 +1003,6 @@ export class EngineCommandManager { | |||||||
|         this.initPlanes().then(() => { |         this.initPlanes().then(() => { | ||||||
|           this.resolveReady() |           this.resolveReady() | ||||||
|           setIsStreamReady(true) |           setIsStreamReady(true) | ||||||
|           executeCode(undefined, true) |  | ||||||
|         }) |         }) | ||||||
|       }, |       }, | ||||||
|       onClose: () => { |       onClose: () => { | ||||||
|  | |||||||
| @ -100,7 +100,7 @@ export const fileLoader: LoaderFunction = async ({ | |||||||
|     const children = await invoke<FileEntry[]>('read_dir_recursive', { |     const children = await invoke<FileEntry[]>('read_dir_recursive', { | ||||||
|       path: projectPath, |       path: projectPath, | ||||||
|     }) |     }) | ||||||
|     kclManager.setCodeAndExecute(code, false) |     kclManager.setCode(code, false) | ||||||
|  |  | ||||||
|     // Set the file system manager to the project path |     // Set the file system manager to the project path | ||||||
|     // So that WASM gets an updated path for operations |     // So that WASM gets an updated path for operations | ||||||
|  | |||||||
| @ -98,7 +98,6 @@ export async function executor( | |||||||
|     setMediaStream: () => {}, |     setMediaStream: () => {}, | ||||||
|     width: 0, |     width: 0, | ||||||
|     height: 0, |     height: 0, | ||||||
|     executeCode: () => {}, |  | ||||||
|     theme: Themes.Dark, |     theme: Themes.Dark, | ||||||
|     makeDefaultPlanes: () => { |     makeDefaultPlanes: () => { | ||||||
|       return new Promise((resolve) => resolve(defaultPlanes)) |       return new Promise((resolve) => resolve(defaultPlanes)) | ||||||
|  | |||||||
| @ -192,7 +192,11 @@ export const modelingMachine = createMachine( | |||||||
|           Extrude: { |           Extrude: { | ||||||
|             target: 'idle', |             target: 'idle', | ||||||
|             cond: 'has valid extrude selection', |             cond: 'has valid extrude selection', | ||||||
|             actions: ['AST extrude'], |             actions: [ | ||||||
|  |               'disable lsp execution', | ||||||
|  |               'AST extrude', | ||||||
|  |               'enable lsp execution', | ||||||
|  |             ], | ||||||
|             internal: true, |             internal: true, | ||||||
|           }, |           }, | ||||||
|  |  | ||||||
| @ -490,13 +494,18 @@ export const modelingMachine = createMachine( | |||||||
|           'tear down client sketch', |           'tear down client sketch', | ||||||
|           'remove sketch grid', |           'remove sketch grid', | ||||||
|           'engineToClient cam sync direction', |           'engineToClient cam sync direction', | ||||||
|  |           'enable lsp execution', | ||||||
|         ], |         ], | ||||||
|  |  | ||||||
|         entry: ['add axis n grid', 'conditionally equip line tool'], |         entry: ['add axis n grid', 'conditionally equip line tool'], | ||||||
|       }, |       }, | ||||||
|  |  | ||||||
|       'Sketch no face': { |       'Sketch no face': { | ||||||
|         entry: ['show default planes', 'set selection filter to faces only'], |         entry: [ | ||||||
|  |           'disable lsp execution', | ||||||
|  |           'show default planes', | ||||||
|  |           'set selection filter to faces only', | ||||||
|  |         ], | ||||||
|  |  | ||||||
|         exit: ['hide default planes', 'set selection filter to defaults'], |         exit: ['hide default planes', 'set selection filter to defaults'], | ||||||
|         on: { |         on: { | ||||||
|  | |||||||
| @ -45,7 +45,6 @@ export const settingsMachine = createMachine( | |||||||
|               'setSettingAtLevel', |               'setSettingAtLevel', | ||||||
|               'toastSuccess', |               'toastSuccess', | ||||||
|               'setClientSideSceneUnits', |               'setClientSideSceneUnits', | ||||||
|               'Execute AST', |  | ||||||
|               'persistSettings', |               'persistSettings', | ||||||
|             ], |             ], | ||||||
|           }, |           }, | ||||||
| @ -70,7 +69,6 @@ export const settingsMachine = createMachine( | |||||||
|               'setThemeClass', |               'setThemeClass', | ||||||
|               'setEngineTheme', |               'setEngineTheme', | ||||||
|               'setClientSideSceneUnits', |               'setClientSideSceneUnits', | ||||||
|               'Execute AST', |  | ||||||
|               'persistSettings', |               'persistSettings', | ||||||
|             ], |             ], | ||||||
|           }, |           }, | ||||||
| @ -83,7 +81,6 @@ export const settingsMachine = createMachine( | |||||||
|               'setThemeClass', |               'setThemeClass', | ||||||
|               'setEngineTheme', |               'setEngineTheme', | ||||||
|               'setClientSideSceneUnits', |               'setClientSideSceneUnits', | ||||||
|               'Execute AST', |  | ||||||
|               'persistSettings', |               'persistSettings', | ||||||
|             ], |             ], | ||||||
|           }, |           }, | ||||||
|  | |||||||
| @ -11,13 +11,8 @@ export default function FutureWork() { | |||||||
|   const dismiss = useDismiss() |   const dismiss = useDismiss() | ||||||
|  |  | ||||||
|   useEffect(() => { |   useEffect(() => { | ||||||
|     if (kclManager.engineCommandManager.engineConnection?.isReady()) { |  | ||||||
|       // If the engine is ready, promptly execute the loaded code |  | ||||||
|       kclManager.setCodeAndExecute(bracket) |  | ||||||
|     } else { |  | ||||||
|     // Otherwise, just set the code and wait for the connection to complete |     // Otherwise, just set the code and wait for the connection to complete | ||||||
|     kclManager.setCode(bracket) |     kclManager.setCode(bracket) | ||||||
|     } |  | ||||||
|  |  | ||||||
|     send({ type: 'Cancel' }) // in case the user hit 'Next' while still in sketch mode |     send({ type: 'Cancel' }) // in case the user hit 'Next' while still in sketch mode | ||||||
|   }, [send]) |   }, [send]) | ||||||
|  | |||||||
| @ -70,7 +70,7 @@ function OnboardingWithNewFile() { | |||||||
|               className="mt-6" |               className="mt-6" | ||||||
|               dismiss={dismiss} |               dismiss={dismiss} | ||||||
|               next={() => { |               next={() => { | ||||||
|                 kclManager.setCodeAndExecute(bracket) |                 kclManager.setCode(bracket) | ||||||
|                 next() |                 next() | ||||||
|               }} |               }} | ||||||
|               nextText="Overwrite code and continue" |               nextText="Overwrite code and continue" | ||||||
|  | |||||||
| @ -10,13 +10,7 @@ export default function Sketching() { | |||||||
|   const next = useNextClick(onboardingPaths.FUTURE_WORK) |   const next = useNextClick(onboardingPaths.FUTURE_WORK) | ||||||
|  |  | ||||||
|   useEffect(() => { |   useEffect(() => { | ||||||
|     if (kclManager.engineCommandManager.engineConnection?.isReady()) { |  | ||||||
|       // If the engine is ready, promptly execute the loaded code |  | ||||||
|       kclManager.setCodeAndExecute('') |  | ||||||
|     } else { |  | ||||||
|       // Otherwise, just set the code and wait for the connection to complete |  | ||||||
|     kclManager.setCode('') |     kclManager.setCode('') | ||||||
|     } |  | ||||||
|   }, []) |   }, []) | ||||||
|  |  | ||||||
|   return ( |   return ( | ||||||
|  | |||||||
| @ -2,7 +2,6 @@ import { create } from 'zustand' | |||||||
| import { persist } from 'zustand/middleware' | import { persist } from 'zustand/middleware' | ||||||
| import { addLineHighlight, EditorView } from './editor/highlightextension' | import { addLineHighlight, EditorView } from './editor/highlightextension' | ||||||
| import { | import { | ||||||
|   parse, |  | ||||||
|   Program, |   Program, | ||||||
|   _executor, |   _executor, | ||||||
|   ProgramMemory, |   ProgramMemory, | ||||||
| @ -175,74 +174,6 @@ export const useStore = create<StoreState>()( | |||||||
|   ) |   ) | ||||||
| ) | ) | ||||||
|  |  | ||||||
| export async function executeCode({ |  | ||||||
|   engineCommandManager, |  | ||||||
|   code, |  | ||||||
|   lastAst, |  | ||||||
|   force, |  | ||||||
| }: { |  | ||||||
|   code: string |  | ||||||
|   lastAst: Program |  | ||||||
|   engineCommandManager: EngineCommandManager |  | ||||||
|   force?: boolean |  | ||||||
| }): Promise< |  | ||||||
|   | { |  | ||||||
|       logs: string[] |  | ||||||
|       errors: KCLError[] |  | ||||||
|       programMemory: ProgramMemory |  | ||||||
|       ast: Program |  | ||||||
|       isChange: true |  | ||||||
|     } |  | ||||||
|   | { isChange: false } |  | ||||||
| > { |  | ||||||
|   let ast: Program |  | ||||||
|   try { |  | ||||||
|     ast = parse(code) |  | ||||||
|   } catch (e) { |  | ||||||
|     let errors: KCLError[] = [] |  | ||||||
|     let logs: string[] = [JSON.stringify(e)] |  | ||||||
|     if (e instanceof KCLError) { |  | ||||||
|       errors = [e] |  | ||||||
|       logs = [] |  | ||||||
|       if (e.msg === 'file is empty') engineCommandManager.endSession() |  | ||||||
|     } |  | ||||||
|     return { |  | ||||||
|       isChange: true, |  | ||||||
|       logs, |  | ||||||
|       errors, |  | ||||||
|       programMemory: { |  | ||||||
|         root: {}, |  | ||||||
|         return: null, |  | ||||||
|       }, |  | ||||||
|       ast: { |  | ||||||
|         start: 0, |  | ||||||
|         end: 0, |  | ||||||
|         body: [], |  | ||||||
|         nonCodeMeta: { |  | ||||||
|           nonCodeNodes: {}, |  | ||||||
|           start: [], |  | ||||||
|         }, |  | ||||||
|       }, |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
|   // Check if the ast we have is equal to the ast in the storage. |  | ||||||
|   // If it is, we don't need to update the ast. |  | ||||||
|   if (JSON.stringify(ast) === JSON.stringify(lastAst) && !force) |  | ||||||
|     return { isChange: false } |  | ||||||
|  |  | ||||||
|   const { logs, errors, programMemory } = await executeAst({ |  | ||||||
|     ast, |  | ||||||
|     engineCommandManager, |  | ||||||
|   }) |  | ||||||
|   return { |  | ||||||
|     ast, |  | ||||||
|     logs, |  | ||||||
|     errors, |  | ||||||
|     programMemory, |  | ||||||
|     isChange: true, |  | ||||||
|   } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| export async function executeAst({ | export async function executeAst({ | ||||||
|   ast, |   ast, | ||||||
|   engineCommandManager, |   engineCommandManager, | ||||||
|  | |||||||
| @ -223,8 +223,7 @@ pub async fn kcl_lsp_run( | |||||||
|     let engine = kcl_lib::engine::conn_wasm::EngineConnection::new(engine_manager) |     let engine = kcl_lib::engine::conn_wasm::EngineConnection::new(engine_manager) | ||||||
|         .await |         .await | ||||||
|         .map_err(|e| format!("{:?}", e))?; |         .map_err(|e| format!("{:?}", e))?; | ||||||
|     // Turn off lsp execute for now |     let executor_ctx = kcl_lib::executor::ExecutorContext { | ||||||
|     let _executor_ctx = kcl_lib::executor::ExecutorContext { |  | ||||||
|         engine: Arc::new(Box::new(engine)), |         engine: Arc::new(Box::new(engine)), | ||||||
|         fs: file_manager.clone(), |         fs: file_manager.clone(), | ||||||
|         stdlib: std::sync::Arc::new(stdlib), |         stdlib: std::sync::Arc::new(stdlib), | ||||||
| @ -266,8 +265,8 @@ pub async fn kcl_lsp_run( | |||||||
|         semantic_tokens_map: Default::default(), |         semantic_tokens_map: Default::default(), | ||||||
|         zoo_client, |         zoo_client, | ||||||
|         can_send_telemetry: privacy_settings.can_train_on_data, |         can_send_telemetry: privacy_settings.can_train_on_data, | ||||||
|         executor_ctx: Default::default(), |         executor_ctx: Arc::new(tokio::sync::RwLock::new(Some(executor_ctx))), | ||||||
|         can_execute: Default::default(), |         can_execute: Arc::new(tokio::sync::RwLock::new(true)), | ||||||
|  |  | ||||||
|         is_initialized: Default::default(), |         is_initialized: Default::default(), | ||||||
|         current_handle: Default::default(), |         current_handle: Default::default(), | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user
	