Add project-aware playground completion

This commit is contained in:
2026-08-13 18:07:24 +09:00
parent 610358110f
commit e862e53f3e
9 changed files with 416 additions and 12 deletions
+28 -2
View File
@@ -2,10 +2,11 @@ import initRuntime, { evaluateProject } from 'decodal-wasm';
import runtimeWasmUrl from 'decodal-wasm/decodal_wasm_bg.wasm?url';
import { EditorView, basicSetup } from 'codemirror';
import { keymap } from '@codemirror/view';
import { decodal } from 'decodal-codemirror';
import { decodal, decodalLanguage } from 'decodal-codemirror';
import { formatDecodal, initDecodalFormatter } from 'decodal-codemirror/format';
import toolsWasmUrl from 'decodal-codemirror/wasm/decodal_language_tools_bg.wasm?url';
import { playgroundExamples } from './playground-examples.js';
import { createProjectCompletionSource } from './playground-completion.js';
const STORAGE_KEY = 'decodal-playground-project-v2';
const starterProject = playgroundExamples[0];
@@ -56,14 +57,39 @@ const editorTheme = EditorView.theme({
'&.cm-focused .cm-selectionBackground, .cm-selectionBackground, ::selection': {
backgroundColor: 'rgb(59 130 246 / 0.35)',
},
'.cm-tooltip-autocomplete': {
backgroundColor: '#111827',
border: '1px solid #334155',
borderRadius: '8px',
color: '#e5e7eb',
overflow: 'hidden',
},
'.cm-tooltip-autocomplete > ul > li': {
padding: '3px 8px',
},
'.cm-tooltip-autocomplete > ul > li[aria-selected]': {
backgroundColor: '#1d4ed8',
color: '#fff',
},
'.cm-completionDetail': {
color: '#94a3b8',
fontStyle: 'normal',
marginLeft: '1.5em',
},
}, { dark: true });
const completionSource = createProjectCompletionSource({
getFiles: () => project.files,
getActivePath: () => project.activePath,
});
const editor = new EditorView({
doc: project.files[project.activePath] ?? '',
parent: editorHost,
extensions: [
basicSetup,
decodal(),
decodalLanguage.data.of({ autocomplete: completionSource }),
editorTheme,
keymap.of([
{
@@ -288,7 +314,7 @@ try {
await Promise.all([initRuntime(runtimeWasmUrl), initDecodalFormatter(toolsWasmUrl)]);
run.disabled = false;
formatButton.disabled = false;
status.textContent = '';
status.textContent = 'Ctrl+Space: complete';
execute();
} catch (error) {
status.textContent = `Failed to load WASM: ${error?.message ?? error}`;