refactor(编辑器): 去掉 vue-codemirror,代码编辑器、协作编辑器、教程编辑器改用自己的薄外壳

三个编辑器只用到它的 v-model、extensions、只读、缩进、占位文字、尺寸和 ready,
shared/components/CodeMirror.vue 照它的做法写了这几样,功能和手感不变:
- 它默认带的 basicSetup(行号、撤销、折叠、搜索、括号……)照样带上
- 各项配置的先后顺序和它一致;外部改代码仍是一次不带 userEvent 的 changes,
  提交时的编辑过程统计不受影响
- @codemirror/commands 现在直接 import,显式声明进依赖

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
xuyueandClaude Opus 5.5 committed 2026-10-12 20:22:39 +08:00
1 parent 6216e1cf22
commit d2b8a1ce4a
7 files changed
+133 -24

No files matched your search

@@ -1,6 +1,6 @@
<script lang="ts" setup>
import { bracketMatching } from "@codemirror/language"
import { Codemirror } from "vue-codemirror"
import CodeMirror from "./CodeMirror.vue"
import { autocompletion, closeBrackets, completeAnyWord } from "@codemirror/autocomplete"
import type { EditorView } from "@codemirror/view"
import type { Extension } from "@codemirror/state"
@@ -68,10 +68,6 @@ const extensions = computed(() => [
...extraExtensions,
])
interface EditorReadyPayload {
view: EditorView
}
// shallowRef,不是 ref:CodeMirror 的 EditorView 是带 getter 的类实例,
// Vue 的 UnwrapRef 深度展开会把它结构化成一个丢了原型方法的假类型,
// vue-tsc 会报 "missing dispatchTransactions/_root/..." 这类莫名其妙的错。
@@ -123,11 +119,11 @@ const detach = () => {
if (wasBound && collabStore.room) collabStore.leave("left")
}
const handleEditorReady = (payload: EditorReadyPayload) => {
editorView.value = payload.view
const handleEditorReady = (view: EditorView) => {
editorView.value = view
// 也从这里起:学生排队时切去看提交记录、老师在这期间接了单,
// 等他切回来时 room 早就非空了,只靠下面的 watch 是等不到的
bind(payload.view)
bind(view)
}
/**
@@ -206,14 +202,14 @@ onUnmounted(() => {
</script>
<template>
<Codemirror
<CodeMirror
v-model="code"
indentWithTab
:extensions="extensions"
:disabled="readonly"
:tab-size="4"
:placeholder="placeholder"
:style="{ height, fontSize: `${fontSize}px` }"
:height="height"
:font-size="`${fontSize}px`"
@ready="handleEditorReady"
/>
</template>