feat(自学): C 教程里没写 main 的片段也能运行——上下套一层灰色的 main,灰的几行改不了;其余没 main 的片段不再给一按就报错的「运行」按钮
Deploy / deploy (push) Canceled after 0s
Deploy / deploy (push) Canceled after 0s
教程正文里写 ```c main 的片段才套。套的行就在编辑器里,报错行号和看到的一致,复制出去是完整程序。 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
dae10d0813
commit
27210eac1b
4 files changed
+92
-17
No files matched your search
@@ -9,6 +9,7 @@ import { explainPythonCompileError } from "oj/problem/utils/pythonError"
|
||||
import { explainRuntimeError } from "oj/problem/utils/runtimeError"
|
||||
import { useAuthModalStore } from "shared/store/authModal"
|
||||
import { useUserStore } from "shared/store/user"
|
||||
import { mainWrapExtensions, wrapMain } from "../wrapMain"
|
||||
|
||||
const CodeEditor = defineAsyncComponent(() => import("shared/components/CodeEditor.vue"))
|
||||
|
||||
@@ -18,11 +19,14 @@ const CodeEditor = defineAsyncComponent(() => import("shared/components/CodeEdit
|
||||
* 运行走题目页同一台判题机(POST /trial-runs,带 tutorialId),不算提交。
|
||||
* 报错用题目页那套中文解释(pythonError / cError / runtimeError),原文收在下面。
|
||||
* 代码里读输入(input() / scanf)才出输入框。
|
||||
* C 的片段(原文没有 main,只是讲一两行写法)跑不起来,不给「运行」按钮;
|
||||
* 教程里标了 ```c main 的片段套上灰色的 main 再给(见 wrapMain.ts)。
|
||||
*/
|
||||
const props = defineProps<{
|
||||
code: string
|
||||
lang: "python" | "c"
|
||||
tutorialId: number
|
||||
wrapMain?: boolean
|
||||
}>()
|
||||
|
||||
const userStore = useUserStore()
|
||||
@@ -30,7 +34,9 @@ const authModal = useAuthModalStore()
|
||||
const message = useMessage()
|
||||
const { copy } = useClipboard({ legacy: true })
|
||||
|
||||
const value = ref(props.code)
|
||||
const original = computed(() => (props.wrapMain ? wrapMain(props.code) : props.code))
|
||||
const extensions = computed(() => (props.wrapMain ? mainWrapExtensions : []))
|
||||
const value = ref(original.value)
|
||||
const input = ref("")
|
||||
const running = ref(false)
|
||||
|
||||
@@ -41,16 +47,15 @@ type Outcome =
|
||||
const outcome = ref<Outcome | null>(null)
|
||||
|
||||
// 换课时组件实例可能被复用(v-for 的 key 是段落序号),跟着原文重置
|
||||
watch(
|
||||
() => props.code,
|
||||
(code) => {
|
||||
value.value = code
|
||||
input.value = ""
|
||||
outcome.value = null
|
||||
},
|
||||
)
|
||||
watch(original, (code) => {
|
||||
value.value = code
|
||||
input.value = ""
|
||||
outcome.value = null
|
||||
})
|
||||
|
||||
const edited = computed(() => value.value !== props.code)
|
||||
const edited = computed(() => value.value !== original.value)
|
||||
// 看原文不看改过的:学生把 main 删了,按钮还在,点了才知道错在哪
|
||||
const runnable = computed(() => props.lang === "python" || /\bmain\s*\(/.test(original.value))
|
||||
const needsInput = computed(() =>
|
||||
props.lang === "python"
|
||||
? /\binput\s*\(/.test(value.value)
|
||||
@@ -173,7 +178,7 @@ async function run() {
|
||||
}
|
||||
|
||||
function restore() {
|
||||
value.value = props.code
|
||||
value.value = original.value
|
||||
outcome.value = null
|
||||
}
|
||||
|
||||
@@ -194,7 +199,14 @@ async function copyCode() {
|
||||
<Icon icon="ph:arrow-counter-clockwise" :width="14" />还原
|
||||
</button>
|
||||
</template>
|
||||
<button type="button" class="run" :class="{ busy: running }" :disabled="running" @click="run">
|
||||
<button
|
||||
v-if="runnable"
|
||||
type="button"
|
||||
class="run"
|
||||
:class="{ busy: running }"
|
||||
:disabled="running"
|
||||
@click="run"
|
||||
>
|
||||
<template v-if="running">运行中…</template>
|
||||
<template v-else><Icon icon="ph:play-fill" :width="12" />运行</template>
|
||||
</button>
|
||||
@@ -203,10 +215,16 @@ async function copyCode() {
|
||||
</button>
|
||||
</div>
|
||||
<div class="editor" :style="{ minHeight: `${lineCount * 22 + 16}px` }">
|
||||
<CodeEditor v-model:value="value" :language="language" :font-size="14" height="auto" />
|
||||
<CodeEditor
|
||||
v-model:value="value"
|
||||
:language="language"
|
||||
:font-size="14"
|
||||
height="auto"
|
||||
:extra-extensions="extensions"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
v-if="needsInput"
|
||||
v-if="runnable && needsInput"
|
||||
class="pane input"
|
||||
:class="{ ask: outcome?.kind === 'error' && outcome.needInput }"
|
||||
>
|
||||
@@ -315,6 +333,9 @@ async function copyCode() {
|
||||
background: transparent;
|
||||
border-right: 0;
|
||||
}
|
||||
.editor :deep(.cm-main-wrap) {
|
||||
opacity: 0.4;
|
||||
}
|
||||
.editor :deep(.cm-scroller) {
|
||||
font-family: var(--learn-code-font);
|
||||
line-height: 22px;
|
||||
|
||||
Reference in new issue
Block a user