From a20f81939d0162c0b7f3b219a34bec4f47ee37d8 Mon Sep 17 00:00:00 2001 From: Kyle Corbitt Date: Fri, 14 Jul 2023 12:33:57 -0700 Subject: [PATCH] implement format on save --- package.json | 3 +- pnpm-lock.yaml | 22 ++++++++------- src/components/OutputsTable/VariantEditor.tsx | 9 ++++-- src/state/sharedVariantEditor.slice.ts | 28 +++++++++++++++++++ 4 files changed, 49 insertions(+), 13 deletions(-) diff --git a/package.json b/package.json index 2b21546..5ffb8bb 100644 --- a/package.json +++ b/package.json @@ -48,6 +48,7 @@ "openai": "4.0.0-beta.2", "pluralize": "^8.0.0", "posthog-js": "^1.68.4", + "prettier": "^3.0.0", "react": "18.2.0", "react-dom": "18.2.0", "react-icons": "^4.10.1", @@ -77,8 +78,8 @@ "eslint": "^8.40.0", "eslint-config-next": "^13.4.2", "eslint-plugin-unused-imports": "^2.0.0", + "monaco-editor": "^0.40.0", "openapi-typescript": "^6.3.4", - "prettier": "^3.0.0", "prisma": "^4.14.0", "raw-loader": "^4.0.2", "typescript": "^5.0.4", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 69f99d2..e9fff22 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -22,7 +22,7 @@ dependencies: version: 11.11.0(@emotion/react@11.11.1)(@types/react@18.2.6)(react@18.2.0) '@monaco-editor/loader': specifier: ^1.3.3 - version: 1.3.3(monaco-editor@0.39.0) + version: 1.3.3(monaco-editor@0.40.0) '@next-auth/prisma-adapter': specifier: ^1.0.5 version: 1.0.5(@prisma/client@4.14.0)(next-auth@4.22.1) @@ -107,6 +107,9 @@ dependencies: posthog-js: specifier: ^1.68.4 version: 1.68.4 + prettier: + specifier: ^3.0.0 + version: 3.0.0 react: specifier: 18.2.0 version: 18.2.0 @@ -190,12 +193,12 @@ devDependencies: eslint-plugin-unused-imports: specifier: ^2.0.0 version: 2.0.0(@typescript-eslint/eslint-plugin@5.59.6)(eslint@8.40.0) + monaco-editor: + specifier: ^0.40.0 + version: 0.40.0 openapi-typescript: specifier: ^6.3.4 version: 6.3.4 - prettier: - specifier: ^3.0.0 - version: 3.0.0 prisma: specifier: ^4.14.0 version: 4.14.0 @@ -2029,12 +2032,12 @@ packages: '@jridgewell/sourcemap-codec': 1.4.14 dev: true - /@monaco-editor/loader@1.3.3(monaco-editor@0.39.0): + /@monaco-editor/loader@1.3.3(monaco-editor@0.40.0): resolution: {integrity: sha512-6KKF4CTzcJiS8BJwtxtfyYt9shBiEv32ateQ9T4UVogwn4HM/uPo9iJd2Dmbkpz8CM6Y0PDUpjnZzCwC+eYo2Q==} peerDependencies: monaco-editor: '>= 0.21.0 < 1' dependencies: - monaco-editor: 0.39.0 + monaco-editor: 0.40.0 state-local: 1.0.7 dev: false @@ -5135,9 +5138,8 @@ packages: ufo: 1.1.2 dev: true - /monaco-editor@0.39.0: - resolution: {integrity: sha512-zhbZ2Nx93tLR8aJmL2zI1mhJpsl87HMebNBM6R8z4pLfs8pj604pIVIVwyF1TivcfNtIPpMXL+nb3DsBmE/x6Q==} - dev: false + /monaco-editor@0.40.0: + resolution: {integrity: sha512-1wymccLEuFSMBvCk/jT1YDW/GuxMLYwnFwF9CDyYCxoTw2Pt379J3FUhwy9c43j51JdcxVPjwk0jm0EVDsBS2g==} /ms@2.0.0: resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} @@ -5637,7 +5639,7 @@ packages: resolution: {integrity: sha512-zBf5eHpwHOGPC47h0zrPyNn+eAEIdEzfywMoYn2XPi0P44Zp0tSq64rq0xAREh4auw2cJZHo9QUob+NqCQky4g==} engines: {node: '>=14'} hasBin: true - dev: true + dev: false /pretty-format@29.6.1: resolution: {integrity: sha512-7jRj+yXO0W7e4/tSJKoR7HRIHLPPjtNaUGG2xxKQnGvPNRkgWcQ0AZX6P4KBRJN4FcTBWb3sa7DVUJmocYuoog==} diff --git a/src/components/OutputsTable/VariantEditor.tsx b/src/components/OutputsTable/VariantEditor.tsx index d1eb1ce..156cc57 100644 --- a/src/components/OutputsTable/VariantEditor.tsx +++ b/src/components/OutputsTable/VariantEditor.tsx @@ -27,11 +27,16 @@ export default function VariantConfigEditor(props: { variant: PromptVariant }) { const toast = useToast(); const [onSave] = useHandledAsyncCallback(async () => { - const currentFn = editorRef.current?.getValue(); + if (!editorRef.current) return; + + await editorRef.current.getAction("editor.action.formatDocument")?.run(); + + const currentFn = editorRef.current.getValue(); + if (!currentFn) return; // Check if the editor has any typescript errors - const model = editorRef.current?.getModel(); + const model = editorRef.current.getModel(); if (!model) return; const markers = monaco?.editor.getModelMarkers({ resource: model.uri }); diff --git a/src/state/sharedVariantEditor.slice.ts b/src/state/sharedVariantEditor.slice.ts index ce455db..9465178 100644 --- a/src/state/sharedVariantEditor.slice.ts +++ b/src/state/sharedVariantEditor.slice.ts @@ -2,6 +2,12 @@ import { type RouterOutputs } from "~/utils/api"; import { type SliceCreator } from "./store"; import loader from "@monaco-editor/loader"; import openAITypes from "~/codegen/openai.types.ts.txt"; +import prettier from "prettier/standalone"; +import parserTypescript from "prettier/plugins/typescript"; + +// @ts-expect-error for some reason missing from types +import parserEstree from "prettier/plugins/estree"; +import { type languages } from "monaco-editor/esm/vs/editor/editor.api"; export type SharedVariantEditorSlice = { monaco: null | ReturnType; @@ -11,6 +17,26 @@ export type SharedVariantEditorSlice = { setScenarios: (scenarios: RouterOutputs["scenarios"]["list"]) => void; }; +const customFormatter: languages.DocumentFormattingEditProvider = { + provideDocumentFormattingEdits: async (model) => { + const val = model.getValue(); + console.log("going to format!", val); + const text = await prettier.format(val, { + parser: "typescript", + plugins: [parserTypescript, parserEstree], + // We're showing these in pretty narrow panes so let's keep the print width low + printWidth: 60, + }); + + return [ + { + range: model.getFullModelRange(), + text, + }, + ]; + }, +}; + export const createVariantEditorSlice: SliceCreator = (set, get) => ({ monaco: loader.__getMonacoInstance(), loadMonaco: async () => { @@ -40,6 +66,8 @@ export const createVariantEditorSlice: SliceCreator = monaco.Uri.parse("file:///openai.types.ts"), ); + monaco.languages.registerDocumentFormattingEditProvider("typescript", customFormatter); + set((state) => { state.sharedVariantEditor.monaco = monaco; });