From 00b3ccdfcb7ca5fbfb010778d5da46741a9eb3e6 Mon Sep 17 00:00:00 2001 From: hugocasa Date: Mon, 1 Sep 2025 14:36:06 +0200 Subject: [PATCH] feat(frontend): preprocessor snippet completion in code editor (#6502) * feat(frontend): preprocessor snippet completion in code editor * fix: only for main script editor --- frontend/src/lib/components/Editor.svelte | 61 ++++++++++++++++++- .../src/lib/components/ScriptBuilder.svelte | 1 + .../src/lib/components/ScriptEditor.svelte | 5 +- 3 files changed, 65 insertions(+), 2 deletions(-) diff --git a/frontend/src/lib/components/Editor.svelte b/frontend/src/lib/components/Editor.svelte index 7ed6954710..0bc4a4d57c 100644 --- a/frontend/src/lib/components/Editor.svelte +++ b/frontend/src/lib/components/Editor.svelte @@ -155,6 +155,7 @@ import { aiChatManager } from './copilot/chat/AIChatManager.svelte' import type { Selection } from 'monaco-editor' import { getDbSchemas } from './apps/components/display/dbtable/utils' + import { PYTHON_PREPROCESSOR_MODULE_CODE, TS_PREPROCESSOR_MODULE_CODE } from '$lib/script_helpers' // import EditorTheme from './EditorTheme.svelte' let divEl: HTMLDivElement | null = $state(null) @@ -185,6 +186,7 @@ key?: string | undefined class?: string | undefined moduleId?: string + enablePreprocessorSnippet?: boolean } let { @@ -211,7 +213,8 @@ loadAsync = false, key = undefined, class: clazz = undefined, - moduleId = undefined + moduleId = undefined, + enablePreprocessorSnippet = false }: Props = $props() $effect.pre(() => { @@ -665,6 +668,55 @@ } } + let preprocessorCompletor: IDisposable | undefined = undefined + function addPreprocessorCompletions(lang: 'typescript' | 'python') { + if (preprocessorCompletor) { + preprocessorCompletor.dispose() + } + const preprocessorCode = + lang === 'typescript' ? TS_PREPROCESSOR_MODULE_CODE : PYTHON_PREPROCESSOR_MODULE_CODE + preprocessorCompletor = languages.registerCompletionItemProvider(lang, { + provideCompletionItems: function (model, position) { + const word = model.getWordUntilPosition(position) + + if (word.word.length >= 3 && 'preprocessor'.startsWith(word.word)) { + const range = { + startLineNumber: position.lineNumber, + endLineNumber: position.lineNumber, + startColumn: word.startColumn, + endColumn: word.endColumn + } + return { + suggestions: [ + { + label: 'preprocessor (windmill)', + kind: languages.CompletionItemKind.Function, + insertTextRules: languages.CompletionItemInsertTextRule.InsertAsSnippet, + insertText: preprocessorCode, + range, + additionalTextEdits: [ + { + range: { + startLineNumber: position.lineNumber, + endLineNumber: position.lineNumber, + startColumn: 0, + endColumn: word.startColumn + }, + text: '' + } + ] + } + ] + } + } + + return { + suggestions: [] + } + } + }) + } + let reviewingChanges = $state(writable(false)) let aiChatEditorHandler: AIChatEditorHandler | undefined = $state(undefined) @@ -1568,6 +1620,7 @@ sqlSchemaCompletor && sqlSchemaCompletor.dispose() autocompletor && autocompletor.dispose() sqlTypeCompletor && sqlTypeCompletor.dispose() + preprocessorCompletor && preprocessorCompletor.dispose() timeoutModel && clearTimeout(timeoutModel) loadTimeout && clearTimeout(loadTimeout) aiChatEditorHandler?.clear() @@ -1620,6 +1673,12 @@ : sqlTypeCompletor?.dispose() }) + $effect(() => { + initialized && (lang === 'typescript' || lang === 'python') && enablePreprocessorSnippet + ? untrack(() => addPreprocessorCompletions(lang as 'typescript' | 'python')) + : preprocessorCompletor?.dispose() + }) + let lastArg = undefined $effect(() => { let newArg = lang === 'graphql' ? args?.api : args?.database diff --git a/frontend/src/lib/components/ScriptBuilder.svelte b/frontend/src/lib/components/ScriptBuilder.svelte index 15f69838d6..dc5746d1e7 100644 --- a/frontend/src/lib/components/ScriptBuilder.svelte +++ b/frontend/src/lib/components/ScriptBuilder.svelte @@ -1791,6 +1791,7 @@ bind:hasPreprocessor bind:captureTable bind:assets={script.assets} + enablePreprocessorSnippet /> {:else} diff --git a/frontend/src/lib/components/ScriptEditor.svelte b/frontend/src/lib/components/ScriptEditor.svelte index e7ebe6c0d1..51389adcc4 100644 --- a/frontend/src/lib/components/ScriptEditor.svelte +++ b/frontend/src/lib/components/ScriptEditor.svelte @@ -81,6 +81,7 @@ disableAi?: boolean assets?: AssetWithAltAccessType[] editor_bar_right?: import('svelte').Snippet + enablePreprocessorSnippet?: boolean } let { @@ -111,7 +112,8 @@ lastDeployedCode = undefined, disableAi = false, assets = $bindable(), - editor_bar_right + editor_bar_right, + enablePreprocessorSnippet = false }: Props = $props() $effect.pre(() => { @@ -625,6 +627,7 @@ automaticLayout={true} {fixedOverflowWidgets} {args} + {enablePreprocessorSnippet} />