Spaces:
Build error
Build error
File size: 2,841 Bytes
87a665c | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 | <script lang="ts">
import '$lib/utils/codemirror';
import { basicSetup, EditorView } from 'codemirror';
import { keymap } from '@codemirror/view';
import { Compartment, EditorState, Prec } from '@codemirror/state';
import { indentWithTab } from '@codemirror/commands';
import { indentUnit } from '@codemirror/language';
import { languages } from '@codemirror/language-data';
import { oneDark } from '@codemirror/theme-one-dark';
import { onMount, onDestroy, createEventDispatcher } from 'svelte';
const dispatch = createEventDispatcher();
export let value = '';
export let lang = 'python';
let container: HTMLDivElement;
let editor: EditorView | null = null;
let editorTheme = new Compartment();
let editorLanguage = new Compartment();
const getLang = async () => {
const language = languages.find((l) => l.alias.includes(lang));
return await language?.load();
};
onMount(async () => {
const isDark = document.documentElement.classList.contains('dark');
const extensions = [
Prec.highest(
keymap.of([
{
key: 'Mod-Enter',
run: () => {
dispatch('run');
return true;
}
},
{
key: 'Escape',
run: () => {
dispatch('cancel');
return true;
}
}
])
),
basicSetup,
keymap.of([indentWithTab]),
indentUnit.of(' '),
EditorView.updateListener.of((e) => {
if (e.docChanged) {
value = e.state.doc.toString();
dispatch('change', value);
}
}),
editorTheme.of(isDark ? oneDark : []),
editorLanguage.of([]),
EditorView.theme({
'&': { fontSize: '0.75rem' },
'.cm-content': {
padding: '0.35rem 0',
fontFamily: 'ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace'
},
'.cm-gutters': { display: 'none' },
'.cm-focused': { outline: 'none' },
'.cm-scroller': { overflow: 'auto' }
})
];
editor = new EditorView({
state: EditorState.create({ doc: value, extensions }),
parent: container
});
const language = await getLang();
if (language && editor) {
editor.dispatch({ effects: editorLanguage.reconfigure(language) });
}
// Watch dark mode
const observer = new MutationObserver(() => {
const dark = document.documentElement.classList.contains('dark');
editor?.dispatch({ effects: editorTheme.reconfigure(dark ? oneDark : []) });
});
observer.observe(document.documentElement, { attributes: true, attributeFilter: ['class'] });
editor.focus();
return () => {
observer.disconnect();
editor?.destroy();
editor = null;
};
});
onDestroy(() => {
editor?.destroy();
editor = null;
});
</script>
<div bind:this={container} class="nb-cm-editor" />
<style>
.nb-cm-editor {
width: 100%;
background: #fffef5;
}
:global(.dark) .nb-cm-editor {
background: transparent;
}
</style>
|