Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

start of fixing changing files and cleaning up after execute #897

Merged
merged 5 commits into from
Nov 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 0 additions & 21 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useEffect, useCallback, MouseEventHandler } from 'react'

Check warning on line 1 in src/App.tsx

View workflow job for this annotation

GitHub Actions / build-test-apps (macos-latest)

'useEffect' is defined but never used

Check warning on line 1 in src/App.tsx

View workflow job for this annotation

GitHub Actions / build-test-apps (ubuntu-latest)

'useEffect' is defined but never used

Check warning on line 1 in src/App.tsx

View workflow job for this annotation

GitHub Actions / build-test-apps (windows-latest)

'useEffect' is defined but never used
import { DebugPanel } from './components/DebugPanel'
import { v4 as uuidv4 } from 'uuid'
import { PaneType, useStore } from './useStore'
Expand All @@ -19,7 +19,7 @@
} from '@fortawesome/free-solid-svg-icons'
import { useHotkeys } from 'react-hotkeys-hook'
import { getNormalisedCoordinates } from './lib/utils'
import { isTauri } from './lib/isTauri'

Check warning on line 22 in src/App.tsx

View workflow job for this annotation

GitHub Actions / build-test-apps (macos-latest)

'isTauri' is defined but never used

Check warning on line 22 in src/App.tsx

View workflow job for this annotation

GitHub Actions / build-test-apps (ubuntu-latest)

'isTauri' is defined but never used

Check warning on line 22 in src/App.tsx

View workflow job for this annotation

GitHub Actions / build-test-apps (windows-latest)

'isTauri' is defined but never used
import { useLoaderData } from 'react-router-dom'
import { IndexLoaderData } from './Router'
import { useGlobalStateContext } from 'hooks/useGlobalStateContext'
Expand All @@ -31,11 +31,10 @@
import { Themes, getSystemTheme } from 'lib/theme'
import { useEngineConnectionSubscriptions } from 'hooks/useEngineConnectionSubscriptions'
import { engineCommandManager } from './lang/std/engineConnection'
import { kclManager } from 'lang/KclSinglton'
import { useModelingContext } from 'hooks/useModelingContext'

export function App() {
const { code: loadedCode, project, file } = useLoaderData() as IndexLoaderData

Check warning on line 37 in src/App.tsx

View workflow job for this annotation

GitHub Actions / build-test-apps (macos-latest)

'loadedCode' is assigned a value but never used

Check warning on line 37 in src/App.tsx

View workflow job for this annotation

GitHub Actions / build-test-apps (ubuntu-latest)

'loadedCode' is assigned a value but never used

Check warning on line 37 in src/App.tsx

View workflow job for this annotation

GitHub Actions / build-test-apps (windows-latest)

'loadedCode' is assigned a value but never used

useHotKeyListener()
const {
Expand Down Expand Up @@ -82,26 +81,6 @@
? 'opacity-40'
: ''

// Use file code loaded from disk
// on mount, and overwrite any locally-stored code
useEffect(() => {
if (isTauri() && loadedCode !== null) {
if (kclManager.engineCommandManager.engineConnection?.isReady()) {
// If the engine is ready, promptly execute the loaded code
kclManager.setCodeAndExecute(loadedCode)
} else {
// Otherwise, just set the code and wait for the connection to complete
kclManager.setCode(loadedCode)
}
}
return () => {
// Clear code on unmount if in desktop app
if (isTauri()) {
kclManager.setCode('')
}
}
}, [loadedCode])

useEngineConnectionSubscriptions()

const debounceSocketSend = throttle<EngineCommand>((message) => {
Expand Down
3 changes: 2 additions & 1 deletion src/Router.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ import CommandBarProvider from 'components/CommandBar'
import { TEST, VITE_KC_SENTRY_DSN } from './env'
import * as Sentry from '@sentry/react'
import ModelingMachineProvider from 'components/ModelingMachineProvider'
import { KclContextProvider } from 'lang/KclSinglton'
import { KclContextProvider, kclManager } from 'lang/KclSinglton'
import FileMachineProvider from 'components/FileMachineProvider'
import { sep } from '@tauri-apps/api/path'

Expand Down Expand Up @@ -207,6 +207,7 @@ const router = createBrowserRouter(
projectPath + sep + PROJECT_ENTRYPOINT
)
const children = await readDir(projectPath, { recursive: true })
kclManager.setCodeAndExecute(code, false)
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


return {
code,
Expand Down
29 changes: 18 additions & 11 deletions src/components/AvailableVarsHelpers.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useEffect, useState, useRef } from 'react'
import { parse, BinaryPart, Value, executor } from '../lang/wasm'
import { parse, BinaryPart, Value } from '../lang/wasm'
import {
createIdentifier,
createLiteral,
Expand All @@ -10,6 +10,7 @@ import { findAllPreviousVariables, PrevVariable } from '../lang/queryAst'
import { engineCommandManager } from '../lang/std/engineConnection'
import { kclManager, useKclContext } from 'lang/KclSinglton'
import { useModelingContext } from 'hooks/useModelingContext'
import { executeAst } from 'useStore'

export const AvailableVars = ({
onVarClick,
Expand Down Expand Up @@ -130,27 +131,29 @@ export function useCalc({
if (!programMemory || !selectionRange) return
const varInfo = findAllPreviousVariables(
kclManager.ast,
programMemory,
kclManager.programMemory,
selectionRange
)
setAvailableVarInfo(varInfo)
}, [kclManager.ast, programMemory, selectionRange])
}, [kclManager.ast, kclManager.programMemory, selectionRange])

useEffect(() => {
try {
const code = `const __result__ = ${value}\nshow(__result__)`
const code = `const __result__ = ${value}`
const ast = parse(code)
const _programMem: any = { root: {}, return: null }
availableVarInfo.variables.forEach(({ key, value }) => {
_programMem.root[key] = { type: 'userVal', value, __meta: [] }
})

executor(
executeAst({
ast,
_programMem,
engineCommandManager,
kclManager.defaultPlanes
).then((programMemory) => {
defaultPlanes: kclManager.defaultPlanes,
useFakeExecutor: true,
programMemoryOverride: JSON.parse(
JSON.stringify(kclManager.programMemory)
),
}).then(({ programMemory }) => {
const resultDeclaration = ast.body.find(
(a) =>
a.type === 'VariableDeclaration' &&
Expand All @@ -167,7 +170,7 @@ export function useCalc({
setCalcResult('NAN')
setValueNode(null)
}
}, [value])
}, [value, availableVarInfo])

return {
valueNode,
Expand Down Expand Up @@ -212,7 +215,10 @@ export const CreateNewVariable = ({
}) => {
return (
<>
<label htmlFor="create-new-variable" className="block mt-3 font-mono">
<label
htmlFor="create-new-variable"
className="block mt-3 font-mono text-gray-900"
>
Create new variable
</label>
<div className="mt-1 flex gap-2 items-center">
Expand All @@ -223,6 +229,7 @@ export const CreateNewVariable = ({
onChange={(e) => {
setShouldCreateVariable(e.target.checked)
}}
className="bg-white text-gray-900"
/>
)}
<input
Expand Down
1 change: 0 additions & 1 deletion src/components/FileTree.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,6 @@ const FileTreeItem = ({

function openFile() {
if (fileOrDir.children !== undefined) return // Don't open directories
kclManager.setCode('')
navigate(`${paths.FILE}/${encodeURIComponent(fileOrDir.path)}`)
closePanel()
}
Expand Down
2 changes: 1 addition & 1 deletion src/components/ModelingMachineProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ export const ModelingMachineProvider = ({
engineCommandManager.artifactMap[sketchEnginePathId] = {
type: 'result',
range: [startProfileAtCallExp.start, startProfileAtCallExp.end],
commandType: 'extend_path',
commandType: 'start_path',
data: null,
raw: {} as any,
}
Expand Down
4 changes: 2 additions & 2 deletions src/components/SetAngleLengthModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ export const SetAngleLengthModal = ({
</label>
<div className="mt-1 flex">
<button
className="border border-gray-300 px-2"
className="border border-gray-300 px-2 text-gray-900"
onClick={() => setSign(-sign)}
>
{sign > 0 ? '+' : '-'}
Expand All @@ -118,7 +118,7 @@ export const SetAngleLengthModal = ({
type="text"
name="val"
id="val"
className="shadow-sm focus:ring-blue-500 focus:border-blue-500 block w-full sm:text-sm border-gray-300 rounded-md font-mono pl-1"
className="shadow-sm focus:ring-blue-500 focus:border-blue-500 block w-full sm:text-sm border-gray-300 rounded-md font-mono pl-1 text-gray-900"
value={value}
onChange={(e) => {
setValue(e.target.value)
Expand Down
8 changes: 4 additions & 4 deletions src/components/SetHorVertDistanceModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ export const GetInfoModal = ({
leaveFrom="opacity-100 scale-100"
leaveTo="opacity-0 scale-95"
>
<Dialog.Panel className="w-full max-w-md transform overflow-hidden rounded-2xl bg-white p-6 text-left align-middle shadow-xl transition-all">
<Dialog.Panel className="w-full max-w-md transform overflow-hidden rounded-2xl bg-white/90 p-6 text-left align-middle shadow-xl transition-all">
<Dialog.Title
as="h3"
className="text-lg font-medium leading-6 text-gray-900"
Expand All @@ -109,7 +109,7 @@ export const GetInfoModal = ({
</label>
<div className="mt-1 flex">
<button
className="border border-gray-300 px-2 mr-1"
className="border border-gray-400 px-2 mr-1 text-gray-900"
onClick={() => setSign(-sign)}
>
{sign > 0 ? '+' : '-'}
Expand All @@ -119,7 +119,7 @@ export const GetInfoModal = ({
name="val"
id="val"
ref={inputRef}
className="shadow-sm focus:ring-blue-500 focus:border-blue-500 block w-full sm:text-sm border-gray-300 rounded-md font-mono"
className="shadow-sm focus:ring-blue-500 focus:border-blue-500 block w-full sm:text-sm text-gray-900 border-gray-300 rounded-md font-mono"
value={value}
onChange={(e) => {
setValue(e.target.value)
Expand All @@ -139,7 +139,7 @@ export const GetInfoModal = ({
name="segName"
id="segName"
disabled={!isSegNameEditable}
className="shadow-sm focus:ring-blue-500 focus:border-blue-500 block w-full sm:text-sm border-gray-300 rounded-md font-mono"
className="shadow-sm focus:ring-blue-500 focus:border-blue-500 block w-full sm:text-sm text-gray-900 border-gray-300 rounded-md font-mono"
value={segName}
onChange={(e) => {
setSegName(e.target.value)
Expand Down
23 changes: 1 addition & 22 deletions src/components/TextEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,7 @@
import { processCodeMirrorRanges } from 'lib/selections'
import { LanguageServerClient } from 'editor/lsp'
import kclLanguage from 'editor/lsp/language'
import { isTauri } from 'lib/isTauri'
import { useParams } from 'react-router-dom'
import { writeTextFile } from '@tauri-apps/api/fs'
import { toast } from 'react-hot-toast'
import {
EditorView,
addLineHighlight,
lineHighlightField,
} from 'editor/highlightextension'
import { EditorView, lineHighlightField } from 'editor/highlightextension'
import { roundOff } from 'lib/utils'
import { kclErrToDiagnostic } from 'lang/errors'
import { CSSRuleObject } from 'tailwindcss/types/config'
Expand All @@ -50,7 +42,6 @@
}: {
theme: Themes.Light | Themes.Dark
}) => {
const pathParams = useParams()
const { editorView, isLSPServerReady, setEditorView, setIsLSPServerReady } =
useStore((s) => ({
editorView: s.editorView,
Expand Down Expand Up @@ -113,18 +104,6 @@
// const onChange = React.useCallback((value: string, viewUpdate: ViewUpdate) => {
const onChange = (newCode: string) => {
kclManager.setCodeAndExecute(newCode)
if (isTauri() && pathParams.id) {
// Save the file to disk
// Note that PROJECT_ENTRYPOINT is hardcoded until we support multiple files
writeTextFile(pathParams.id, newCode).catch((err) => {
// TODO: add Sentry per GH issue #254 (https://github.com/KittyCAD/modeling-app/issues/254)
console.error('error saving file', err)
toast.error('Error saving file, please check file permissions')
})
}
if (editorView) {
editorView?.dispatch({ effects: addLineHighlight.of([0, 0]) })
}
Comment on lines 106 to -127
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

kclManager.setCodeAndExecute(newCode) handles saving the file too now, hence why all this could be deleted.

} //, []);
const onUpdate = (viewUpdate: ViewUpdate) => {
if (!editorView) {
Expand Down Expand Up @@ -220,7 +199,7 @@
}

return extensions
}, [kclLSP, textWrapping, convertCallback])

Check warning on line 202 in src/components/TextEditor.tsx

View workflow job for this annotation

GitHub Actions / build-test-apps (macos-latest)

React Hook useMemo has missing dependencies: 'convertEnabled', 'errors', and 'setCommandBarOpen'. Either include them or remove the dependency array

Check warning on line 202 in src/components/TextEditor.tsx

View workflow job for this annotation

GitHub Actions / build-test-apps (ubuntu-latest)

React Hook useMemo has missing dependencies: 'convertEnabled', 'errors', and 'setCommandBarOpen'. Either include them or remove the dependency array

Check warning on line 202 in src/components/TextEditor.tsx

View workflow job for this annotation

GitHub Actions / build-test-apps (windows-latest)

React Hook useMemo has missing dependencies: 'convertEnabled', 'errors', and 'setCommandBarOpen'. Either include them or remove the dependency array

return (
<div
Expand Down
59 changes: 47 additions & 12 deletions src/lang/KclSinglton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,11 @@ import { bracket } from 'lib/exampleKcl'
import { createContext, useContext, useEffect, useState } from 'react'
import { getNodeFromPath } from './queryAst'
import { IndexLoaderData } from 'Router'
import { useLoaderData } from 'react-router-dom'
import { Params, useLoaderData } from 'react-router-dom'
import { isTauri } from 'lib/isTauri'
import { writeTextFile } from '@tauri-apps/api/fs'
import { toast } from 'react-hot-toast'
import { useParams } from 'react-router-dom'

const PERSIST_CODE_TOKEN = 'persistCode'

Expand All @@ -41,6 +45,7 @@ class KclManager {
private _kclErrors: KCLError[] = []
private _isExecuting = false
private _wasmInitFailed = true
private _params: Params<string> = {}

engineCommandManager: EngineCommandManager
private _defferer = deferExecution((code: string) => {
Expand Down Expand Up @@ -71,6 +76,21 @@ class KclManager {
set code(code) {
this._code = code
this._codeCallBack(code)
if (isTauri()) {
setTimeout(() => {
// Wait one event loop to give a chance for params to be set
// Save the file to disk
// Note that PROJECT_ENTRYPOINT is hardcoded until we support multiple files
this._params.id &&
writeTextFile(this._params.id, code).catch((err) => {
// TODO: add Sentry per GH issue #254 (https://github.com/KittyCAD/modeling-app/issues/254)
console.error('error saving file', err)
toast.error('Error saving file, please check file permissions')
})
})
} else {
localStorage.setItem(PERSIST_CODE_TOKEN, code)
}
}

get programMemory() {
Expand Down Expand Up @@ -117,8 +137,17 @@ class KclManager {
this._wasmInitFailedCallback(wasmInitFailed)
}

setParams(params: Params<string>) {
this._params = params
}

constructor(engineCommandManager: EngineCommandManager) {
this.engineCommandManager = engineCommandManager

if (isTauri()) {
this.code = ''
return
}
const storedCode = localStorage.getItem(PERSIST_CODE_TOKEN)
// TODO #819 remove zustand persistence logic in a few months
// short term migration, shouldn't make a difference for tauri app users
Expand All @@ -130,6 +159,7 @@ class KclManager {
zustandStore.state.code = ''
localStorage.setItem('store', JSON.stringify(zustandStore))
} else if (storedCode === null) {
console.log('stored brack thing')
this.code = bracket
} else {
this.code = storedCode
Expand Down Expand Up @@ -189,8 +219,7 @@ class KclManager {
this._programMemory = programMemory
this._ast = { ...ast }
if (updateCode) {
this._code = recast(ast)
this._codeCallBack(this._code)
this.code = recast(ast)
}
this._executeCallback()
}
Expand Down Expand Up @@ -233,13 +262,17 @@ class KclManager {
this.ast = ast
if (code) this.code = code
}
setCode(code: string) {
setCode(code: string, shouldWriteFile = true) {
if (shouldWriteFile) {
// use the normal code setter
this.code = code
return
}
this._code = code
this._codeCallBack(code)
localStorage.setItem(PERSIST_CODE_TOKEN, code)
}
setCodeAndExecute(code: string) {
this.setCode(code)
setCodeAndExecute(code: string, shouldWriteFile = true) {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generally, when the code is updated we want to save the file as well. Except when the file is first loaded because the user opened a project.

this.setCode(code, shouldWriteFile)
if (code.trim()) {
this._defferer(code)
return
Expand Down Expand Up @@ -270,15 +303,12 @@ class KclManager {
execute: boolean,
optionalParams?: {
focusPath?: PathToNode
callBack?: (ast: Program) => void
}
): Promise<Selections | null> {
const newCode = recast(ast)
const astWithUpdatedSource = parse(newCode)
optionalParams?.callBack?.(astWithUpdatedSource)
let returnVal: Selections | null = null

this.code = newCode
if (optionalParams?.focusPath) {
const { node } = getNodeFromPath<any>(
astWithUpdatedSource,
Expand All @@ -299,12 +329,12 @@ class KclManager {

if (execute) {
// Call execute on the set ast.
await this.executeAst(astWithUpdatedSource)
await this.executeAst(astWithUpdatedSource, true)
} else {
// 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.
await this.executeAstMock(astWithUpdatedSource)
await this.executeAstMock(astWithUpdatedSource, true)
}
return returnVal
}
Expand Down Expand Up @@ -369,6 +399,11 @@ export function KclContextProvider({
setWasmInitFailed,
})
}, [])

const params = useParams()
useEffect(() => {
kclManager.setParams(params)
}, [params])
return (
<KclContext.Provider
value={{
Expand Down
Loading
Loading