Compare commits

...

15 Commits

Author SHA1 Message Date
2f51763df9 Cut release v0.24.0 (#2972)
* Cut release v0.24.0

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

* Trigger CI

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

* Trigger CI

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

* Trigger CI

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

* Trigger CI

---------

Co-authored-by: Frank Noirot <frank@zoo.dev>
Co-authored-by: Jess Frazelle <jessfraz@users.noreply.github.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-07-09 10:29:08 -04:00
7c4bf8d793 fix when you comment out it should re-execute (#2975)
* fix when you comment out it should re-execute

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>

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

* copilot being a little shit

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

* fix

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

* fix

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

* fmt

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

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

* fix

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>

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

* turn copilot off

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)

* fix for realisesi

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

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

* remove footguns

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

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Kurt Hutten <k.hutten@protonmail.ch>
2024-07-08 21:07:15 -07:00
4747cdcab6 Bump syn from 2.0.69 to 2.0.70 in /src/wasm-lib (#2981)
Bumps [syn](https://github.com/dtolnay/syn) from 2.0.69 to 2.0.70.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/2.0.69...2.0.70)

---
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>
2024-07-08 20:36:30 -07:00
de73f335fe Bump uuid from 1.9.1 to 1.10.0 in /src/wasm-lib (#2980)
Bumps [uuid](https://github.com/uuid-rs/uuid) from 1.9.1 to 1.10.0.
- [Release notes](https://github.com/uuid-rs/uuid/releases)
- [Commits](https://github.com/uuid-rs/uuid/compare/1.9.1...1.10.0)

---
updated-dependencies:
- dependency-name: uuid
  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>
2024-07-08 20:36:19 -07:00
a62004da82 Bump clap from 4.5.7 to 4.5.9 in /src/wasm-lib (#2979)
Bumps [clap](https://github.com/clap-rs/clap) from 4.5.7 to 4.5.9.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/clap_complete-v4.5.7...v4.5.9)

---
updated-dependencies:
- dependency-name: clap
  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>
2024-07-08 20:35:54 -07:00
92e0da1f8d playwright fixmes 😭 (#2977)
* add fixmes 😭

* fmt
2024-07-09 11:11:32 +10:00
a111473658 Uses the grammar marijn made :) (#2967)
* Add a Lezer KCL grammar

* fmt

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

* make tsc happy

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

* turn off semantic tokens in favor of grammar

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

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

* fixups

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

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

* empty

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
Co-authored-by: Marijn Haverbeke <marijn@haverbeke.berlin>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-07-08 16:47:30 -07:00
7cfed9bff4 Add a timeout instead of insta teardown on window hide (#2970)
* Add a timeout instead of insta teardown on window hide

* Close sketch mode on teardown
2024-07-09 07:58:09 +10:00
a30bd185d8 Allow modify sketch when extrude on end of pipe expr (#2960) 2024-07-09 07:57:37 +10:00
e8cae630a1 remove all z_near far params in engine calls, enable ssao again (#2956)
* remove all z_near far params in engine calls, enable ssao again

* fmt
2024-07-09 06:53:33 +10:00
74ec749560 Add segment length indicators to straight segments in sketch mode (#2935)
* Rough impl of line lengths, still duplicating

* Make sure the labels get cleared along with the rest of the sketch

* Show current units in segment length indicators

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

* Re-run CI after snapshots

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

* Re-run CI

* Make sure `close` segments get insert segment handles

* Skip engine connection tests on Safari with a todo

* Fmt

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-07-08 16:41:00 -04:00
ebdaf59d1c Bump pyo3 from 0.22.0 to 0.22.1 in /src/wasm-lib (#2949) 2024-07-08 12:44:55 -07:00
cd68414d54 Bump async-trait from 0.1.80 to 0.1.81 in /src/wasm-lib (#2948) 2024-07-08 12:44:43 -07:00
c8238ff04a Bump syn from 2.0.68 to 2.0.69 in /src/wasm-lib (#2947)
Bumps [syn](https://github.com/dtolnay/syn) from 2.0.68 to 2.0.69.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/2.0.68...2.0.69)

---
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>
2024-07-08 10:00:23 -07:00
8089369108 Bump serde from 1.0.203 to 1.0.204 in /src/wasm-lib (#2946)
Bumps [serde](https://github.com/serde-rs/serde) from 1.0.203 to 1.0.204.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.203...v1.0.204)

---
updated-dependencies:
- dependency-name: serde
  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>
2024-07-08 10:00:13 -07:00
44 changed files with 660 additions and 342 deletions

View File

@ -560,6 +560,50 @@ test.describe('Testing Camera Movement', () => {
})
test.describe('Editor tests', () => {
test('can comment out code with ctrl+/', async ({ page }) => {
const u = await getUtils(page)
await page.setViewportSize({ width: 1000, height: 500 })
await u.waitForAuthSkipAppStart()
const CtrlKey = process.platform === 'darwin' ? 'Meta' : 'Control'
// check no error to begin with
await expect(page.locator('.cm-lint-marker-error')).not.toBeVisible()
await u.codeLocator.click()
await page.keyboard.type(`const sketch001 = startSketchOn('XY')
|> startProfileAt([-10, -10], %)
|> line([20, 0], %)
|> line([0, 20], %)
|> line([-20, 0], %)
|> close(%)`)
await page.keyboard.down(CtrlKey)
await page.keyboard.press('/')
await page.keyboard.up(CtrlKey)
await expect(page.locator('.cm-content'))
.toHaveText(`const sketch001 = startSketchOn('XY')
|> startProfileAt([-10, -10], %)
|> line([20, 0], %)
|> line([0, 20], %)
|> line([-20, 0], %)
// |> close(%)`)
// uncomment the code
await page.keyboard.down(CtrlKey)
await page.keyboard.press('/')
await page.keyboard.up(CtrlKey)
await expect(page.locator('.cm-content'))
.toHaveText(`const sketch001 = startSketchOn('XY')
|> startProfileAt([-10, -10], %)
|> line([20, 0], %)
|> line([0, 20], %)
|> line([-20, 0], %)
|> close(%)`)
})
test('if you click the format button it formats your code', async ({
page,
}) => {
@ -1221,7 +1265,9 @@ test.describe('Editor tests', () => {
|> close(%)`)
})
test('Can undo a sketch modification with ctrl+z', async ({ page }) => {
// failing for the same reason as "Can edit a sketch that has been extruded in the same pipe"
// please fix together
test.fixme('Can undo a sketch modification with ctrl+z', async ({ page }) => {
const u = await getUtils(page)
await page.addInitScript(async () => {
localStorage.setItem(
@ -4070,108 +4116,111 @@ test.describe('Sketch tests', () => {
})
})
test('Can edit a sketch that has been extruded in the same pipe', async ({
page,
}) => {
const u = await getUtils(page)
await page.addInitScript(async () => {
localStorage.setItem(
'persistCode',
`const sketch001 = startSketchOn('XZ')
// failing for the same reason as "Can undo a sketch modification with ctrl+z"
// please fix together
test.fixme(
'Can edit a sketch that has been extruded in the same pipe',
async ({ page }) => {
const u = await getUtils(page)
await page.addInitScript(async () => {
localStorage.setItem(
'persistCode',
`const sketch001 = startSketchOn('XZ')
|> startProfileAt([4.61, -14.01], %)
|> line([12.73, -0.09], %)
|> tangentialArcTo([24.95, -5.38], %)
|> close(%)
|> extrude(5, %)`
)
})
)
})
await page.setViewportSize({ width: 1200, height: 500 })
await page.setViewportSize({ width: 1200, height: 500 })
await u.waitForAuthSkipAppStart()
await expect(
page.getByRole('button', { name: 'Start Sketch' })
).not.toBeDisabled()
await u.waitForAuthSkipAppStart()
await expect(
page.getByRole('button', { name: 'Start Sketch' })
).not.toBeDisabled()
await page.waitForTimeout(100)
await u.openAndClearDebugPanel()
await u.sendCustomCmd({
type: 'modeling_cmd_req',
cmd_id: uuidv4(),
cmd: {
type: 'default_camera_look_at',
vantage: { x: 0, y: -1250, z: 580 },
center: { x: 0, y: 0, z: 0 },
up: { x: 0, y: 0, z: 1 },
},
})
await page.waitForTimeout(100)
await u.sendCustomCmd({
type: 'modeling_cmd_req',
cmd_id: uuidv4(),
cmd: {
type: 'default_camera_get_settings',
},
})
await page.waitForTimeout(100)
await page.waitForTimeout(100)
await u.openAndClearDebugPanel()
await u.sendCustomCmd({
type: 'modeling_cmd_req',
cmd_id: uuidv4(),
cmd: {
type: 'default_camera_look_at',
vantage: { x: 0, y: -1250, z: 580 },
center: { x: 0, y: 0, z: 0 },
up: { x: 0, y: 0, z: 1 },
},
})
await page.waitForTimeout(100)
await u.sendCustomCmd({
type: 'modeling_cmd_req',
cmd_id: uuidv4(),
cmd: {
type: 'default_camera_get_settings',
},
})
await page.waitForTimeout(100)
const startPX = [665, 458]
const startPX = [665, 458]
const dragPX = 40
const dragPX = 40
await page.getByText('startProfileAt([4.61, -14.01], %)').click()
await expect(
page.getByRole('button', { name: 'Edit Sketch' })
).toBeVisible()
await page.getByRole('button', { name: 'Edit Sketch' }).click()
await page.waitForTimeout(400)
let prevContent = await page.locator('.cm-content').innerText()
await page.getByText('startProfileAt([4.61, -14.01], %)').click()
await expect(
page.getByRole('button', { name: 'Edit Sketch' })
).toBeVisible()
await page.getByRole('button', { name: 'Edit Sketch' }).click()
await page.waitForTimeout(400)
let prevContent = await page.locator('.cm-content').innerText()
await expect(page.getByTestId('segment-overlay')).toHaveCount(2)
await expect(page.getByTestId('segment-overlay')).toHaveCount(2)
// drag startProfieAt handle
await page.dragAndDrop('#stream', '#stream', {
sourcePosition: { x: startPX[0], y: startPX[1] },
targetPosition: { x: startPX[0] + dragPX, y: startPX[1] + dragPX },
})
await page.waitForTimeout(100)
await expect(page.locator('.cm-content')).not.toHaveText(prevContent)
prevContent = await page.locator('.cm-content').innerText()
// drag startProfieAt handle
await page.dragAndDrop('#stream', '#stream', {
sourcePosition: { x: startPX[0], y: startPX[1] },
targetPosition: { x: startPX[0] + dragPX, y: startPX[1] + dragPX },
})
await page.waitForTimeout(100)
await expect(page.locator('.cm-content')).not.toHaveText(prevContent)
prevContent = await page.locator('.cm-content').innerText()
// drag line handle
await page.waitForTimeout(100)
// drag line handle
await page.waitForTimeout(100)
const lineEnd = await u.getBoundingBox('[data-overlay-index="0"]')
await page.waitForTimeout(100)
await page.dragAndDrop('#stream', '#stream', {
sourcePosition: { x: lineEnd.x - 5, y: lineEnd.y },
targetPosition: { x: lineEnd.x + dragPX, y: lineEnd.y + dragPX },
})
await expect(page.locator('.cm-content')).not.toHaveText(prevContent)
prevContent = await page.locator('.cm-content').innerText()
const lineEnd = await u.getBoundingBox('[data-overlay-index="0"]')
await page.waitForTimeout(100)
await page.dragAndDrop('#stream', '#stream', {
sourcePosition: { x: lineEnd.x - 5, y: lineEnd.y },
targetPosition: { x: lineEnd.x + dragPX, y: lineEnd.y + dragPX },
})
await expect(page.locator('.cm-content')).not.toHaveText(prevContent)
prevContent = await page.locator('.cm-content').innerText()
// drag tangentialArcTo handle
const tangentEnd = await u.getBoundingBox('[data-overlay-index="1"]')
await page.dragAndDrop('#stream', '#stream', {
sourcePosition: { x: tangentEnd.x, y: tangentEnd.y - 5 },
targetPosition: {
x: tangentEnd.x + dragPX,
y: tangentEnd.y + dragPX,
},
})
await page.waitForTimeout(100)
await expect(page.locator('.cm-content')).not.toHaveText(prevContent)
// drag tangentialArcTo handle
const tangentEnd = await u.getBoundingBox('[data-overlay-index="1"]')
await page.dragAndDrop('#stream', '#stream', {
sourcePosition: { x: tangentEnd.x, y: tangentEnd.y - 5 },
targetPosition: {
x: tangentEnd.x + dragPX,
y: tangentEnd.y + dragPX,
},
})
await page.waitForTimeout(100)
await expect(page.locator('.cm-content')).not.toHaveText(prevContent)
// expect the code to have changed
await expect(page.locator('.cm-content'))
.toHaveText(`const sketch001 = startSketchOn('XZ')
// expect the code to have changed
await expect(page.locator('.cm-content'))
.toHaveText(`const sketch001 = startSketchOn('XZ')
|> startProfileAt([7.12, -16.82], %)
|> line([15.4, -2.74], %)
|> tangentialArcTo([24.95, -5.38], %)
|> line([2.65, -2.69], %)
|> close(%)
|> extrude(5, %)`)
})
}
)
test('Can edit a sketch that has been revolved in the same pipe', async ({
page,
@ -6721,7 +6770,15 @@ ${extraLine ? 'const myVar = segLen(seg01, part001)' : ''}`
})
test.describe('Test network and connection issues', () => {
test('simulate network down and network little widget', async ({ page }) => {
test('simulate network down and network little widget', async ({
page,
browserName,
}) => {
// TODO: Don't skip Mac for these. After `window.tearDown` is working in Safari, these should work on webkit
test.skip(
browserName === 'webkit',
'Skip on Safari until `window.tearDown` is working there'
)
const u = await getUtils(page)
await page.setViewportSize({ width: 1200, height: 500 })
@ -6791,7 +6848,15 @@ test.describe('Test network and connection issues', () => {
await expect(page.getByText('Network Health (Connected)')).toBeVisible()
})
test('Engine disconnect & reconnect in sketch mode', async ({ page }) => {
test('Engine disconnect & reconnect in sketch mode', async ({
page,
browserName,
}) => {
// TODO: Don't skip Mac for these. After `window.tearDown` is working in Safari, these should work on webkit
test.skip(
browserName === 'webkit',
'Skip on Safari until `window.tearDown` is working there'
)
const u = await getUtils(page)
await page.setViewportSize({ width: 1200, height: 500 })
const PUR = 400 / 37.5 //pixeltoUnitRatio

View File

@ -435,6 +435,8 @@ test('Draft segments should look right', async ({ page, context }) => {
await page.mouse.move(startXPx + PUR * 30, 500 - PUR * 20, { steps: 10 })
await page.waitForTimeout(300)
await expect(page).toHaveScreenshot({
maxDiffPixels: 100,
})

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 49 KiB

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 71 KiB

After

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 61 KiB

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 29 KiB

View File

@ -1,6 +1,6 @@
{
"name": "untitled-app",
"version": "0.23.1",
"version": "0.24.0",
"private": true,
"dependencies": {
"@codemirror/autocomplete": "^6.17.0",
@ -17,7 +17,9 @@
"@fortawesome/react-fontawesome": "^0.2.0",
"@headlessui/react": "^1.7.19",
"@headlessui/tailwindcss": "^0.2.0",
"@kittycad/lib": "^0.0.69",
"@kittycad/lib": "^0.0.70",
"@lezer/highlight": "^1.2.0",
"@lezer/lr": "^1.4.1",
"@react-hook/resize-observer": "^2.0.1",
"@replit/codemirror-interact": "^6.3.1",
"@tauri-apps/api": "^2.0.0-beta.14",
@ -109,6 +111,7 @@
"@babel/plugin-proposal-private-property-in-object": "^7.21.11",
"@babel/preset-env": "^7.24.3",
"@iarna/toml": "^2.2.5",
"@lezer/generator": "^1.7.1",
"@playwright/test": "^1.45.1",
"@tauri-apps/cli": "==2.0.0-beta.13",
"@testing-library/jest-dom": "^5.14.1",

View File

@ -71,6 +71,9 @@ export interface LanguageServerOptions {
) => void
changesDelay?: number
doSemanticTokens?: boolean
doFoldingRanges?: boolean
}
export class LanguageServerPlugin implements PluginValue {
@ -87,6 +90,9 @@ export class LanguageServerPlugin implements PluginValue {
notification: LSP.NotificationMessage
) => void
private doSemanticTokens: boolean = false
private doFoldingRanges: boolean = false
private _defferer = deferExecution((code: string) => {
try {
// Update the state (not the editor) with the new code.
@ -109,6 +115,9 @@ export class LanguageServerPlugin implements PluginValue {
this.client = options.client
this.documentVersion = 0
this.doSemanticTokens = options.doSemanticTokens ?? false
this.doFoldingRanges = options.doFoldingRanges ?? false
if (options.changesDelay) {
this.changesDelay = options.changesDelay
}
@ -220,6 +229,7 @@ export class LanguageServerPlugin implements PluginValue {
async getFoldingRanges(): Promise<LSP.FoldingRange[] | null> {
if (
!this.doFoldingRanges ||
!this.client.ready ||
!this.client.getServerCapabilities().foldingRangeProvider
)
@ -445,6 +455,7 @@ export class LanguageServerPlugin implements PluginValue {
async requestSemanticTokens() {
if (
!this.doSemanticTokens ||
!this.client.ready ||
!this.client.getServerCapabilities().semanticTokensProvider
) {

View File

@ -80,5 +80,5 @@
}
},
"productName": "Zoo Modeling App",
"version": "0.23.1"
"version": "0.24.0"
}

View File

@ -529,7 +529,6 @@ export class CameraControls {
parameters: {
fov_y:
this.camera instanceof PerspectiveCamera ? this.camera.fov : 45,
...calculateNearFarFromFOV(this.lastPerspectiveFov),
},
},
})
@ -612,8 +611,6 @@ export class CameraControls {
type: 'default_camera_set_perspective',
parameters: {
fov_y: newFov,
z_near: 0.01,
z_far: 1000,
},
},
})
@ -631,8 +628,6 @@ export class CameraControls {
target: this.target,
}),
fov_y: newFov,
z_near: 0.01,
z_far: 1000,
},
})
}

View File

@ -96,6 +96,7 @@ export const ClientSideScene = ({
if (!canvasRef.current) return
const canvas = canvasRef.current
canvas.appendChild(sceneInfra.renderer.domElement)
canvas.appendChild(sceneInfra.labelRenderer.domElement)
sceneInfra.animate()
canvas.addEventListener('mousemove', sceneInfra.onMouseMove, false)
canvas.addEventListener('mousedown', sceneInfra.onMouseDown, false)

View File

@ -29,6 +29,9 @@ import {
INTERSECTION_PLANE_LAYER,
OnMouseEnterLeaveArgs,
RAYCASTABLE_PLANE,
SEGMENT_LENGTH_LABEL,
SEGMENT_LENGTH_LABEL_OFFSET_PX,
SEGMENT_LENGTH_LABEL_TEXT,
SKETCH_GROUP_SEGMENTS,
SKETCH_LAYER,
X_AXIS,
@ -47,6 +50,7 @@ import {
programMemoryInit,
recast,
SketchGroup,
ExtrudeGroup,
VariableDeclaration,
VariableDeclarator,
} from 'lang/wasm'
@ -102,6 +106,7 @@ import {
} from 'lib/rectangleTool'
import { getThemeColorForThreeJs } from 'lib/theme'
import { err, trap } from 'lib/trap'
import { CSS2DObject } from 'three/examples/jsm/renderers/CSS2DRenderer'
type DraftSegment = 'line' | 'tangentialArcTo'
@ -414,7 +419,7 @@ export class SceneEntities {
}
)
let seg
let seg: Group
const _node1 = getNodeFromPath<CallExpression>(
maybeModdedAst,
segPathToNode,
@ -1075,9 +1080,16 @@ export class SceneEntities {
programMemoryOverride,
})
this.sceneProgramMemory = programMemory
const sketchGroup = programMemory.root[
variableDeclarationName
] as SketchGroup
const maybeSketchGroup = programMemory.root[variableDeclarationName]
let sketchGroup = undefined
if (maybeSketchGroup.type === 'SketchGroup') {
sketchGroup = maybeSketchGroup
} else if ((maybeSketchGroup as ExtrudeGroup).sketchGroup) {
sketchGroup = (maybeSketchGroup as ExtrudeGroup).sketchGroup
}
if (!sketchGroup) return
const sgPaths = sketchGroup.value
const orthoFactor = orthoScale(sceneInfra.camControls.camera)
@ -1302,6 +1314,7 @@ export class SceneEntities {
shape.moveTo(0, (-SEGMENT_WIDTH_PX / 2) * scale) // The width of the line in px (2.4px in this case)
shape.lineTo(0, (SEGMENT_WIDTH_PX / 2) * scale)
const arrowGroup = group.getObjectByName(ARROWHEAD) as Group
const labelGroup = group.getObjectByName(SEGMENT_LENGTH_LABEL) as Group
const length = Math.sqrt(
Math.pow(to[0] - from[0], 2) + Math.pow(to[1] - from[1], 2)
@ -1347,6 +1360,29 @@ export class SceneEntities {
extraSegmentGroup.visible = isHandlesVisible
}
if (labelGroup) {
const labelWrapper = labelGroup.getObjectByName(
SEGMENT_LENGTH_LABEL_TEXT
) as CSS2DObject
const labelWrapperElem = labelWrapper.element as HTMLDivElement
const label = labelWrapperElem.children[0] as HTMLParagraphElement
label.innerText = `${roundOff(length)}${sceneInfra._baseUnit}`
label.classList.add(SEGMENT_LENGTH_LABEL_TEXT)
const offsetFromMidpoint = new Vector2(to[0] - from[0], to[1] - from[1])
.normalize()
.rotateAround(new Vector2(0, 0), Math.PI / 2)
.multiplyScalar(SEGMENT_LENGTH_LABEL_OFFSET_PX * scale)
label.style.setProperty('--x', `${offsetFromMidpoint.x}px`)
label.style.setProperty('--y', `${offsetFromMidpoint.y}px`)
labelWrapper.position.set(
(from[0] + to[0]) / 2 + offsetFromMidpoint.x,
(from[1] + to[1]) / 2 + offsetFromMidpoint.y,
0
)
labelGroup.visible = isHandlesVisible
}
const straightSegmentBody = group.children.find(
(child) => child.userData.type === STRAIGHT_SEGMENT_BODY
) as Mesh
@ -1397,6 +1433,14 @@ export class SceneEntities {
)
let shouldResolve = false
if (sketchSegments) {
// We have to manually remove the CSS2DObjects
// as they don't get removed when the group is removed
sketchSegments.traverse((object) => {
if (object instanceof CSS2DObject) {
object.element.remove()
object.remove()
}
})
this.scene.remove(sketchSegments)
shouldResolve = true
} else {

View File

@ -31,6 +31,7 @@ import { EngineCommandManager } from 'lang/std/engineConnection'
import { MouseState, SegmentOverlayPayload } from 'machines/modelingMachine'
import { getAngle, throttle } from 'lib/utils'
import { Themes } from 'lib/theme'
import { CSS2DRenderer } from 'three/examples/jsm/renderers/CSS2DRenderer'
type SendType = ReturnType<typeof useModelingContext>['send']
@ -54,6 +55,9 @@ export const Y_AXIS = 'yAxis'
export const AXIS_GROUP = 'axisGroup'
export const SKETCH_GROUP_SEGMENTS = 'sketch-group-segments'
export const ARROWHEAD = 'arrowhead'
export const SEGMENT_LENGTH_LABEL = 'segment-length-label'
export const SEGMENT_LENGTH_LABEL_TEXT = 'segment-length-label-text'
export const SEGMENT_LENGTH_LABEL_OFFSET_PX = 30
export interface OnMouseEnterLeaveArgs {
selected: Object3D<Object3DEventMap>
@ -95,6 +99,7 @@ export class SceneInfra {
static instance: SceneInfra
scene: Scene
renderer: WebGLRenderer
labelRenderer: CSS2DRenderer
camControls: CameraControls
isPerspective = true
fov = 45
@ -264,6 +269,13 @@ export class SceneInfra {
this.renderer = new WebGLRenderer({ antialias: true, alpha: true }) // Enable transparency
this.renderer.setSize(window.innerWidth, window.innerHeight)
this.renderer.setClearColor(0x000000, 0) // Set clear color to black with 0 alpha (fully transparent)
// LABEL RENDERER
this.labelRenderer = new CSS2DRenderer()
this.labelRenderer.setSize(window.innerWidth, window.innerHeight)
this.labelRenderer.domElement.style.position = 'absolute'
this.labelRenderer.domElement.style.top = '0px'
this.labelRenderer.domElement.style.pointerEvents = 'none'
window.addEventListener('resize', this.onWindowResize)
this.camControls = new CameraControls(
@ -328,6 +340,7 @@ export class SceneInfra {
onWindowResize = () => {
this.renderer.setSize(window.innerWidth, window.innerHeight)
this.labelRenderer.setSize(window.innerWidth, window.innerHeight)
}
animate = () => {
@ -337,6 +350,7 @@ export class SceneInfra {
// console.log('animation frame', this.cameraControls.camera)
this.camControls.update()
this.renderer.render(this.scene, this.camControls.camera)
this.labelRenderer.render(this.scene, this.camControls.camera)
}
}

View File

@ -21,6 +21,7 @@ import {
Vector3,
} from 'three'
import { mergeGeometries } from 'three/examples/jsm/utils/BufferGeometryUtils.js'
import { CSS2DObject } from 'three/examples/jsm/renderers/CSS2DRenderer'
import { PathToNode, SketchGroup, getTangentialArcToInfo } from 'lang/wasm'
import {
EXTRA_SEGMENT_HANDLE,
@ -36,8 +37,14 @@ import {
TANGENTIAL_ARC_TO__SEGMENT_DASH,
} from './sceneEntities'
import { getTangentPointFromPreviousArc } from 'lib/utils2d'
import { ARROWHEAD } from './sceneInfra'
import {
ARROWHEAD,
SEGMENT_LENGTH_LABEL,
SEGMENT_LENGTH_LABEL_OFFSET_PX,
SEGMENT_LENGTH_LABEL_TEXT,
} from './sceneInfra'
import { Themes, getThemeColorForThreeJs } from 'lib/theme'
import { roundOff } from 'lib/utils'
export function profileStart({
from,
@ -101,7 +108,7 @@ export function straightSegment({
theme: Themes
isSelected?: boolean
}): Group {
const group = new Group()
const segmentGroup = new Group()
const shape = new Shape()
shape.moveTo(0, (-SEGMENT_WIDTH_PX / 2) * scale)
@ -133,7 +140,7 @@ export function straightSegment({
: STRAIGHT_SEGMENT_BODY
mesh.name = STRAIGHT_SEGMENT_BODY
group.userData = {
segmentGroup.userData = {
type: STRAIGHT_SEGMENT,
id,
from,
@ -143,37 +150,60 @@ export function straightSegment({
callExpName,
baseColor,
}
group.name = STRAIGHT_SEGMENT
segmentGroup.name = STRAIGHT_SEGMENT
segmentGroup.add(mesh)
const length = Math.sqrt(
Math.pow(to[0] - from[0], 2) + Math.pow(to[1] - from[1], 2)
)
const arrowGroup = createArrowhead(scale, theme, color)
arrowGroup.position.set(to[0], to[1], 0)
const dir = new Vector3()
.subVectors(new Vector3(to[0], to[1], 0), new Vector3(from[0], from[1], 0))
.normalize()
arrowGroup.quaternion.setFromUnitVectors(new Vector3(0, 1, 0), dir)
const pxLength = length / scale
const shouldHide = pxLength < HIDE_SEGMENT_LENGTH
arrowGroup.visible = !shouldHide
group.add(mesh)
if (callExpName !== 'close') group.add(arrowGroup)
// All segment types get an extra segment handle,
// Which is a little plus sign that appears at the origin of the segment
// and can be dragged to insert a new segment
const extraSegmentGroup = createExtraSegmentHandle(scale, texture, theme)
const offsetFromBase = new Vector2(to[0] - from[0], to[1] - from[1])
.normalize()
.multiplyScalar(EXTRA_SEGMENT_OFFSET_PX * scale)
const directionVector = new Vector2(
to[0] - from[0],
to[1] - from[1]
).normalize()
const offsetFromBase = directionVector.multiplyScalar(
EXTRA_SEGMENT_OFFSET_PX * scale
)
extraSegmentGroup.position.set(
from[0] + offsetFromBase.x,
from[1] + offsetFromBase.y,
0
)
extraSegmentGroup.visible = !shouldHide
group.add(extraSegmentGroup)
segmentGroup.add(extraSegmentGroup)
return group
// Segment decorators that only apply to non-close segments
if (callExpName !== 'close') {
// an arrowhead that appears at the end of the segment
const arrowGroup = createArrowhead(scale, theme, color)
arrowGroup.position.set(to[0], to[1], 0)
const dir = new Vector3()
.subVectors(
new Vector3(to[0], to[1], 0),
new Vector3(from[0], from[1], 0)
)
.normalize()
arrowGroup.quaternion.setFromUnitVectors(new Vector3(0, 1, 0), dir)
arrowGroup.visible = !shouldHide
segmentGroup.add(arrowGroup)
// A length indicator that appears at the midpoint of the segment
const lengthIndicatorGroup = createLengthIndicator({
from,
to,
scale,
length,
})
segmentGroup.add(lengthIndicatorGroup)
}
return segmentGroup
}
function createArrowhead(scale = 1, theme: Themes, color?: number): Group {
@ -230,6 +260,46 @@ function createExtraSegmentHandle(
return extraSegmentGroup
}
/**
* Creates a group containing a CSS2DObject with the length of the segment
*/
function createLengthIndicator({
from,
to,
scale,
length,
}: {
from: Coords2d
to: Coords2d
scale: number
length: number
}) {
const lengthIndicatorGroup = new Group()
lengthIndicatorGroup.name = SEGMENT_LENGTH_LABEL
// Make the elements
const lengthIndicatorText = document.createElement('p')
lengthIndicatorText.classList.add(SEGMENT_LENGTH_LABEL_TEXT)
lengthIndicatorText.innerText = roundOff(length).toString()
const lengthIndicatorWrapper = document.createElement('div')
// Style the elements
lengthIndicatorWrapper.style.position = 'absolute'
lengthIndicatorWrapper.appendChild(lengthIndicatorText)
const cssObject = new CSS2DObject(lengthIndicatorWrapper)
cssObject.name = SEGMENT_LENGTH_LABEL_TEXT
// Position the elements based on the line's heading
const offsetFromMidpoint = new Vector2(to[0] - from[0], to[1] - from[1])
.normalize()
.rotateAround(new Vector2(0, 0), -Math.PI / 2)
.multiplyScalar(SEGMENT_LENGTH_LABEL_OFFSET_PX * scale)
lengthIndicatorText.style.setProperty('--x', `${offsetFromMidpoint.x}px`)
lengthIndicatorText.style.setProperty('--y', `${offsetFromMidpoint.y}px`)
lengthIndicatorGroup.add(cssObject)
return lengthIndicatorGroup
}
export function tangentialArcToSegment({
prevSegment,
from,

View File

@ -8,7 +8,7 @@ import {
LanguageServerPlugin,
} from '@kittycad/codemirror-lsp-client'
import { TEST, VITE_KC_API_BASE_URL } from 'env'
import KclLanguageSupport from 'editor/plugins/lsp/kcl/language'
import { kcl } from 'editor/plugins/lsp/kcl/language'
import { copilotPlugin } from 'editor/plugins/lsp/copilot'
import { useSettingsAuthContext } from 'hooks/useSettingsAuthContext'
import { Extension } from '@codemirror/state'
@ -146,7 +146,7 @@ export const LspProvider = ({ children }: { children: React.ReactNode }) => {
let plugin = null
if (isKclLspReady && !TEST && kclLspClient) {
// Set up the lsp plugin.
const lsp = new KclLanguageSupport({
const lsp = kcl({
documentUri: `file:///${PROJECT_ENTRYPOINT}`,
workspaceFolders: getWorkspaceFolders(),
client: kclLspClient,

View File

@ -8,7 +8,7 @@ import { NetworkHealthState } from 'hooks/useNetworkStatus'
import { ClientSideScene } from 'clientSideScene/ClientSideSceneComp'
import { butName } from 'lib/cameraControls'
import { sendSelectEventToEngine } from 'lib/selections'
import { kclManager, engineCommandManager } from 'lib/singletons'
import { kclManager, engineCommandManager, sceneInfra } from 'lib/singletons'
export const Stream = () => {
const [isLoading, setIsLoading] = useState(true)
@ -51,40 +51,42 @@ export const Stream = () => {
capture: true,
})
// Teardown everything if we go hidden or reconnect
if (globalThis?.window?.document) {
globalThis.window.document.onvisibilitychange = () => {
if (globalThis.window.document.visibilityState === 'hidden') {
videoRef.current?.pause()
setIsFreezeFrame(true)
window.requestAnimationFrame(() => {
engineCommandManager.engineConnection?.tearDown({ freeze: true })
})
} else {
engineCommandManager.engineConnection?.connect(true)
}
}
}
const IDLE_TIME_MS = 1000 * 20
let timeoutIdIdle: ReturnType<typeof setTimeout> | undefined = undefined
let timeoutIdIdleA: ReturnType<typeof setTimeout> | undefined = undefined
const onIdle = () => {
const teardown = () => {
videoRef.current?.pause()
setIsFreezeFrame(true)
kclManager.isFirstRender = true
setIsFirstRender(true)
sceneInfra.modelingSend({ type: 'Cancel' })
// Give video time to pause
window.requestAnimationFrame(() => {
engineCommandManager.engineConnection?.tearDown({ freeze: true })
})
}
// Teardown everything if we go hidden or reconnect
if (globalThis?.window?.document) {
globalThis.window.document.onvisibilitychange = () => {
if (globalThis.window.document.visibilityState === 'hidden') {
clearTimeout(timeoutIdIdleA)
timeoutIdIdleA = setTimeout(teardown, IDLE_TIME_MS)
} else if (!engineCommandManager.engineConnection?.isReady()) {
clearTimeout(timeoutIdIdleA)
engineCommandManager.engineConnection?.connect(true)
}
}
}
let timeoutIdIdleB: ReturnType<typeof setTimeout> | undefined = undefined
const onAnyInput = () => {
if (!engineCommandManager.engineConnection?.isReady()) {
engineCommandManager.engineConnection?.connect(true)
}
clearTimeout(timeoutIdIdle)
timeoutIdIdle = setTimeout(onIdle, IDLE_TIME_MS)
// Clear both timers
clearTimeout(timeoutIdIdleA)
clearTimeout(timeoutIdIdleB)
timeoutIdIdleB = setTimeout(teardown, IDLE_TIME_MS)
}
globalThis?.window?.document?.addEventListener('keydown', onAnyInput)
@ -93,7 +95,7 @@ export const Stream = () => {
globalThis?.window?.document?.addEventListener('scroll', onAnyInput)
globalThis?.window?.document?.addEventListener('touchstart', onAnyInput)
timeoutIdIdle = setTimeout(onIdle, IDLE_TIME_MS)
timeoutIdIdleB = setTimeout(teardown, IDLE_TIME_MS)
return () => {
globalThis?.window?.document?.removeEventListener('paste', handlePaste, {

View File

@ -12,14 +12,14 @@ import {
setDiagnosticsEffect,
} from '@codemirror/lint'
const updateOutsideEditorAnnotation = Annotation.define<null>()
export const updateOutsideEditorEvent = updateOutsideEditorAnnotation.of(null)
const updateOutsideEditorAnnotation = Annotation.define<boolean>()
export const updateOutsideEditorEvent = updateOutsideEditorAnnotation.of(true)
const modelingMachineAnnotation = Annotation.define<null>()
export const modelingMachineEvent = modelingMachineAnnotation.of(null)
const modelingMachineAnnotation = Annotation.define<boolean>()
export const modelingMachineEvent = modelingMachineAnnotation.of(true)
const setDiagnosticsAnnotation = Annotation.define<null>()
export const setDiagnosticsEvent = setDiagnosticsAnnotation.of(null)
const setDiagnosticsAnnotation = Annotation.define<boolean>()
export const setDiagnosticsEvent = setDiagnosticsAnnotation.of(true)
function diagnosticIsEqual(d1: Diagnostic, d2: Diagnostic): boolean {
return d1.from === d2.from && d1.to === d2.to && d1.message === d2.message
@ -123,7 +123,11 @@ export default class EditorManager {
this._editorView.dispatch({
effects: [setDiagnosticsEffect.of(diagnostics)],
annotations: [setDiagnosticsEvent, Transaction.addToHistory.of(false)],
annotations: [
setDiagnosticsEvent,
updateOutsideEditorEvent,
Transaction.addToHistory.of(false),
],
})
}

View File

@ -37,11 +37,11 @@ import { CopilotAcceptCompletionParams } from 'wasm-lib/kcl/bindings/CopilotAcce
import { CopilotRejectCompletionParams } from 'wasm-lib/kcl/bindings/CopilotRejectCompletionParams'
import { editorManager } from 'lib/singletons'
const copilotPluginAnnotation = Annotation.define<null>()
export const copilotPluginEvent = copilotPluginAnnotation.of(null)
const copilotPluginAnnotation = Annotation.define<boolean>()
export const copilotPluginEvent = copilotPluginAnnotation.of(true)
const rejectSuggestionAnnotation = Annotation.define<null>()
export const rejectSuggestionCommand = rejectSuggestionAnnotation.of(null)
const rejectSuggestionAnnotation = Annotation.define<boolean>()
export const rejectSuggestionCommand = rejectSuggestionAnnotation.of(true)
// Effects to tell StateEffect what to do with GhostText
const addSuggestion = StateEffect.define<Suggestion>()
@ -229,7 +229,7 @@ export class CompletionRequester implements PluginValue {
isRelevant = true
} else if (tr.isUserEvent('move')) {
isRelevant = true
} else if (tr.annotation(copilotPluginEvent.type) !== undefined) {
} else if (tr.annotation(copilotPluginEvent.type)) {
isRelevant = true
}
}
@ -457,6 +457,7 @@ export class CompletionRequester implements PluginValue {
effects: clearSuggestion.of(null),
annotations: [
rejectSuggestionCommand,
copilotPluginEvent,
Transaction.addToHistory.of(false),
],
})

View File

@ -0,0 +1,26 @@
import { styleTags, tags as t } from '@lezer/highlight'
export const klcHighlight = styleTags({
'fn var let const': t.definitionKeyword,
return: t.controlKeyword,
'true false': t.bool,
nil: t.null,
'AddOp MultOp ExpOp': t.arithmeticOperator,
CompOp: t.logicOperator,
'Equals Arrow': t.definitionOperator,
PipeOperator: t.controlOperator,
String: t.string,
Number: t.number,
LineComment: t.lineComment,
BlockComment: t.blockComment,
Shebang: t.meta,
PipeSubstitution: t.atom,
VariableDefinition: t.definition(t.variableName),
VariableName: t.variableName,
PropertyName: t.propertyName,
TagDeclarator: t.tagName,
'( )': t.paren,
'{ }': t.brace,
'[ ]': t.bracket,
', . : ? ..': t.punctuation,
})

View File

@ -12,6 +12,9 @@ import { UpdateUnitsParams } from 'wasm-lib/kcl/bindings/UpdateUnitsParams'
import { UpdateCanExecuteParams } from 'wasm-lib/kcl/bindings/UpdateCanExecuteParams'
import { UpdateUnitsResponse } from 'wasm-lib/kcl/bindings/UpdateUnitsResponse'
import { UpdateCanExecuteResponse } from 'wasm-lib/kcl/bindings/UpdateCanExecuteResponse'
import { codeManagerUpdateEvent } from 'lang/codeManager'
import { copilotPluginEvent } from '../copilot'
import { updateOutsideEditorEvent } from 'editor/manager'
const changesDelay = 600
@ -45,11 +48,10 @@ export class KclPlugin implements PluginValue {
editorManager.setEditorView(viewUpdate.view)
let isUserSelect = false
let isRelevant = false
let isRelevant = viewUpdate.docChanged
for (const tr of viewUpdate.transactions) {
if (tr.isUserEvent('select')) {
isUserSelect = true
break
} else if (tr.isUserEvent('input')) {
isRelevant = true
} else if (tr.isUserEvent('delete')) {
@ -63,6 +65,21 @@ export class KclPlugin implements PluginValue {
} else if (tr.annotation(lspFormatCodeEvent.type)) {
isRelevant = true
}
// Don't make this an else.
if (tr.annotation(codeManagerUpdateEvent.type)) {
// We want to ignore when we are forcing the editor to update.
isRelevant = false
break
} else if (tr.annotation(copilotPluginEvent.type)) {
// We want to ignore when copilot is doing stuff.
isRelevant = false
break
} else if (tr.annotation(updateOutsideEditorEvent.type)) {
// We want to ignore other events outside the editor.
isRelevant = false
break
}
}
// If we have a user select event, we want to update what parts are

View File

@ -0,0 +1,113 @@
@precedence {
member
call
exp @left
mult @left
add @left
comp @left
pipe @left
range
}
@top Program {
Shebang?
statement*
}
statement[@isGroup=Statement] {
FunctionDeclaration { kw<"fn"> VariableDefinition Equals ParamList Arrow Body } |
VariableDeclaration { (kw<"var"> | kw<"let"> | kw<"const">) VariableDefinition Equals expression } |
ReturnStatement { kw<"return"> expression } |
ExpressionStatement { expression }
}
ParamList { "(" commaSep<Parameter { VariableDefinition "?"? (":" type)? }> ")" }
Body { "{" statement* "}" }
expression[@isGroup=Expression] {
String |
Number |
VariableName |
TagDeclarator |
kw<"true"> | kw<"false"> | kw<"nil"> |
PipeSubstitution |
BinaryExpression {
expression !add AddOp expression |
expression !mult MultOp expression |
expression !exp ExpOp expression |
expression !comp CompOp expression
} |
UnaryExpression { AddOp expression } |
ParenthesizedExpression { "(" expression ")" } |
CallExpression { expression !call ArgumentList } |
ArrayExpression { "[" commaSep<expression | IntegerRange { expression !range ".." expression }> "]" } |
ObjectExpression { "{" commaSep<ObjectProperty> "}" } |
MemberExpression { expression !member "." PropertyName } |
SubscriptExpression { expression !member "[" expression "]" } |
PipeExpression { expression (!pipe PipeOperator expression)+ }
}
ObjectProperty { PropertyName ":" expression }
ArgumentList { "(" commaSep<expression> ")" }
type[@isGroup=Type] {
@specialize[@name=PrimitiveType]<
identifier,
"string" | "number" | "bool" | "sketch_group" | "sketch_surface" | "extrude_group"
> |
ArrayType { type !member "[" "]" } |
ObjectType { "{" commaSep<ObjectProperty { PropertyName ":" type }> "}" }
}
VariableDefinition { identifier }
VariableName { identifier }
@skip { whitespace | LineComment | BlockComment }
kw<term> { @specialize[@name={term}]<identifier, term> }
commaSep<term> { (term ("," term)*)? ","? }
@tokens {
String[isolate] { "'" ("\\" _ | !['\\])* "'" | '"' ("\\" _ | !["\\])* '"' }
Number { "." @digit+ | @digit+ ("." @digit*)? }
@precedence { Number, "." }
AddOp { "+" | "-" }
MultOp { "/" | "*" | "\\" }
ExpOp { "^" }
CompOp { $[<>] "="? | "!=" | "==" }
Equals { "=" }
Arrow { "=>" }
PipeOperator { "|>" }
PipeSubstitution { "%" }
identifier { (@asciiLetter | "_") (@asciiLetter | @digit | "_")* }
PropertyName { identifier }
TagDeclarator { "$" identifier }
whitespace { @whitespace+ }
LineComment[isolate] { "//" ![\n]* }
BlockComment[isolate] { "/*" blockCommentRest }
blockCommentRest { @eof | ![*] blockCommentRest | "*" blockCommentStar }
blockCommentStar { @eof | "/" | ![/] blockCommentRest | "*" blockCommentStar }
@precedence { LineComment, BlockComment, MultOp }
Shebang { "#!" ![\n]* }
"(" ")"
"{" "}"
"[" "]"
"," "?" ":" "." ".."
}
@external propSource klcHighlight from "./highlight"
@detectDelim

View File

@ -1,9 +1,13 @@
// Code mirror language implementation for kcl.
import {
Language,
defineLanguageFacet,
LRLanguage,
LanguageSupport,
indentNodeProp,
continuedIndent,
delimitedIndent,
foldNodeProp,
foldInside,
} from '@codemirror/language'
import {
LanguageServerClient,
@ -11,18 +15,8 @@ import {
} from '@kittycad/codemirror-lsp-client'
import { kclPlugin } from '.'
import type * as LSP from 'vscode-languageserver-protocol'
import KclParser from './parser'
const data = defineLanguageFacet({
// https://codemirror.net/docs/ref/#commands.CommentTokens
commentTokens: {
line: '//',
block: {
open: '/*',
close: '*/',
},
},
})
// @ts-ignore: No types available
import { parser } from './kcl.grammar'
export interface LanguageOptions {
workspaceFolders: LSP.WorkspaceFolder[]
@ -34,26 +28,40 @@ export interface LanguageOptions {
) => void
}
class KclLanguage extends Language {
constructor(options: LanguageOptions) {
const plugin = kclPlugin({
export const KclLanguage = LRLanguage.define({
name: 'klc',
parser: parser.configure({
props: [
indentNodeProp.add({
Body: delimitedIndent({ closing: '}' }),
BlockComment: () => null,
'Statement Property': continuedIndent({ except: /^{/ }),
}),
foldNodeProp.add({
'Body ArrayExpression ObjectExpression': foldInside,
BlockComment(tree) {
return { from: tree.from + 2, to: tree.to - 2 }
},
PipeExpression(tree) {
return { from: tree.firstChild!.to, to: tree.to }
},
}),
],
}),
languageData: {
commentTokens: { line: '//', block: { open: '/*', close: '*/' } },
},
})
export function kcl(options: LanguageOptions) {
return new LanguageSupport(
KclLanguage,
kclPlugin({
documentUri: options.documentUri,
workspaceFolders: options.workspaceFolders,
allowHTMLContent: true,
client: options.client,
processLspNotification: options.processLspNotification,
})
const parser = new KclParser()
super(data, parser, [plugin], 'kcl')
}
}
export default class KclLanguageSupport extends LanguageSupport {
constructor(options: LanguageOptions) {
const lang = new KclLanguage(options)
super(lang)
}
)
}

View File

@ -1,47 +0,0 @@
// Extends the codemirror Parser for kcl.
// This is really just a no-op parser since we use semantic tokens from the LSP
// server.
import {
Parser,
Input,
TreeFragment,
PartialParse,
Tree,
NodeType,
} from '@lezer/common'
import { DocInput } from '@codemirror/language'
export default class KclParser extends Parser {
createParse(
input: Input,
fragments: readonly TreeFragment[],
ranges: readonly { from: number; to: number }[]
): PartialParse {
let parse: PartialParse = new Context(input)
return parse
}
}
class Context implements PartialParse {
private input: DocInput
stoppedAt: number = 0
constructor(input: Input) {
this.input = input as DocInput
}
get parsedPos(): number {
return 0
}
advance(): Tree | null {
this.stoppedAt = this.input.doc.length
return new Tree(NodeType.none, [], [], this.input.doc.length)
}
stopAt(pos: number) {
this.stoppedAt = pos
}
}

View File

@ -254,6 +254,10 @@ code {
color: rgb(120, 120, 120, 0.8) !important;
}
.segment-length-label-text {
transform: translate(var(--x, 0), var(--y, 0));
}
@layer components {
kbd.hotkey {
@apply font-mono text-xs inline-block px-1 py-0.5 rounded-sm;

View File

@ -11,8 +11,8 @@ import { KeyBinding } from '@codemirror/view'
const PERSIST_CODE_KEY = 'persistCode'
const codeManagerUpdateAnnotation = Annotation.define<null>()
export const codeManagerUpdateEvent = codeManagerUpdateAnnotation.of(null)
const codeManagerUpdateAnnotation = Annotation.define<boolean>()
export const codeManagerUpdateEvent = codeManagerUpdateAnnotation.of(true)
export default class CodeManager {
private _code: string = bracket

View File

@ -157,7 +157,7 @@ export function createSettings() {
),
}),
enableSSAO: new Setting<boolean>({
defaultValue: false,
defaultValue: true,
description:
'Whether or not Screen Space Ambient Occlusion (SSAO) is enabled',
validate: (v) => typeof v === 'boolean',

120
src/wasm-lib/Cargo.lock generated
View File

@ -169,18 +169,18 @@ checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.68",
"syn 2.0.70",
]
[[package]]
name = "async-trait"
version = "0.1.80"
version = "0.1.81"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca"
checksum = "6e0c28dcc82d7c8ead5cb13beb15405b57b8546e93215673ff8ca0349a028107"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.68",
"syn 2.0.70",
]
[[package]]
@ -191,7 +191,7 @@ checksum = "3c87f3f15e7794432337fc718554eaa4dc8f04c9677a950ffe366f20a162ae42"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.68",
"syn 2.0.70",
]
[[package]]
@ -400,9 +400,9 @@ dependencies = [
[[package]]
name = "clap"
version = "4.5.7"
version = "4.5.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5db83dced34638ad474f39f250d7fea9598bdd239eaced1bdf45d597da0f433f"
checksum = "64acc1846d54c1fe936a78dc189c34e28d3f5afc348403f28ecf53660b9b8462"
dependencies = [
"clap_builder",
"clap_derive",
@ -410,9 +410,9 @@ dependencies = [
[[package]]
name = "clap_builder"
version = "4.5.7"
version = "4.5.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7e204572485eb3fbf28f871612191521df159bc3e15a9f5064c66dba3a8c05f"
checksum = "6fb8393d67ba2e7bfaf28a23458e4e2b543cc73a99595511eb207fdb8aede942"
dependencies = [
"anstream",
"anstyle",
@ -424,14 +424,14 @@ dependencies = [
[[package]]
name = "clap_derive"
version = "4.5.5"
version = "4.5.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c780290ccf4fb26629baa7a1081e68ced113f1d3ec302fa5948f1c381ebf06c6"
checksum = "2bac35c6dafb060fd4d275d9a4ffae97917c13a6327903a8be2153cd964f7085"
dependencies = [
"heck 0.5.0",
"proc-macro2",
"quote",
"syn 2.0.68",
"syn 2.0.70",
]
[[package]]
@ -631,7 +631,7 @@ dependencies = [
"proc-macro2",
"quote",
"strsim 0.10.0",
"syn 2.0.68",
"syn 2.0.70",
]
[[package]]
@ -642,7 +642,7 @@ checksum = "a668eda54683121533a393014d8692171709ff57a7d61f187b6e782719f8933f"
dependencies = [
"darling_core",
"quote",
"syn 2.0.68",
"syn 2.0.70",
]
[[package]]
@ -697,7 +697,7 @@ checksum = "4078275de501a61ceb9e759d37bdd3d7210e654dbc167ac1a3678ef4435ed57b"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.68",
"syn 2.0.70",
"synstructure",
]
@ -726,7 +726,7 @@ dependencies = [
"rustfmt-wrapper",
"serde",
"serde_tokenstream",
"syn 2.0.68",
"syn 2.0.70",
]
[[package]]
@ -737,7 +737,7 @@ checksum = "67e77553c4162a157adbf834ebae5b415acbecbeafc7a74b0e886657506a7611"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.68",
"syn 2.0.70",
]
[[package]]
@ -764,7 +764,7 @@ checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.68",
"syn 2.0.70",
]
[[package]]
@ -936,7 +936,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.68",
"syn 2.0.70",
]
[[package]]
@ -1026,7 +1026,7 @@ dependencies = [
"inflections",
"proc-macro2",
"quote",
"syn 2.0.68",
"syn 2.0.70",
]
[[package]]
@ -1448,7 +1448,7 @@ dependencies = [
"pretty_assertions",
"proc-macro2",
"quote",
"syn 2.0.68",
"syn 2.0.70",
]
[[package]]
@ -1824,7 +1824,7 @@ dependencies = [
"regex",
"regex-syntax 0.8.3",
"structmeta",
"syn 2.0.68",
"syn 2.0.70",
]
[[package]]
@ -1877,7 +1877,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.68",
"syn 2.0.70",
]
[[package]]
@ -1996,9 +1996,9 @@ dependencies = [
[[package]]
name = "pyo3"
version = "0.22.0"
version = "0.22.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1962a33ed2a201c637fc14a4e0fd4e06e6edfdeee6a5fede0dab55507ad74cf7"
checksum = "4e99090d12f6182924499253aaa1e73bf15c69cea8d2774c3c781e35badc3548"
dependencies = [
"cfg-if",
"indoc",
@ -2014,9 +2014,9 @@ dependencies = [
[[package]]
name = "pyo3-build-config"
version = "0.22.0"
version = "0.22.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ab7164b2202753bd33afc7f90a10355a719aa973d1f94502c50d06f3488bc420"
checksum = "7879eb018ac754bba32cb0eec7526391c02c14a093121857ed09fbf1d1057d41"
dependencies = [
"once_cell",
"target-lexicon",
@ -2024,9 +2024,9 @@ dependencies = [
[[package]]
name = "pyo3-ffi"
version = "0.22.0"
version = "0.22.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c6424906ca49013c0829c5c1ed405e20e2da2dc78b82d198564880a704e6a7b7"
checksum = "ce2baa5559a411fc1cf519295f24c34b53d5d725818bc96b5abf94762da09041"
dependencies = [
"libc",
"pyo3-build-config",
@ -2034,27 +2034,27 @@ dependencies = [
[[package]]
name = "pyo3-macros"
version = "0.22.0"
version = "0.22.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "82b2f19e153122d64afd8ce7aaa72f06a00f52e34e1d1e74b6d71baea396460a"
checksum = "049621c20a23f2def20f4fe67978d1da8d8a883d64b9c21362f3b776e254edc7"
dependencies = [
"proc-macro2",
"pyo3-macros-backend",
"quote",
"syn 2.0.68",
"syn 2.0.70",
]
[[package]]
name = "pyo3-macros-backend"
version = "0.22.0"
version = "0.22.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd698c04cac17cf0fe63d47790ab311b8b25542f5cb976b65c374035c50f1eef"
checksum = "0e969ee2e025435f1819d31a275ba4bb9cbbdf3ac535227fdbd85b9322ffe144"
dependencies = [
"heck 0.5.0",
"proc-macro2",
"pyo3-build-config",
"quote",
"syn 2.0.68",
"syn 2.0.70",
]
[[package]]
@ -2516,7 +2516,7 @@ dependencies = [
"proc-macro2",
"quote",
"serde_derive_internals",
"syn 2.0.68",
"syn 2.0.70",
]
[[package]]
@ -2566,9 +2566,9 @@ checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca"
[[package]]
name = "serde"
version = "1.0.203"
version = "1.0.204"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094"
checksum = "bc76f558e0cbb2a839d37354c575f1dc3fdc6546b5be373ba43d95f231bf7c12"
dependencies = [
"serde_derive",
]
@ -2584,13 +2584,13 @@ dependencies = [
[[package]]
name = "serde_derive"
version = "1.0.203"
version = "1.0.204"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba"
checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.68",
"syn 2.0.70",
]
[[package]]
@ -2601,7 +2601,7 @@ checksum = "330f01ce65a3a5fe59a60c82f3c9a024b573b8a6e875bd233fe5f934e71d54e3"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.68",
"syn 2.0.70",
]
[[package]]
@ -2624,7 +2624,7 @@ checksum = "0b2e6b945e9d3df726b65d6ee24060aff8e3533d431f677a9695db04eff9dfdb"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.68",
"syn 2.0.70",
]
[[package]]
@ -2645,7 +2645,7 @@ dependencies = [
"proc-macro2",
"quote",
"serde",
"syn 2.0.68",
"syn 2.0.70",
]
[[package]]
@ -2782,7 +2782,7 @@ dependencies = [
"proc-macro2",
"quote",
"structmeta-derive",
"syn 2.0.68",
"syn 2.0.70",
]
[[package]]
@ -2793,7 +2793,7 @@ checksum = "152a0b65a590ff6c3da95cabe2353ee04e6167c896b28e3b14478c2636c922fc"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.68",
"syn 2.0.70",
]
[[package]]
@ -2837,9 +2837,9 @@ dependencies = [
[[package]]
name = "syn"
version = "2.0.68"
version = "2.0.70"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "901fa70d88b9d6c98022e23b4136f9f3e54e4662c3bc1bd1d84a42a9a0f0c1e9"
checksum = "2f0209b68b3613b093e0ec905354eccaedcfe83b8cb37cbdeae64026c3064c16"
dependencies = [
"proc-macro2",
"quote",
@ -2860,7 +2860,7 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.68",
"syn 2.0.70",
]
[[package]]
@ -2943,7 +2943,7 @@ checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.68",
"syn 2.0.70",
]
[[package]]
@ -3039,7 +3039,7 @@ checksum = "5f5ae998a069d4b5aba8ee9dad856af7d520c3699e6159b185c2acd48155d39a"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.68",
"syn 2.0.70",
]
[[package]]
@ -3192,7 +3192,7 @@ checksum = "84fd902d4e0b9a4b27f2f440108dc034e1758628a9b702f8ec61ad66355422fa"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.68",
"syn 2.0.70",
]
[[package]]
@ -3220,7 +3220,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.68",
"syn 2.0.70",
]
[[package]]
@ -3297,7 +3297,7 @@ checksum = "c88cc88fd23b5a04528f3a8436024f20010a16ec18eb23c164b1242f65860130"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.68",
"syn 2.0.70",
"termcolor",
]
@ -3419,9 +3419,9 @@ checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
[[package]]
name = "uuid"
version = "1.9.1"
version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5de17fd2f7da591098415cff336e12965a28061ddace43b59cb3c430179c9439"
checksum = "81dfa00651efa65069b0b6b651f4aaa31ba9e3c3ce0137aaad053604ee7e0314"
dependencies = [
"getrandom",
"serde",
@ -3455,7 +3455,7 @@ dependencies = [
"proc-macro-error",
"proc-macro2",
"quote",
"syn 2.0.68",
"syn 2.0.70",
]
[[package]]
@ -3516,7 +3516,7 @@ dependencies = [
"once_cell",
"proc-macro2",
"quote",
"syn 2.0.68",
"syn 2.0.70",
"wasm-bindgen-shared",
]
@ -3551,7 +3551,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.68",
"syn 2.0.70",
"wasm-bindgen-backend",
"wasm-bindgen-shared",
]
@ -3876,7 +3876,7 @@ checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.68",
"syn 2.0.70",
]
[[package]]

View File

@ -11,14 +11,14 @@ crate-type = ["cdylib"]
[dependencies]
bson = { version = "2.11.0", features = ["uuid-1", "chrono"] }
clap = "4.5.7"
clap = "4.5.9"
gloo-utils = "0.2.0"
kcl-lib = { path = "kcl" }
kittycad.workspace = true
serde_json = "1.0.120"
tokio = { version = "1.38.0", features = ["sync"] }
toml = "0.8.14"
uuid = { version = "1.9.1", features = ["v4", "js", "serde"] }
uuid = { version = "1.10.0", features = ["v4", "js", "serde"] }
wasm-bindgen = "0.2.91"
wasm-bindgen-futures = "0.4.42"
@ -31,7 +31,7 @@ pretty_assertions = "1.4.0"
reqwest = { version = "0.11.26", default-features = false }
tokio = { version = "1.38.0", features = ["rt-multi-thread", "macros", "time"] }
twenty-twenty = "0.8"
uuid = { version = "1.9.1", features = ["v4", "js", "serde"] }
uuid = { version = "1.10.0", features = ["v4", "js", "serde"] }
[target.'cfg(target_arch = "wasm32")'.dependencies]
console_error_panic_hook = "0.1.7"

View File

@ -18,9 +18,9 @@ once_cell = "1.19.0"
proc-macro2 = "1"
quote = "1"
regex = "1.10"
serde = { version = "1.0.203", features = ["derive"] }
serde = { version = "1.0.204", features = ["derive"] }
serde_tokenstream = "0.2"
syn = { version = "2.0.68", features = ["full"] }
syn = { version = "2.0.70", features = ["full"] }
[dev-dependencies]
anyhow = "1.0.86"

View File

@ -15,7 +15,7 @@ databake = "0.1.8"
kcl-lib = { path = "../kcl" }
proc-macro2 = "1"
quote = "1"
syn = { version = "2.0.68", features = ["full"] }
syn = { version = "2.0.70", features = ["full"] }
[dev-dependencies]
pretty_assertions = "1.4.0"

View File

@ -10,6 +10,6 @@ anyhow = "1.0.86"
hyper = { version = "0.14.29", features = ["server"] }
kcl-lib = { version = "0.1.70", path = "../kcl" }
pico-args = "0.5.0"
serde = { version = "1.0.203", features = ["derive"] }
serde = { version = "1.0.204", features = ["derive"] }
serde_json = "1.0.120"
tokio = { version = "1.38.0", features = ["macros", "rt-multi-thread"] }

View File

@ -13,10 +13,10 @@ keywords = ["kcl", "KittyCAD", "CAD"]
[dependencies]
anyhow = { version = "1.0.86", features = ["backtrace"] }
async-recursion = "1.1.1"
async-trait = "0.1.80"
async-trait = "0.1.81"
base64 = "0.22.1"
chrono = "0.4.38"
clap = { version = "4.5.7", default-features = false, optional = true }
clap = { version = "4.5.9", default-features = false, optional = true }
dashmap = "6.0.1"
databake = { version = "0.1.8", features = ["derive"] }
derive-docs = { version = "0.1.20", path = "../derive-docs" }
@ -28,18 +28,18 @@ kittycad = { workspace = true, features = ["clap"] }
lazy_static = "1.5.0"
mime_guess = "2.0.5"
parse-display = "0.9.1"
pyo3 = { version = "0.22.0", optional = true }
pyo3 = { version = "0.22.1", optional = true }
reqwest = { version = "0.11.26", default-features = false, features = ["stream", "rustls-tls"] }
ropey = "1.6.1"
schemars = { version = "0.8.17", features = ["impl_json_schema", "url", "uuid1"] }
serde = { version = "1.0.203", features = ["derive"] }
serde = { version = "1.0.204", features = ["derive"] }
serde_json = "1.0.120"
sha2 = "0.10.8"
thiserror = "1.0.61"
toml = "0.8.14"
ts-rs = { version = "9.0.1", features = ["uuid-impl", "url-impl", "chrono-impl", "no-serde-warnings", "serde-json-impl"] }
url = { version = "2.5.2", features = ["serde"] }
uuid = { version = "1.9.1", features = ["v4", "js", "serde"] }
uuid = { version = "1.10.0", features = ["v4", "js", "serde"] }
validator = { version = "0.18.1", features = ["derive"] }
winnow = "0.5.40"
zip = { version = "2.0.0", default-features = false }

View File

@ -231,7 +231,6 @@ impl Backend {
|> line([0, scale], %)
|> line([scale, 0], %)
|> line([0, -scale], %)
return sg
}
const part001 = cube([0,0], 20)

View File

@ -12,7 +12,8 @@
"@types/wicg-file-system-access",
"node",
"@wdio/globals/types",
"mocha"
"mocha",
"@lezer/generator"
],
"target": "esnext",
"lib": ["dom", "dom.iterable", "esnext"],
@ -32,6 +33,6 @@
"jsx": "react-jsx"
},
"include": ["src", "e2e", "packages", "./*.ts"],
"exclude": ["node_modules"],
"exclude": ["node_modules", "./*.grammar"],
"references": [{ "path": "./tsconfig.node.json" }]
}

View File

@ -3,6 +3,8 @@ import viteTsconfigPaths from 'vite-tsconfig-paths'
import eslint from 'vite-plugin-eslint'
import { defineConfig, configDefaults } from 'vitest/config'
import version from 'vite-plugin-package-version'
// @ts-ignore: No types available
import { lezer } from '@lezer/generator/rollup'
const config = defineConfig({
server: {
@ -58,7 +60,7 @@ const config = defineConfig({
'@kittycad/codemirror-lsp-client': '/packages/codemirror-lsp-client/src',
},
},
plugins: [react(), viteTsconfigPaths(), eslint(), version()],
plugins: [react(), viteTsconfigPaths(), eslint(), version(), lezer()],
worker: {
plugins: () => [viteTsconfigPaths()],
},

View File

@ -1628,10 +1628,10 @@
resolved "https://registry.yarnpkg.com/@juggle/resize-observer/-/resize-observer-3.4.0.tgz#08d6c5e20cf7e4cc02fd181c4b0c225cd31dbb60"
integrity sha512-dfLbk+PwWvFzSxwk3n5ySL0hfBog779o8h68wK/7/APo/7cgyWp5jcXockbxdk5kFRkbeXWm4Fbi9FrdN381sA==
"@kittycad/lib@^0.0.69":
version "0.0.69"
resolved "https://registry.yarnpkg.com/@kittycad/lib/-/lib-0.0.69.tgz#755fb5bc87ea6401d013be8047955b890e88493d"
integrity sha512-D6VBx2kUd0ya2op+SYcnB+/JU0TU8/rYh4o5VGCxO7Z13wW7SiAawucHhid3KSzzXfwjLXeoEXXYBv0rRzLJ3A==
"@kittycad/lib@^0.0.70":
version "0.0.70"
resolved "https://registry.yarnpkg.com/@kittycad/lib/-/lib-0.0.70.tgz#398ec3b2385cef055bbd7c2681040f08b3751ac6"
integrity sha512-P6IyfUIiCZ5Cc7EDx/apXBsmHAUmO/yhMw5E6fviMCRt0sNJnUfed6iTmfTpq2m44k7k8Vrn0WwrkQMsReLUhA==
dependencies:
node-fetch "3.3.2"
openapi-types "^12.0.0"
@ -1643,14 +1643,22 @@
resolved "https://registry.yarnpkg.com/@lezer/common/-/common-1.2.1.tgz#198b278b7869668e1bebbe687586e12a42731049"
integrity sha512-yemX0ZD2xS/73llMZIK6KplkjIjf2EvAHcinDi/TfJ9hS25G0388+ClHt6/3but0oOxinTcQHJLDXh6w1crzFQ==
"@lezer/highlight@^1.0.0":
"@lezer/generator@^1.7.1":
version "1.7.1"
resolved "https://registry.yarnpkg.com/@lezer/generator/-/generator-1.7.1.tgz#90c1a9de2fb4d5a714216fa659058c7859accaab"
integrity sha512-MgPJN9Si+ccxzXl3OAmCeZuUKw4XiPl4y664FX/hnnyG9CTqUPq65N3/VGPA2jD23D7QgMTtNqflta+cPN+5mQ==
dependencies:
"@lezer/common" "^1.1.0"
"@lezer/lr" "^1.3.0"
"@lezer/highlight@^1.0.0", "@lezer/highlight@^1.2.0":
version "1.2.0"
resolved "https://registry.yarnpkg.com/@lezer/highlight/-/highlight-1.2.0.tgz#e5898c3644208b4b589084089dceeea2966f7780"
integrity sha512-WrS5Mw51sGrpqjlh3d4/fOwpEV2Hd3YOkp9DBt4k8XZQcoTHZFB7sx030A6OcahF4J1nDQAa3jXlTVVYH50IFA==
dependencies:
"@lezer/common" "^1.0.0"
"@lezer/lr@^1.0.0":
"@lezer/lr@^1.0.0", "@lezer/lr@^1.3.0", "@lezer/lr@^1.4.1":
version "1.4.1"
resolved "https://registry.yarnpkg.com/@lezer/lr/-/lr-1.4.1.tgz#fe25f051880a754e820b28148d90aa2a96b8bdd2"
integrity sha512-CHsKq8DMKBf9b3yXPDIU4DbH+ZJd/sJdYOW2llbW/HudP5u0VS6Bfq1hLYfgU7uAYGFIyGGQIsSOXGPEErZiJw==
@ -7535,16 +7543,7 @@ string-natural-compare@^3.0.1:
resolved "https://registry.yarnpkg.com/string-natural-compare/-/string-natural-compare-3.0.1.tgz#7a42d58474454963759e8e8b7ae63d71c1e7fdf4"
integrity sha512-n3sPwynL1nwKi3WJ6AIsClwBMa0zTi54fn2oLU6ndfTSIO05xaznjSf15PcBZU6FNWbmN5Q6cxT4V5hGvB4taw==
"string-width-cjs@npm:string-width@^4.2.0":
version "4.2.3"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
dependencies:
emoji-regex "^8.0.0"
is-fullwidth-code-point "^3.0.0"
strip-ansi "^6.0.1"
string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
version "4.2.3"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
@ -7622,14 +7621,7 @@ string_decoder@~1.1.1:
dependencies:
safe-buffer "~5.1.0"
"strip-ansi-cjs@npm:strip-ansi@^6.0.1":
version "6.0.1"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
dependencies:
ansi-regex "^5.0.1"
strip-ansi@^6.0.0, strip-ansi@^6.0.1:
"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1:
version "6.0.1"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
@ -8497,7 +8489,7 @@ workerpool@6.2.1:
resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.1.tgz#46fc150c17d826b86a008e5a4508656777e9c343"
integrity sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==
"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0":
"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
@ -8515,15 +8507,6 @@ wrap-ansi@^6.2.0:
string-width "^4.1.0"
strip-ansi "^6.0.0"
wrap-ansi@^7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
dependencies:
ansi-styles "^4.0.0"
string-width "^4.1.0"
strip-ansi "^6.0.0"
wrap-ansi@^8.1.0:
version "8.1.0"
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214"