Files
code/src/composables/debug.ts
yuetsh aa928dd3f5
Some checks failed
Deploy / build-and-deploy (push) Has been cancelled
feat: 调试面板支持移动端,变量按作用域分组
- 调试逻辑下沉到 composables/debug.ts,桌面和移动端共用;模态框抽成
  DebugModal.vue(桌面 80vw / 移动 96vw),用 update:show 收口,
  关闭按钮、Esc、遮罩三条路径都会清理状态
- 移动端在"操作"菜单里补上调试入口(仅 Python)
- 变量面板改为分组展示:栈顶帧的局部变量在前、全局变量在后,
  顺序用 pg_encoder 的 ordered_globals / ordered_varnames,
  __return__ 显示成"返回值"。原来两者是 merge 成一份的,
  在函数里分不清哪个是局部、哪个是外面的全局
- 面板关闭时还原全局 output / status,否则主页输出区会停在某一调试步
- 输入切分不再过滤空行,只丢掉末尾换行产生的空串:程序可能正需要读一个
  空行,过滤掉会让输入提前耗尽、误报"需要更多输入"
- 后端超时/超限的 detail 透传到提示里,调试按钮加 loading 态
- 清掉 computed 和高亮更新里遗留的 console.log(自动播放时 500ms 刷一次)

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019QGZaLUWzGPEMTk6A5RShC
2026-09-07 04:46:01 -06:00

75 lines
2.0 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { ref } from "vue"
import { debug as fetchDebugTrace } from "../api"
import { code, input } from "./code"
export const showDebugModal = ref(false)
export const debugData = ref<any>(null)
export const debugLoading = ref(false)
/**
* 把输入框内容切成 stdin 行。
* 只丢掉末尾换行产生的那个空串,中间的空行必须保留 ——
* 程序可能正需要读一个空行input() 返回 ""),过滤掉会导致输入提前耗尽。
*/
function splitInputLines(text: string): string[] {
if (!text) return []
const lines = text.split("\n")
if (lines[lines.length - 1] === "") lines.pop()
return lines
}
/**
* trace 末尾停在 raw_input 即说明输入不足
* pg_logger 在缺输入时会立刻 done=Truetrace 中至多只有 1 个 raw_input 事件,
* 所以不能用计数对比,只能看末尾)
*/
function endsAtRawInput(data: any): boolean {
const trace = data?.trace
if (!trace?.length) return false
return trace[trace.length - 1].event === "raw_input"
}
export type DebugResult =
| { ok: true }
| { ok: false; level: "error" | "warning"; message: string }
/**
* 请求调试数据并打开面板。
* 提示文案交给调用方展示useMessage() 只能在组件的 setup 里取。
*/
export async function startDebug(): Promise<DebugResult> {
if (debugLoading.value) return { ok: true }
debugLoading.value = true
let res
try {
res = await fetchDebugTrace(code.value, splitInputLines(input.value))
} catch (err: any) {
return {
ok: false,
level: "error",
message: `调试失败: ${err?.response?.data?.detail ?? err?.message ?? "未知错误"}`,
}
} finally {
debugLoading.value = false
}
debugData.value = res.data
if (endsAtRawInput(res.data)) {
return {
ok: false,
level: "warning",
message: "程序需要更多输入,请在输入框补全后重新点击调试",
}
}
showDebugModal.value = true
return { ok: true }
}
export function closeDebug() {
showDebugModal.value = false
debugData.value = null
}