Files
OJ2/apps/web/src/shared/components/CodeEditor.vue
T
xuyue d25b5dbe6d
Deploy / deploy (push) Canceled after 0s
update
2026-09-27 19:36:28 +08:00

66 lines
1.8 KiB
Vue

<script lang="ts" setup>
import { cpp } from "@codemirror/lang-cpp"
import { python } from "@codemirror/lang-python"
import { sql, SQLite } from "@codemirror/lang-sql"
import { bracketMatching } from "@codemirror/language"
import { Codemirror } from "vue-codemirror"
import type { Extension } from "@codemirror/state"
import { autocompletion, closeBrackets, completeAnyWord } from "@codemirror/autocomplete"
import type { LANGUAGE } from "utils/types"
import { oneDark } from "../themes/oneDark"
import { smoothy } from "../themes/smoothy"
import { styleTheme } from "shared/extensions/baseTheme"
import { enhanceCompletion } from "shared/extensions/autocompletion"
interface Props {
language?: LANGUAGE
fontSize?: number
height?: string
readonly?: boolean
placeholder?: string
/** 追加的 CodeMirror 扩展。传一个稳定的数组实例,每次渲染新建会让编辑器反复重配 */
extraExtensions?: Extension[]
}
const {
language = "Python",
fontSize = 20,
height = "100%",
readonly = false,
placeholder = "",
extraExtensions = [],
} = defineProps<Props>()
const code = defineModel<string>("value")
const isDark = useDark()
const langExtension = computed(() => {
if (language === "SQL") return sql({ dialect: SQLite, upperCaseKeywords: true })
return language === "Python" ? python() : cpp()
})
const extensions = computed(() => [
styleTheme,
langExtension.value,
bracketMatching(),
closeBrackets(),
autocompletion({
override: [enhanceCompletion(language), completeAnyWord],
}),
isDark.value ? oneDark : smoothy,
...extraExtensions,
])
</script>
<template>
<Codemirror
v-model="code"
indentWithTab
:extensions="extensions"
:disabled="readonly"
:tab-size="4"
:placeholder="placeholder"
:style="{ height, fontSize: `${fontSize}px` }"
/>
</template>