This commit is contained in:
103
src/components/DebugEditor.vue
Normal file
103
src/components/DebugEditor.vue
Normal file
@@ -0,0 +1,103 @@
|
||||
<script lang="ts" setup>
|
||||
import { cpp } from "@codemirror/lang-cpp"
|
||||
import { python } from "@codemirror/lang-python"
|
||||
import { EditorState } from "@codemirror/state"
|
||||
import { EditorView } from "@codemirror/view"
|
||||
import { Icon } from "@iconify/vue"
|
||||
import { useDark } from "@vueuse/core"
|
||||
import { computed, ref, watch } from "vue"
|
||||
import { Codemirror } from "vue-codemirror"
|
||||
import { oneDark } from "../themes/oneDark"
|
||||
import { smoothy } from "../themes/smoothy"
|
||||
import { LANGUAGE } from "../types"
|
||||
|
||||
interface Props {
|
||||
modelValue: string
|
||||
label?: string
|
||||
icon?: string
|
||||
language?: LANGUAGE
|
||||
fontSize?: number
|
||||
readonly?: boolean
|
||||
placeholder?: string
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
label: "",
|
||||
language: "python",
|
||||
fontSize: 24,
|
||||
readonly: false,
|
||||
placeholder: "",
|
||||
})
|
||||
|
||||
const code = ref(props.modelValue)
|
||||
const isDark = useDark()
|
||||
const styleTheme = EditorView.baseTheme({
|
||||
"& .cm-scroller": {
|
||||
"font-family": "Monaco",
|
||||
},
|
||||
"&.cm-editor.cm-focused": {
|
||||
outline: "none",
|
||||
},
|
||||
"&.cm-editor .cm-tooltip.cm-tooltip-autocomplete ul": {
|
||||
"font-family": "Monaco",
|
||||
},
|
||||
})
|
||||
const emit = defineEmits(["update:modelValue", "ready"])
|
||||
|
||||
watch(
|
||||
() => props.modelValue,
|
||||
(v) => {
|
||||
code.value = v
|
||||
},
|
||||
)
|
||||
|
||||
const lang = computed(() => {
|
||||
if (props.language === "python" || props.language === "turtle") {
|
||||
return python()
|
||||
}
|
||||
return cpp()
|
||||
})
|
||||
|
||||
function onChange(v: string) {
|
||||
emit("update:modelValue", v)
|
||||
}
|
||||
|
||||
function onReady(payload: {
|
||||
view: EditorView
|
||||
state: EditorState
|
||||
container: HTMLDivElement
|
||||
}) {
|
||||
emit("ready", payload.view)
|
||||
}
|
||||
</script>
|
||||
<template>
|
||||
<n-flex align="center" class="header" v-if="props.label">
|
||||
<Icon v-if="icon" :icon="icon" :width="24" :height="24"></Icon>
|
||||
<span class="title">{{ label }}</span>
|
||||
<slot name="actions"></slot>
|
||||
</n-flex>
|
||||
<Codemirror
|
||||
v-model="code"
|
||||
indentWithTab
|
||||
:extensions="[styleTheme, lang, isDark ? oneDark : smoothy]"
|
||||
:disabled="props.readonly"
|
||||
:tabSize="4"
|
||||
:placeholder="props.placeholder"
|
||||
:style="{
|
||||
height: !!props.label ? 'calc(100% - 60px)' : '100%',
|
||||
fontSize: props.fontSize + 'px',
|
||||
}"
|
||||
@change="onChange"
|
||||
@ready="onReady"
|
||||
/>
|
||||
</template>
|
||||
<style scoped>
|
||||
.header {
|
||||
padding: 12px 20px;
|
||||
height: 60px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.title {
|
||||
font-size: 16px;
|
||||
}
|
||||
</style>
|
||||
@@ -28,15 +28,6 @@ async function handleDebug() {
|
||||
:language="code.language"
|
||||
>
|
||||
<template #actions>
|
||||
<n-button
|
||||
quaternary
|
||||
type="error"
|
||||
:disabled="!code.value"
|
||||
v-if="code.language === 'python'"
|
||||
@click="handleDebug"
|
||||
>
|
||||
调试
|
||||
</n-button>
|
||||
<n-button quaternary type="primary" @click="copy">复制</n-button>
|
||||
<n-button quaternary @click="reset">清空</n-button>
|
||||
</template>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<script lang="ts" setup>
|
||||
import { code } from "../composables/code"
|
||||
import CodeSection from "./CodeSection.vue"
|
||||
import DebugSection from "./DebugSection.vue"
|
||||
import InputSection from "./InputSection.vue"
|
||||
import OutputSection from "./OutputSection.vue"
|
||||
import TurtleSection from "./TurtleSection.vue"
|
||||
@@ -10,7 +11,9 @@ import TurtleSection from "./TurtleSection.vue"
|
||||
<n-layout-content class="container">
|
||||
<n-split direction="horizontal" :min="1 / 3" :max="4 / 5">
|
||||
<template #1>
|
||||
<CodeSection />
|
||||
<component
|
||||
:is="code.language === 'python' ? DebugSection : CodeSection"
|
||||
/>
|
||||
</template>
|
||||
<template #2>
|
||||
<n-split
|
||||
|
||||
43
src/desktop/DebugSection.vue
Normal file
43
src/desktop/DebugSection.vue
Normal file
@@ -0,0 +1,43 @@
|
||||
<script lang="ts" setup>
|
||||
import copyTextToClipboard from "copy-text-to-clipboard"
|
||||
import { useMessage } from "naive-ui"
|
||||
import DebugEditor from "../components/DebugEditor.vue"
|
||||
import { code, input, reset, size } from "../composables/code"
|
||||
import { debug } from "../api"
|
||||
|
||||
const message = useMessage()
|
||||
|
||||
function copy() {
|
||||
copyTextToClipboard(code.value)
|
||||
message.success("已经复制好了")
|
||||
}
|
||||
|
||||
async function handleDebug() {
|
||||
const inputs = input.value ? input.value.split("\n") : []
|
||||
const res = await debug(code.value, inputs)
|
||||
console.log(res.data)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<DebugEditor
|
||||
label="代码区"
|
||||
icon="streamline-emojis:lemon"
|
||||
:font-size="size"
|
||||
v-model="code.value"
|
||||
:language="code.language"
|
||||
>
|
||||
<template #actions>
|
||||
<n-button
|
||||
quaternary
|
||||
type="error"
|
||||
:disabled="!code.value"
|
||||
@click="handleDebug"
|
||||
>
|
||||
调试
|
||||
</n-button>
|
||||
<n-button quaternary type="primary" @click="copy">复制</n-button>
|
||||
<n-button quaternary @click="reset">清空</n-button>
|
||||
</template>
|
||||
</DebugEditor>
|
||||
</template>
|
||||
Reference in New Issue
Block a user