/
CodeMirror.vue
66 lines (56 loc) · 1.43 KB
/
CodeMirror.vue
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
<script setup lang="ts">
import type CodeMirror from 'codemirror'
const { mode, readOnly } = defineProps<{
mode?: string
readOnly?: boolean
}>()
const emit = defineEmits<{
(event: 'save', content: string): void
}>()
const modelValue = defineModel<string>()
const attrs = useAttrs()
const modeMap: Record<string, any> = {
// html: 'htmlmixed',
// vue: 'htmlmixed',
// svelte: 'htmlmixed',
js: 'javascript',
mjs: 'javascript',
cjs: 'javascript',
ts: { name: 'javascript', typescript: true },
mts: { name: 'javascript', typescript: true },
cts: { name: 'javascript', typescript: true },
jsx: { name: 'javascript', jsx: true },
tsx: { name: 'javascript', typescript: true, jsx: true },
}
const el = ref<HTMLTextAreaElement>()
const cm = shallowRef<CodeMirror.EditorFromTextArea>()
defineExpose({ cm })
onMounted(async () => {
cm.value = useCodeMirror(el, modelValue as unknown as Ref<string>, {
...attrs,
mode: modeMap[mode || ''] || mode,
readOnly: readOnly ? true : undefined,
extraKeys: {
'Cmd-S': function (cm) {
emit('save', cm.getValue())
},
'Ctrl-S': function (cm) {
emit('save', cm.getValue())
},
},
})
cm.value.setSize('100%', '100%')
cm.value.clearHistory()
setTimeout(() => cm.value!.refresh(), 100)
})
</script>
<template>
<div
relative
font-mono
text-sm
class="codemirror-scrolls"
>
<textarea ref="el" />
</div>
</template>