|
3 | 3 | </template> |
4 | 4 |
|
5 | 5 | <script setup lang="ts"> |
6 | | -import { ref, onMounted, onUnmounted, defineProps, watch, computed } from 'vue' |
| 6 | +import { ref, onUnmounted, defineProps, watch, computed } from 'vue' |
7 | 7 | import { ignorableWatch } from '@vueuse/core' |
8 | 8 | import { decode } from 'js-base64' |
| 9 | +import type * as monaco from 'monaco-editor' |
9 | 10 | import { formatCode } from '../setup/prettier' |
10 | | -import { monaco } from '../setup/monaco' |
| 11 | +import setupMonaco from '../setup/monaco' |
11 | 12 | import { isDark, useNavigateControls } from '../logic' |
12 | 13 |
|
13 | 14 | const props = defineProps({ |
@@ -60,70 +61,71 @@ const ext = computed(() => { |
60 | 61 | } |
61 | 62 | }) |
62 | 63 |
|
63 | | -onMounted(() => { |
64 | | - const model = monaco.editor.createModel( |
65 | | - code.value, |
66 | | - lang.value, |
67 | | - monaco.Uri.parse(`file:///root/${Date.now()}.${ext.value}`), |
68 | | - ) |
69 | | -
|
70 | | - editor = monaco.editor.create(el.value!, { |
71 | | - model, |
72 | | - tabSize: 2, |
73 | | - insertSpaces: true, |
74 | | - detectIndentation: false, |
75 | | - folding: false, |
76 | | - fontSize: 12, |
77 | | - fontFamily: '\'Fira Code\', monospace', |
78 | | - lineDecorationsWidth: 0, |
79 | | - lineNumbersMinChars: 0, |
80 | | - scrollBeyondLastLine: false, |
81 | | - scrollBeyondLastColumn: 0, |
82 | | - automaticLayout: true, |
83 | | - readOnly: props.readonly, |
84 | | - theme: isDark.value ? 'vitesse-dark' : 'vitesse-light', |
85 | | - lineNumbers: props.lineNumbers as any, |
86 | | - glyphMargin: false, |
87 | | - scrollbar: { |
88 | | - useShadows: false, |
89 | | - vertical: 'hidden', |
90 | | - horizontal: 'hidden', |
91 | | - }, |
92 | | - overviewRulerLanes: 0, |
93 | | - minimap: { enabled: false }, |
94 | | - }) |
95 | | - editor.onDidFocusEditorText(() => controls.paused.value = true) |
96 | | - editor.onDidBlurEditorText(() => controls.paused.value = false) |
97 | | -
|
98 | | - async function format() { |
99 | | - code.value = (await formatCode(code.value, lang.value)).trim() |
100 | | - } |
101 | | -
|
102 | | - const { ignoreUpdates } = ignorableWatch(code, (v) => { |
103 | | - const selection = editor.getSelection() |
104 | | - editor.setValue(v) |
105 | | - if (selection) |
106 | | - editor.setSelection(selection) |
107 | | - }) |
108 | | -
|
109 | | - model.onDidChangeContent(() => { |
110 | | - const v = editor.getValue().toString() |
111 | | - if (v !== code.value) |
112 | | - ignoreUpdates(() => code.value = v) |
113 | | - }) |
114 | | -
|
115 | | - // ctrl+s to format |
116 | | - editor.onKeyDown((e) => { |
117 | | - if ((e.ctrlKey || e.metaKey) && e.code === 'KeyS') { |
118 | | - e.preventDefault() |
119 | | - format() |
| 64 | +setupMonaco() |
| 65 | + .then(({ monaco }) => { |
| 66 | + const model = monaco.editor.createModel( |
| 67 | + code.value, |
| 68 | + lang.value, |
| 69 | + monaco.Uri.parse(`file:///root/${Date.now()}.${ext.value}`), |
| 70 | + ) |
| 71 | +
|
| 72 | + editor = monaco.editor.create(el.value!, { |
| 73 | + model, |
| 74 | + tabSize: 2, |
| 75 | + insertSpaces: true, |
| 76 | + detectIndentation: false, |
| 77 | + folding: false, |
| 78 | + fontSize: 12, |
| 79 | + fontFamily: '\'Fira Code\', monospace', |
| 80 | + lineDecorationsWidth: 0, |
| 81 | + lineNumbersMinChars: 0, |
| 82 | + scrollBeyondLastLine: false, |
| 83 | + scrollBeyondLastColumn: 0, |
| 84 | + automaticLayout: true, |
| 85 | + readOnly: props.readonly, |
| 86 | + theme: isDark.value ? 'vitesse-dark' : 'vitesse-light', |
| 87 | + lineNumbers: props.lineNumbers as any, |
| 88 | + glyphMargin: false, |
| 89 | + scrollbar: { |
| 90 | + useShadows: false, |
| 91 | + vertical: 'hidden', |
| 92 | + horizontal: 'hidden', |
| 93 | + }, |
| 94 | + overviewRulerLanes: 0, |
| 95 | + minimap: { enabled: false }, |
| 96 | + }) |
| 97 | + editor.onDidFocusEditorText(() => controls.paused.value = true) |
| 98 | + editor.onDidBlurEditorText(() => controls.paused.value = false) |
| 99 | +
|
| 100 | + async function format() { |
| 101 | + code.value = (await formatCode(code.value, lang.value)).trim() |
120 | 102 | } |
121 | | - }) |
122 | | -}) |
123 | 103 |
|
124 | | -watch(isDark, () => monaco.editor.setTheme(isDark.value ? 'vitesse-dark' : 'vitesse-light')) |
| 104 | + const { ignoreUpdates } = ignorableWatch(code, (v) => { |
| 105 | + const selection = editor.getSelection() |
| 106 | + editor.setValue(v) |
| 107 | + if (selection) |
| 108 | + editor.setSelection(selection) |
| 109 | + }) |
| 110 | +
|
| 111 | + model.onDidChangeContent(() => { |
| 112 | + const v = editor.getValue().toString() |
| 113 | + if (v !== code.value) |
| 114 | + ignoreUpdates(() => code.value = v) |
| 115 | + }) |
| 116 | +
|
| 117 | + // ctrl+s to format |
| 118 | + editor.onKeyDown((e) => { |
| 119 | + if ((e.ctrlKey || e.metaKey) && e.code === 'KeyS') { |
| 120 | + e.preventDefault() |
| 121 | + format() |
| 122 | + } |
| 123 | + }) |
| 124 | +
|
| 125 | + watch(isDark, () => monaco.editor.setTheme(isDark.value ? 'vitesse-dark' : 'vitesse-light')) |
| 126 | + }) |
125 | 127 |
|
126 | | -onUnmounted(() => editor.dispose()) |
| 128 | +onUnmounted(() => editor?.dispose()) |
127 | 129 | </script> |
128 | 130 | <style lang="postcss"> |
129 | 131 | .vue-monaco { |
|
0 commit comments