Compare commits

...

7 Commits

Author SHA1 Message Date
6717543305 Merge branch 'main' into migrate-to-lsp-execution 2024-04-16 11:05:54 -07:00
d822593f35 Merge branch 'main' into migrate-to-lsp-execution 2024-04-15 19:38:12 -07:00
5a236577bb update docs
Signed-off-by: Jess Frazelle <github@jessfraz.com>
2024-04-15 18:20:20 -07:00
96346cfedf fix example
Signed-off-by: Jess Frazelle <github@jessfraz.com>
2024-04-15 18:02:26 -07:00
866dffbb46 fixes
Signed-off-by: Jess Frazelle <github@jessfraz.com>
2024-04-15 17:25:17 -07:00
e86c628118 fixes
Signed-off-by: Jess Frazelle <github@jessfraz.com>
2024-04-15 17:24:29 -07:00
28cd330fc2 updates
Signed-off-by: Jess Frazelle <github@jessfraz.com>

clear scene

Signed-off-by: Jess Frazelle <github@jessfraz.com>

updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

cleanups

Signed-off-by: Jess Frazelle <github@jessfraz.com>

updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

delete unused shit

Signed-off-by: Jess Frazelle <github@jessfraz.com>

add comments

Signed-off-by: Jess Frazelle <github@jessfraz.com>

updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

fix linter

Signed-off-by: Jess Frazelle <github@jessfraz.com>

format moved to plugin

Signed-off-by: Jess Frazelle <github@jessfraz.com>

arc the fs

Signed-off-by: Jess Frazelle <github@jessfraz.com>

update units

Signed-off-by: Jess Frazelle <github@jessfraz.com>

fixes

Signed-off-by: Jess Frazelle <github@jessfraz.com>

tests for folding range

Signed-off-by: Jess Frazelle <github@jessfraz.com>

start of folding

Signed-off-by: Jess Frazelle <github@jessfraz.com>

updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

get rid of old re-execute

Signed-off-by: Jess Frazelle <github@jessfraz.com>

updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu)

lint

Signed-off-by: Jess Frazelle <github@jessfraz.com>

fixes

Signed-off-by: Jess Frazelle <github@jessfraz.com>

test for recast bug fixed

Signed-off-by: Jess Frazelle <github@jessfraz.com>

A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu)

fixes

Signed-off-by: Jess Frazelle <github@jessfraz.com>

udpates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

fix rust test

Signed-off-by: Jess Frazelle <github@jessfraz.com>

A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu)

updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

fix

Signed-off-by: Jess Frazelle <github@jessfraz.com>

updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu)

recreate the planes

Signed-off-by: Jess Frazelle <github@jessfraz.com>

console

Signed-off-by: Jess Frazelle <github@jessfraz.com>

A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu)

get rid of unnessary executions

Signed-off-by: Jess Frazelle <github@jessfraz.com>

add test

Signed-off-by: Jess Frazelle <github@jessfraz.com>

add test

Signed-off-by: Jess Frazelle <github@jessfraz.com>

get rid of unnessary executions

Signed-off-by: Jess Frazelle <github@jessfraz.com>

updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

fix race on engine execute

Signed-off-by: Jess Frazelle <github@jessfraz.com>

updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

better naming;

Signed-off-by: Jess Frazelle <github@jessfraz.com>

fix planes

Signed-off-by: Jess Frazelle <github@jessfraz.com>

updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

errors pane

Signed-off-by: Jess Frazelle <github@jessfraz.com>

add errors for tokenizer

Signed-off-by: Jess Frazelle <github@jessfraz.com>

fix docs

Signed-off-by: Jess Frazelle <github@jessfraz.com>

updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

fixes

Signed-off-by: Jess Frazelle <github@jessfraz.com>

updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

fix tests

Signed-off-by: Jess Frazelle <github@jessfraz.com>

updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

planes in engine

Signed-off-by: Jess Frazelle <github@jessfraz.com>

use the default planes

Signed-off-by: Jess Frazelle <github@jessfraz.com>

better size

Signed-off-by: Jess Frazelle <github@jessfraz.com>

updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

fixes

Signed-off-by: Jess Frazelle <github@jessfraz.com>

updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

fix tests

Signed-off-by: Jess Frazelle <github@jessfraz.com>

ffix load local storage

Signed-off-by: Jess Frazelle <github@jessfraz.com>

fix

Signed-off-by: Jess Frazelle <github@jessfraz.com>

dont wait for execute on exit

Signed-off-by: Jess Frazelle <github@jessfraz.com>

A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu)

add back in bs

Signed-off-by: Jess Frazelle <github@jessfraz.com>

Revert "dont wait for execute on exit"

This reverts commit efcaca150ae589ba6ac293765b8302d0fd0c3bf8.

A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu)

updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu)

updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

add endpoint for setcanexecute

Signed-off-by: Jess Frazelle <github@jessfraz.com>

A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu)

fixed tests

Signed-off-by: Jess Frazelle <github@jessfraz.com>

fix tests

Signed-off-by: Jess Frazelle <github@jessfraz.com>

A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu)

updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

add back in debounce for now

Signed-off-by: Jess Frazelle <github@jessfraz.com>

updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

better debounce

Signed-off-by: Jess Frazelle <github@jessfraz.com>

A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu)

updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

Bump syn from 2.0.58 to 2.0.59 in /src/wasm-lib (#2106)

Bumps [syn](https://github.com/dtolnay/syn) from 2.0.58 to 2.0.59.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/2.0.58...2.0.59)

---
updated-dependencies:
- dependency-name: syn
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu)

updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu)

mepty

A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu)

empty

updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

Bump vitest from 1.4.0 to 1.5.0 (#2111)

Bumps [vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest) from 1.4.0 to 1.5.0.
- [Release notes](https://github.com/vitest-dev/vitest/releases)
- [Commits](https://github.com/vitest-dev/vitest/commits/v1.5.0/packages/vitest)

---
updated-dependencies:
- dependency-name: vitest
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

Bump @testing-library/react from 15.0.1 to 15.0.2 (#2112)

Bumps [@testing-library/react](https://github.com/testing-library/react-testing-library) from 15.0.1 to 15.0.2.
- [Release notes](https://github.com/testing-library/react-testing-library/releases)
- [Changelog](https://github.com/testing-library/react-testing-library/blob/main/CHANGELOG.md)
- [Commits](https://github.com/testing-library/react-testing-library/compare/v15.0.1...v15.0.2)

---
updated-dependencies:
- dependency-name: "@testing-library/react"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

Bump @wdio/mocha-framework from 8.35.0 to 8.36.0 (#2110)

Bumps [@wdio/mocha-framework](https://github.com/webdriverio/webdriverio/tree/HEAD/packages/wdio-mocha-framework) from 8.35.0 to 8.36.0.
- [Release notes](https://github.com/webdriverio/webdriverio/releases)
- [Changelog](https://github.com/webdriverio/webdriverio/blob/main/CHANGELOG.md)
- [Commits](https://github.com/webdriverio/webdriverio/commits/v8.36.0/packages/wdio-mocha-framework)

---
updated-dependencies:
- dependency-name: "@wdio/mocha-framework"
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu)

empty

updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

deferrer

Signed-off-by: Jess Frazelle <github@jessfraz.com>
2024-04-15 17:23:23 -07:00
19 changed files with 91 additions and 227 deletions

View File

@ -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()

View File

@ -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()

View File

@ -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
) )

View File

@ -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))

View File

@ -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(),

View File

@ -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),
}, },

View File

@ -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(

View File

@ -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: () => {

View File

@ -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(
}, },
}, },
], ],
}) }))
} }

View File

@ -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: () => {

View File

@ -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

View File

@ -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))

View File

@ -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: {

View File

@ -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',
], ],
}, },

View File

@ -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])

View File

@ -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"

View File

@ -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 (

View File

@ -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,

View File

@ -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(),