From e1cf63b1eb6db08b833c8f433ac787f00a0e77dd Mon Sep 17 00:00:00 2001 From: ZOI-dayo Date: Mon, 16 Dec 2024 17:02:09 +0900 Subject: [PATCH] =?UTF-8?q?CodeBlock=E3=82=92=E5=8D=98=E4=BD=93=E3=81=A7?= =?UTF-8?q?=E4=BD=BF=E3=81=86=E5=A0=B4=E5=90=88(=E6=8F=90=E5=87=BA?= =?UTF-8?q?=E9=96=B2=E8=A6=A7=E3=81=AA=E3=81=A9)=E3=82=92=E6=83=B3?= =?UTF-8?q?=E5=AE=9A=E3=81=97=E3=80=81syntax=E9=96=A2=E9=80=A3=E3=82=92?= =?UTF-8?q?=E3=81=99=E3=81=B9=E3=81=A6CodeBlock=E5=86=85=E3=81=AB=E9=9A=A0?= =?UTF-8?q?=E8=94=BD=E3=81=97=E3=81=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/CodeBlock.vue | 78 ++++++++++++++++++++++------------- src/components/SubmitForm.vue | 51 +++++++---------------- 2 files changed, 63 insertions(+), 66 deletions(-) diff --git a/src/components/CodeBlock.vue b/src/components/CodeBlock.vue index 0702c9e..dd21e52 100644 --- a/src/components/CodeBlock.vue +++ b/src/components/CodeBlock.vue @@ -2,41 +2,57 @@ import { onMounted, onUpdated, useTemplateRef, watch } from 'vue' import * as monaco from 'monaco-editor' import { shikiToMonaco } from '@shikijs/monaco' -import { - type BundledLanguage, - type BundledTheme, - createHighlighter, - type HighlighterGeneric -} from 'shiki' +import { type BundledLanguage, createHighlighter } from 'shiki' import editorWorker from 'monaco-editor/esm/vs/editor/editor.worker?worker' import jsonWorker from 'monaco-editor/esm/vs/language/json/json.worker?worker' import cssWorker from 'monaco-editor/esm/vs/language/css/css.worker?worker' import htmlWorker from 'monaco-editor/esm/vs/language/html/html.worker?worker' import tsWorker from 'monaco-editor/esm/vs/language/typescript/ts.worker?worker' +import { type Language } from '@/api/generated' -const { lang } = defineProps<{ - lang?: BundledLanguage +const { language } = defineProps<{ + language: Language }>() -const model = defineModel() - -const codeBlock = useTemplateRef('codeBlock') +const model = defineModel({ required: true }) let editor: monaco.editor.IStandaloneCodeEditor | undefined +const element = useTemplateRef('codeBlock') + +let highlighter = await createHighlighter({ + themes: ['github-light'], + langs: [] +}) -let highlighter: HighlighterGeneric | undefined +// APIより得られる言語名と、それに対応したフォーマットの対応 +const syntaxMapping: Map = new Map( + Object.entries({ + C: 'c', + 'C++': 'cpp', + Java: 'java', + Python: 'python', + JavaScript: 'javascript', + Ruby: 'ruby', + Swift: 'swift', + Go: 'go', + Rust: 'rust', + Kotlin: 'kotlin' + }) +) -const setLanguage = async (lang: BundledLanguage) => { - if (lang != undefined && editor != undefined) { - highlighter?.loadLanguage(lang) - monaco.languages.register({ id: lang }) - monaco.editor.setModelLanguage(editor!.getModel()!, lang) +const setLanguage = async (language?: Language) => { + if (editor == undefined) return + let syntaxName: BundledLanguage | undefined + if (language != undefined && syntaxMapping.has(language.name)) { + syntaxName = syntaxMapping.get(language.name)! + await highlighter.loadLanguage(syntaxName) + monaco.languages.register({ id: syntaxName }) } + // 対応していない言語の場合、textフォーマッタを使用 + monaco.editor.setModelLanguage(editor!.getModel()!, syntaxName || 'text') } -onMounted(async () => { - if (import.meta.env.SSR) return - +const configureMonacoEditor = () => { self.MonacoEnvironment = { getWorker(_, label) { if (label === 'json') { @@ -55,28 +71,32 @@ onMounted(async () => { } } monaco.languages.typescript.typescriptDefaults.setEagerModelSync(true) +} - editor = monaco.editor.create(codeBlock.value!, { - value: model.value!, +onMounted(async () => { + if (import.meta.env.SSR) return + + configureMonacoEditor() + + editor = monaco.editor.create(element.value!, { + value: model.value, automaticLayout: true }) - highlighter = await createHighlighter({ - themes: ['github-light'], - langs: [] - }) + shikiToMonaco(highlighter, monaco) - if (lang !== undefined) await setLanguage(lang!) + await setLanguage(language) editor.getModel()?.onDidChangeContent(() => { model.value = editor!.getValue() }) }) onUpdated(async () => { - await setLanguage(lang!) + await setLanguage(language) }) + watch(model, () => { - if (model.value != editor?.getValue()) editor!.setValue(model.value!) + if (model.value != editor?.getValue()) editor?.setValue(model.value) }) diff --git a/src/components/SubmitForm.vue b/src/components/SubmitForm.vue index 628ba18..c90371e 100644 --- a/src/components/SubmitForm.vue +++ b/src/components/SubmitForm.vue @@ -2,8 +2,7 @@ import CodeBlock from '@/components/CodeBlock.vue' import PrimaryButton from '@/components/Controls/PrimaryButton.vue' import { type Language, LanguageApi, SubmissionsApi } from '@/api/generated' -import { ref } from 'vue' -import type { BundledLanguage } from 'shiki/langs' +import { onMounted, ref } from 'vue' import router from '@/router' const { problemId } = defineProps<{ @@ -12,36 +11,13 @@ const { problemId } = defineProps<{ // ジャッジで使用可能な言語一覧 const languages = ref([]) -new LanguageApi().getLanguages().then((res: Language[]) => (languages.value = res)) +// 現在選択されている言語 +const language = ref({ id: -1, name: 'none' }) -// 現在選択されている言語のid (デフォルトは1) -const languageId = ref(1) - -// シンタックスハイライトのスタイル (非対応の言語の場合undefined) -const syntax = ref(undefined) - -// APIより得られる言語名と、それに対応したフォーマットの対応 -const syntaxMapping: Map = new Map( - Object.entries({ - C: 'c', - 'C++': 'cpp', - Java: 'java', - Python: 'python', - JavaScript: 'javascript', - Ruby: 'ruby', - Swift: 'swift', - Go: 'go', - Rust: 'rust', - Kotlin: 'kotlin' - }) -) -// APIより得られるlanguage idから、それに対応したフォーマットを返す -const getSyntax = (id: number): BundledLanguage | undefined => { - const language = languages.value.find((language) => language.id === id) - if (language != undefined && syntaxMapping.has(language!.name)) - return syntaxMapping.get(language!.name) - return undefined -} +onMounted(async () => { + languages.value = await new LanguageApi().getLanguages() + language.value = languages.value[0] +}) // 入力したコード const source = ref('') @@ -51,7 +27,7 @@ const submit = async () => { const submission = await new SubmissionsApi().postSubmission({ problemId: problemId, postSubmissionRequest: { - languageId: languageId.value, + languageId: language.value.id, source: source.value } }) @@ -67,17 +43,18 @@ const submit = async () => { class="fontstyle-ui-body rounded border border-border-primary px-4 py-2 text-text-primary" @change=" (e) => { - languageId = parseInt((e.target as HTMLInputElement).value) - syntax = getSyntax(languageId) + language = languages.find( + (lang) => lang.id == parseInt((e.target as HTMLInputElement).value) + )! } " > -
ソースコード
- +