dsh-vscode-mode 0.18.0 → 0.19.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -4
- package/lib/client.debug.js +934 -0
- package/lib/client.debug.js.map +1 -0
- package/lib/client.js +990 -1705
- package/lib/client.js.map +1 -1
- package/lib/client.rules.js +793 -0
- package/lib/client.rules.js.map +1 -0
- package/lib/index.js +236 -42
- package/lib/index.js.map +1 -1
- package/package.json +1 -1
- package/src/client/externalOpen.ts +7 -1
- package/src/client/index.ts +9 -0
- package/src/client/lazyPanel.ts +68 -0
- package/src/client/monaco/loader.ts +2 -0
- package/src/client/monaco/theme.ts +11 -0
- package/src/client/openReceipt.ts +4 -1
- package/src/client/requestId.ts +20 -0
- package/src/client/sidebar/PanelBoundary.ts +57 -0
- package/src/client/sidebar/SidebarView.ts +58 -21
- package/src/client/sidebar/panels/FileExplorer.ts +80 -27
- package/src/client/sidebar/panels/SvnPanel.ts +24 -8
- package/src/client/sidebar/panels/index.ts +3 -4
- package/src/client/sidebar/panels/treeWindow.ts +106 -0
- package/src/client/sidebar/panels/useExplorerReveal.ts +5 -2
- package/src/client/sidebar/registry.ts +4 -1
- package/src/client/state/uiStatePersist.ts +84 -23
- package/src/client/styles/editor.css +8 -0
- package/src/client/textPages.ts +135 -0
- package/src/client/ui/EditorView.ts +74 -16
- package/src/client/ui/LargeTextView.ts +94 -0
- package/src/rpc.ts +29 -7
- package/src/shared/rpc.ts +3 -1
- package/src/shared/snippets.ts +1 -1
- package/src/shared/textPages.ts +28 -0
- package/src/textPages.ts +149 -0
- package/src/treeIndex.ts +62 -37
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.debug.js","names":["React","BP_WIDGET_MODES"],"sources":["../src/shared/dap.ts","../src/client/dap/breakpoints.ts","../src/client/dap/variableTree.ts","../src/client/dap/bpRowMenu.ts","../src/client/dap/modelPath.ts","../src/client/dap/panelSplit.ts","../src/client/sidebar/panels/DebugPanel.ts"],"sourcesContent":["/**\n * dsh-vscode-mode — 调试(DAP)双面契约:调试会话状态、事件投影视图、调试配置与\n * edrv.dap.* RPC 载荷。纯类型与纯函数,禁 node/react(同 shared 纯度规则)。\n * 适配器 = 用户已装扩展清单 contributes.debuggers 声明的 DAP 适配器(通用,不限定语言)。\n * 作者 ddj 2026年09月29号 / 2026年09月21号\n */\n\n/** 调试会话相位。 */\nexport type DapPhase = 'idle' | 'starting' | 'waiting' | 'running' | 'paused' | 'terminated'\n\n/** 系统进程条目(进程枚举投影视图)。 */\nexport interface DapProcessInfo {\n pid: number\n /** 窗口标题(processName 匹配目标,与 VS Code 扩展语义一致)。 */\n title: string\n /** 可执行文件完整路径。 */\n path: string\n /** 路径 basename(如 Unity.exe)。 */\n name: string\n}\n\n/** 调试配置(launch.json configuration 投影视图 + raw 原样透传)。 */\nexport interface DapDebugConfig {\n /** 配置名(工具条下拉显示)。 */\n name: string\n /** 适配器类型(= 扩展清单 contributes.debuggers.type,如 emmylua_attach / coreclr / unity)。 */\n type: string\n /** DAP request:attach | launch(缺省 launch;emmylua_attach 旧配置缺 request 时按 attach 兼容)。 */\n request?: string\n /** 进程名(标题或文件名包含匹配;attach 型按它自动选 pid)。 */\n processName?: string\n /** 直接指定 pid(>0 时跳过进程枚举)。 */\n pid?: number\n /** 附加目标 pid(coreclr/unity 等适配器的 launch.json processId 字段)。 */\n processId?: number\n /** emmylua_new 型:目标 emmy_core 监听地址。 */\n host?: string\n port?: number\n /** 源码根目录列表(chunkname → 文件映射辅助)。 */\n sourcePaths?: string[]\n /** 源码扩展名(emmylua 用;通用适配器按声明 languages 推导)。 */\n ext?: string[]\n /** 附加时捕获 Unity 日志(emmy_tool -capture-log)。 */\n captureLog?: boolean\n /** launch.json 原始配置(attach/launch 请求参数原样透传,含全部未识别字段,变量已替换)。 */\n raw?: Record<string, unknown>\n}\n\n/** launch.json「添加配置」下拉条目(扩展清单 configurationSnippets / initialConfigurations 投影)。 */\nexport interface DapConfigSnippet {\n /** 下拉显示名(%nls% 占位符已解析)。 */\n label: string\n /** 条目说明(%nls% 占位符已解析;无则空)。 */\n description?: string\n /** 适配器类型(= body.type,缺失时由清单条目补齐)。 */\n type: string\n /** 片段主体 JSON 文本(对象;%nls% 已解析,插入方按目标文件缩进重排)。 */\n bodyText: string\n /** 适配器可用性(与工具条同源 debuggerDecls 裁决;false = 下拉过滤不给插入;缺省 = 老 host 未标注,按可用处理)。 */\n available?: boolean\n /** 不可用原因(available=false 时给出,如「适配器入口不存在」)。 */\n reason?: string\n}\n\n/** 调试事件投影视图(host 缓冲、客户端 poll 拉增量)。 */\nexport interface DapEventView {\n /** 事件游标(单调递增,poll since 用)。 */\n seq: number\n kind: 'output' | 'stopped' | 'continued' | 'terminated'\n /** output 文本 / stopped 原因。 */\n text?: string\n reason?: string\n}\n\n/** 调用栈帧视图(file 已归一为工作区相对路径,空串=未能映射)。 */\nexport interface DapFrameView {\n id: number\n name: string\n file: string\n rawFile: string\n line: number\n}\n\n/** 作用域视图(Variables=局部+upvalue / ENV)。 */\nexport interface DapScopeView {\n name: string\n ref: number\n hint?: string\n}\n\n/** 变量视图(ref>0 表示可继续展开)。 */\nexport interface DapVariableView {\n name: string\n value: string\n type?: string\n ref: number\n}\n\n/** 停帧首栈视图(命中断点时驱动文件跳转与行高亮)。 */\nexport interface DapTopFrame {\n file: string\n rawFile: string\n line: number\n name: string\n}\n\n/** 调试会话状态视图(poll 返回,客户端渲染依据)。 */\nexport interface DapStateView {\n phase: DapPhase\n configName?: string\n configType?: string\n pid?: number\n error?: string\n topFrame?: DapTopFrame | null\n}\n\n/** poll 增量结果。 */\nexport interface DapPollResult {\n state: DapStateView\n events: DapEventView[]\n nextSeq: number\n}\n\n/** 断点输入(path 相对工作区根,'/' 分隔;host 负责转绝对路径给适配器)。 */\nexport interface DapBreakpointInput {\n path: string\n line: number\n condition?: string\n hitCondition?: string\n logMessage?: string\n}\n\n/** 调试控制动作(edrv.dap.command)。 */\nexport type DapAction = 'continue' | 'next' | 'stepIn' | 'stepOut' | 'pause' | 'disconnect'\n\n/** 全部合法动作(运行时校验用)。 */\nexport const DAP_ACTIONS: readonly DapAction[] = ['continue', 'next', 'stepIn', 'stepOut', 'pause', 'disconnect']\n\n/** 调试配置文件(工作区相对路径;插件专属,与 VS Code 的 .vscode/launch.json 互不干扰)。 */\nexport const DAP_LAUNCH_REL = '.dsh/launch.json'\n\n/** 旧共用配置路径(仅首读迁移源:复制到 DAP_LAUNCH_REL 后不再读取,永不回写)。 */\nexport const DAP_LEGACY_LAUNCH_REL = '.vscode/launch.json'\n\n/** 断点确认结果(适配器真实回执;适配器可能挪行或判不可验证)。 */\nexport interface DapBreakpointAck {\n line: number\n verified: boolean\n /** 适配器说明(如「该行无可执行代码」)。 */\n message?: string\n}\n\n/** 配置来源。 */\nexport type DapConfigSource = 'launchjson' | 'settings' | 'none'\n\n/** 调试适配器声明(扩展清单 contributes.debuggers 条目投影视图)。 */\nexport interface DapAdapterDecl {\n /** 调试类型(launch.json type 匹配键,= initialize.adapterID)。 */\n type: string\n /** 显示名(下拉与错误提示用)。 */\n label: string\n /** 来源扩展 id(publisher.name)。 */\n extensionId: string\n /** 来源扩展根目录(emmylua 兼容 shim 的 extensionPath 来源)。 */\n extensionPath: string\n /** 适配器入口绝对路径(已按平台解析 program/windows.program)。 */\n program: string\n /** 清单声明的启动参数(如 clrdbg 的 --interpreter=vscode)。 */\n args: string[]\n /** 运行时:'node' = 用 node 跑 js 入口;空 = 直接 spawn program。 */\n runtime?: string\n /** 声明语言(如 ['lua'] / ['csharp'])。 */\n languages: string[]\n /** 该适配器可下断点的文件扩展名(小写、带点;空 = 不限)。 */\n exts: string[]\n /** 入口是否真实存在(DotRush 等按需下载的适配器可能缺失)。 */\n available: boolean\n /** 不可用原因(available=false 时给出)。 */\n reason?: string\n}\n\n/** 下发客户端的适配器可用性视图(edrv.dap.configs.adapters 元素)。 */\nexport interface DapAdapterInfo {\n type: string\n label: string\n available: boolean\n reason?: string\n}\n\n/**\n * chunkname 与候选文件的 basename 匹配(纯函数,可单测)。\n * 适配器 findFileReq 的 file 是 Lua chunkname(可能带 @ 前缀/相对点路径/反斜杠,\n * 且常常不含 .lua 扩展名——xLua 惯例);匹配口径:剥 @、统一分隔符后,\n * 完整相对路径相等 / basename 相等 / basename 去扩展名 stem 相等(大小写不敏感)。\n * @author ddj 2026年09月29号\n * @param chunk 适配器上报的 chunkname\n * @param relPath 候选文件工作区相对路径('/' 分隔)\n * @returns 是否命中\n */\nexport function chunkMatchesFile(chunk: string, relPath: string): boolean {\n const clean = String(chunk || '').replace(/^@/, '').replace(/\\\\/g, '/')\n const rel = String(relPath || '').replace(/\\\\/g, '/')\n if (!clean || !rel) return false\n if (clean === rel) return true\n const chunkBase = (clean.split('/').pop() ?? '').toLowerCase()\n const fileBase = (rel.split('/').pop() ?? '').toLowerCase()\n if (!chunkBase || !fileBase) return false\n if (chunkBase === fileBase) return true\n return chunkBase === fileBase.replace(/\\.[^.]+$/, '')\n}\n\n/**\n * 配置 → DAP request 类型:显式 request 优先;emmylua_attach 旧配置缺 request 时按 attach 兼容。\n * @author ddj 2026年09月21号\n * @param config 调试配置(取 type/request 两字段)\n * @returns 'attach' | 'launch'\n */\nexport function requestOfConfig(config: Pick<DapDebugConfig, 'type' | 'request'>): 'attach' | 'launch' {\n if (config.request === 'attach' || config.request === 'launch') return config.request\n return config.type === 'emmylua_attach' ? 'attach' : 'launch'\n}\n\n/**\n * 是否应发送 configurationDone(DAP 标准握手收尾:断点下发完 → configurationDone → 目标开跑)。\n * 仅当适配器在 initialize 响应声明 supportsConfigurationDoneRequest 时发送;\n * emmylua 适配器未声明该能力(实测响应体仅 5 个 supports* 字段)→ 不发,Lua 行为不变。\n * @author ddj 2026年09月21号\n * @param caps initialize 响应 body(capabilities)\n */\nexport function needsConfigurationDone(caps: Record<string, unknown> | null | undefined): boolean {\n return caps?.supportsConfigurationDoneRequest === true\n}\n\n/**\n * stopped 事件 body → 当前线程 id:多线程适配器(coreclr 等)取真实 threadId,\n * 缺省/非法回退 1(单线程适配器 emmylua 语义不变)。\n * @author ddj 2026年09月21号\n * @param body stopped 事件 body\n */\nexport function threadIdOfStopped(body: Record<string, unknown>): number {\n const id = body.threadId\n return typeof id === 'number' && Number.isInteger(id) && id > 0 ? id : 1\n}\n\n/**\n * setBreakpoints 响应 body → 断点回执(DAP 顺序与请求一致;缺行回退请求行)。\n * 适配器会把断点挪到最近可绑定行并给出 verified/message——必须消费而非造假回执。\n * @author ddj 2026年09月21号\n * @param body setBreakpoints 响应 body(breakpoints 数组)\n * @param items 本次请求的断点(回退基准)\n */\nexport function bpAcksOfResponse(body: unknown, items: DapBreakpointInput[]): DapBreakpointAck[] {\n const list = (body as { breakpoints?: unknown } | null)?.breakpoints\n if (!Array.isArray(list)) return items.map((it) => ({ line: it.line, verified: true }))\n return list.map((item, i) => {\n const b = (item ?? {}) as Record<string, unknown>\n const line = typeof b.line === 'number' && b.line >= 1 ? b.line : items[i]?.line ?? 0\n const ack: DapBreakpointAck = { line, verified: b.verified === true }\n if (typeof b.message === 'string' && b.message) ack.message = b.message\n return ack\n })\n}\n","/**\n * dsh-vscode-mode client — 调试断点集合(纯函数 + localStorage 持久)。\n * 存储:`edrv.dap.bp.<scope>` → Record<relPath, BpEntry[]>(行升序)。\n * scope 与编辑器状态作用域一致(workspaceScopeOf 产物),跨刷新保留。\n * 作者 ddj 2026年09月29号\n */\n\n/** 单条断点。 */\nexport interface BpEntry {\n line: number\n enabled: boolean\n /** 命中条件表达式(Lua,如 count % 10 == 0;空=无条件)。 */\n condition?: string\n /** 命中次数条件(适配器 hitCondition,如 >=5)。 */\n hitCondition?: string\n /** 日志断点消息(适配器 logMessage;存在时命中不打断仅打日志)。 */\n logMessage?: string\n}\n\n/** 断点表:relPath → 条目列表。 */\nexport type BpMap = Record<string, BpEntry[]>\n\n/** localStorage key 前缀。 */\nconst KEY_PREFIX = 'edrv.dap.bp.'\n\n/**\n * 读断点表(缺失/损坏返回空表)。\n * @author ddj 2026年09月29号\n * @param scope 状态作用域\n */\nexport function loadBpMap(scope: string): BpMap {\n try {\n const raw = localStorage.getItem(KEY_PREFIX + scope)\n if (!raw) return {}\n const data = JSON.parse(raw)\n if (!data || typeof data !== 'object' || Array.isArray(data)) return {}\n const out: BpMap = {}\n for (const [path, list] of Object.entries(data as Record<string, unknown>)) {\n if (!Array.isArray(list)) continue\n const entries: BpEntry[] = []\n for (const item of list) {\n if (!item || typeof item !== 'object') continue\n const line = (item as BpEntry).line\n if (typeof line !== 'number' || line < 1) continue\n const entry: BpEntry = { line, enabled: (item as BpEntry).enabled !== false }\n if (typeof (item as BpEntry).condition === 'string') entry.condition = (item as BpEntry).condition\n if (typeof (item as BpEntry).hitCondition === 'string') entry.hitCondition = (item as BpEntry).hitCondition\n if (typeof (item as BpEntry).logMessage === 'string') entry.logMessage = (item as BpEntry).logMessage\n entries.push(entry)\n }\n if (entries.length) out[path] = entries.sort((a, b) => a.line - b.line)\n }\n return out\n } catch {\n return {}\n }\n}\n\n/**\n * 写断点表(空表时清 key;写失败静默)。\n * @author ddj 2026年09月29号\n * @param scope 状态作用域\n * @param map 断点表\n */\nexport function saveBpMap(scope: string, map: BpMap): void {\n try {\n const keys = Object.keys(map)\n if (!keys.length) localStorage.removeItem(KEY_PREFIX + scope)\n else localStorage.setItem(KEY_PREFIX + scope, JSON.stringify(map))\n } catch { /* 无 localStorage 环境:仅内存生效 */ }\n}\n\n/**\n * 切换某文件某行断点(纯函数,返回新表与是否新增)。\n * @author ddj 2026年09月29号\n * @param map 原表\n * @param path 文件相对路径\n * @param line 行号\n */\nexport function toggleBp(map: BpMap, path: string, line: number): { map: BpMap; added: boolean } {\n const list = map[path] ?? []\n const hit = list.find((item) => item.line === line)\n let nextList: BpEntry[]\n let added: boolean\n if (hit) {\n nextList = list.filter((item) => item.line !== line)\n added = false\n } else {\n nextList = [...list, { line, enabled: true }].sort((a, b) => a.line - b.line)\n added = true\n }\n const next: BpMap = { ...map }\n if (nextList.length) next[path] = nextList\n else delete next[path]\n return { map: next, added }\n}\n\n/**\n * 取某文件启用的断点行(升序)。\n * @author ddj 2026年09月29号\n * @param map 断点表\n * @param path 文件相对路径\n */\nexport function bpLinesOf(map: BpMap, path: string): number[] {\n return (map[path] ?? []).filter((item) => item.enabled).map((item) => item.line)\n}\n\n/**\n * 取某文件禁用的断点行(升序;灰点展示用)。\n * @author ddj 2026年09月29号\n * @param map 断点表\n * @param path 文件相对路径\n */\nexport function bpDisabledLinesOf(map: BpMap, path: string): number[] {\n return (map[path] ?? []).filter((item) => !item.enabled).map((item) => item.line)\n}\n\n/**\n * 断点表规模(跨文件总数;版本指纹用)。\n * @author ddj 2026年09月29号\n * @param map 断点表\n */\nexport function bpTotalOf(map: BpMap): number {\n let total = 0\n for (const list of Object.values(map)) total += list.length\n return total\n}\n\n/**\n * 全量启停所有断点(不删条目,只改 enabled;纯函数)。\n * @author ddj 2026年09月21号\n * @param map 原表\n * @param enabled 目标启用态\n */\nexport function setAllEnabled(map: BpMap, enabled: boolean): BpMap {\n const next: BpMap = {}\n for (const [path, list] of Object.entries(map)) {\n if (!list.length) continue\n next[path] = list.map((item) => (item.enabled === enabled ? item : { ...item, enabled }))\n }\n return next\n}\n\n/**\n * 清空所有断点(纯函数;不修改原表)。\n * 同时返回曾有条目的文件清单(store 逐文件 syncPoints 空载荷用)。\n * @author ddj 2026年09月21号\n * @param map 原表\n */\nexport function removeAll(map: BpMap): { map: BpMap; files: string[] } {\n return { map: {}, files: Object.keys(map).filter((path) => (map[path] ?? []).length > 0) }\n}\n\n/**\n * 更新某行断点的编辑字段(条件/命中次数/日志;纯函数)。\n * 空串视为清除该字段。\n * @author ddj 2026年09月29号\n * @param map 原表\n * @param path 文件相对路径\n * @param line 行号\n * @param fields 要写入的字段(undefined = 不变)\n */\nexport function updateBpFields(\n map: BpMap,\n path: string,\n line: number,\n fields: { condition?: string; hitCondition?: string; logMessage?: string },\n): BpMap {\n const clean = (value?: string): string | undefined => {\n const trimmed = typeof value === 'string' ? value.trim() : undefined\n return trimmed ? trimmed : undefined\n }\n const list = (map[path] ?? []).map((item) => {\n if (item.line !== line) return item\n const next: BpEntry = { ...item }\n if (fields.condition !== undefined) next.condition = clean(fields.condition)\n if (fields.hitCondition !== undefined) next.hitCondition = clean(fields.hitCondition)\n if (fields.logMessage !== undefined) next.logMessage = clean(fields.logMessage)\n return next\n })\n return { ...map, [path]: list }\n}\n\n/** 断点行跳转入参(调试面板行视图:文件路径 + 条目)。 */\nexport interface BpJumpRowLike {\n path?: string\n entry?: { line?: number }\n}\n\n/** 断点行跳转目标(1-based;列固定 1,与搜索面板命中跳转同口径)。 */\nexport interface BpJumpTarget {\n path: string\n line: number\n column: number\n}\n\n/**\n * 推导断点行的跳转目标(调试面板点击断点项 → 打开文件并定位到断点行)。\n * 路径缺失或行号非 ≥1 的有限数时返回 null(提前返回,不发起无效导航)。\n * @author ddj 2026年09月21号\n * @param row 面板行视图(文件路径 + 断点条目)\n * @returns 跳转目标;入参不合法时返回 null\n */\nexport function bpJumpTargetOf(row: BpJumpRowLike | null | undefined): BpJumpTarget | null {\n const path = typeof row?.path === 'string' ? row.path : ''\n const line = row?.entry?.line\n if (!path || typeof line !== 'number' || !Number.isFinite(line) || line < 1) return null\n return { path, line: Math.floor(line), column: 1 }\n}\n\n/**\n * 路径是否为可下断点的调试目标(当前调试器为 Lua;按扩展名后缀匹配,\n * 支持 '.lua' 与 '.lua.bytes' 这类带尾缀的 Unity 资产形态)。\n * @author ddj 2026年09月29号\n * @param path 文件路径(相对/绝对均可)\n * @param exts 允许的扩展名列表(默认 ['.lua'];大小写不敏感)\n */\nexport function isDebuggablePath(path: string, exts: readonly string[] = ['.lua']): boolean {\n const lower = String(path || '').toLowerCase()\n if (!lower) return false\n return exts.some((ext) => lower.endsWith(String(ext).toLowerCase()))\n}\n","/**\n * dsh-vscode-mode client — DAP 变量树纯函数。\n * 把 DAP variablesReference 缓存展平成可渲染 sibling rows,避免把子行嵌套进父级\n * 横向 flex 行导致变量重叠;同时限制递归深度与总行数,保护侧栏性能。\n * 作者 ddj 2026年09月29号\n */\n\n/** DAP 变量最小视图。 */\nexport interface VariableLike {\n name: string\n value: string\n type?: string\n ref: number\n}\n\n/** 展平后的变量行。 */\nexport interface VariableRow {\n key: string\n variable: VariableLike\n depth: number\n}\n\n/** 展平选项。 */\nexport interface VariableTreeOptions {\n maxRows?: number\n maxDepth?: number\n}\n\n/**\n * 将变量树展平为 sibling rows;循环 ref 只展开一次,避免异常适配器数据造成递归。\n * @author ddj 2026年09月29号\n * @param roots 根变量\n * @param expanded 已展开的 variablesReference\n * @param cache ref → 子变量缓存\n * @param options 行数/深度上限\n */\nexport function flattenVariableRows(\n roots: readonly VariableLike[],\n expanded: ReadonlySet<number>,\n cache: ReadonlyMap<number, readonly VariableLike[]>,\n options: VariableTreeOptions = {},\n): VariableRow[] {\n const rows: VariableRow[] = []\n const maxRows = options.maxRows ?? 1000\n const maxDepth = options.maxDepth ?? 32\n const walk = (items: readonly VariableLike[], depth: number, ancestry: ReadonlySet<number>, prefix: string): void => {\n if (depth > maxDepth || rows.length >= maxRows) return\n for (let index = 0; index < items.length && rows.length < maxRows; index += 1) {\n const variable = items[index]\n const key = prefix + '/' + index + ':' + variable.name\n rows.push({ key, variable, depth })\n if (variable.ref <= 0 || !expanded.has(variable.ref) || ancestry.has(variable.ref)) continue\n const children = cache.get(variable.ref)\n if (!children?.length) continue\n const nextAncestry = new Set(ancestry)\n nextAncestry.add(variable.ref)\n walk(children, depth + 1, nextAncestry, key)\n }\n }\n walk(roots, 0, new Set(), 'root')\n return rows\n}\n","/**\n * dsh-vscode-mode client — 调试面板断点行右键菜单条目(纯函数,可单测)。\n * 对齐 CodeBuddy(VS Code 内核)断点视图行上下文菜单:\n * 编辑断点… / 编辑条件… / 编辑命中次数… / 编辑记录点… / 启用|禁用断点 / 删除断点。\n * 四个编辑条目都打开面板行内编辑器,仅初始模式不同\n * (0 表达式 / 1 命中次数 / 2 日志消息;\"编辑断点…\"按现有字段自动判定)。\n * 本模块只产出条目数据,onClick 由 DebugPanel 装配(无副作用)。\n * 作者 ddj 2026年09月21号\n */\n\n/** 菜单动作 id。 */\nexport type BpRowMenuAction =\n | 'edit'\n | 'edit-condition'\n | 'edit-hit-count'\n | 'edit-logpoint'\n | 'enable'\n | 'disable'\n | 'remove'\n\n/** 一条菜单条目。 */\nexport interface BpRowMenuEntry {\n id: BpRowMenuAction\n label: string\n /** 前置分隔线(编辑组与启停/删除组之间,对齐 CodeBuddy)。 */\n separator?: boolean\n}\n\n/** 菜单构造输入。 */\nexport interface BpRowMenuState {\n /** 当前断点是否启用(禁用态显示「启用断点」)。 */\n enabled?: boolean\n}\n\n/**\n * 构造调试面板断点行右键菜单条目。\n * @author ddj 2026年09月21号\n * @param state 行内断点状态\n * @returns 菜单条目列表(顺序即展示顺序)\n */\nexport function buildBpRowMenu(state: BpRowMenuState): BpRowMenuEntry[] {\n const enabled = state.enabled !== false\n return [\n { id: 'edit', label: '编辑断点…' },\n { id: 'edit-condition', label: '编辑条件…' },\n { id: 'edit-hit-count', label: '编辑命中次数…' },\n { id: 'edit-logpoint', label: '编辑记录点…' },\n enabled\n ? { id: 'disable', label: '禁用断点', separator: true }\n : { id: 'enable', label: '启用断点', separator: true },\n { id: 'remove', label: '删除断点' },\n ]\n}\n","/**\n * dsh-vscode-mode client — Monaco 编辑器 model 路径归一化(纯函数,可单测)。\n * 与 EditorView 原 modelPathOf 逐字同逻辑,提取共享防止\"编辑器切换断点\"与\n * \"调试面板新增断点\"两处口径漂移(断点表 key 必须同源)。\n * 作者 ddj 2026年09月21号\n */\n\n/** 最小编辑器形状(仅声明用到的 model.uri.path 链)。 */\nexport interface EditorPathLike {\n getModel?: () => { uri?: { path?: string } } | null\n}\n\n/**\n * 取当前 model 的文件路径(uri.path → 去首斜杠 → decode)。\n * 无 model / 无 uri.path 时返回 null(调用方降级提示,不产生断点)。\n * @author ddj 2026年09月21号\n * @param editor Monaco 编辑器实例(或形状兼容对象)\n * @returns 归一化路径;不可用时 null\n */\nexport function editorModelPathOf(editor: unknown): string | null {\n const uriPath = (editor as EditorPathLike | null)?.getModel?.()?.uri?.path\n return uriPath ? decodeURIComponent(String(uriPath).replace(/^\\//, '')) : null\n}\n","/**\n * dsh-vscode-mode client — 调试面板四段分栏高度(纯函数 + localStorage 持久)。\n * 对齐 VS Code/CodeBuddy splitview 语义:段间 sash 拖动时相邻两段高度重分配\n * (拖下 = 上段增高、下段减矮;任一段触到夹取界时拖动量被\"吸收\",分隔条停在可行位置)。\n * 存储:`edrv.dap.split.<scope>` → { variables, watch, stack, breakpoints }。\n * 作者 ddj 2026年09月21号\n */\n\n/** 分栏段 key(与 DebugPanel section key 一致)。 */\nexport const SPLIT_KEYS = ['variables', 'watch', 'stack', 'breakpoints'] as const\n/** 分栏段 key 类型。 */\nexport type SplitKey = (typeof SPLIT_KEYS)[number]\n\n/** 默认高度(沿用重构前各段 max-height 值,改前改后视觉一致)。 */\nexport const DEFAULT_HEIGHTS: Record<SplitKey, number> = { variables: 360, watch: 220, stack: 180, breakpoints: 260 }\n/** 单段最小高度(低于此不可再压缩)。 */\nexport const MIN_H = 64\n/** 单段最大高度(防无限拖爆面板)。 */\nexport const MAX_H = 1200\n\n/** localStorage key 前缀。 */\nconst KEY_PREFIX = 'edrv.dap.split.'\n\n/**\n * 夹取单段高度到 [MIN_H, MAX_H](非有限数回退最小值)。\n * @author ddj 2026年09月21号\n * @param px 目标高度\n */\nexport function clampSectionHeight(px: number): number {\n if (!Number.isFinite(px)) return MIN_H\n return Math.min(MAX_H, Math.max(MIN_H, Math.round(px)))\n}\n\n/**\n * 归一化高度表:非对象/缺 key 回退默认,非法值丢弃(损坏安全)。\n * @author ddj 2026年09月21号\n * @param input localStorage 解析结果\n */\nexport function sanitizeHeights(input: unknown): Record<SplitKey, number> {\n const out: Record<SplitKey, number> = { ...DEFAULT_HEIGHTS }\n if (!input || typeof input !== 'object' || Array.isArray(input)) return out\n const data = input as Record<string, unknown>\n for (const key of SPLIT_KEYS) {\n const value = data[key]\n if (typeof value === 'number' && Number.isFinite(value)) out[key] = clampSectionHeight(value)\n }\n return out\n}\n\n/**\n * 相邻两段高度重分配:above += dy、below −= dy,各自夹取;\n * 一段被夹取吸收的量补给另一段(分隔条停在可行位置,拖动量尽量生效)。\n * @author ddj 2026年09月21号\n * @param heights 拖动起点高度表(不修改入参)\n * @param above 上邻段 key\n * @param below 下邻段 key\n * @param dy 拖动位移(>0 向下拖 = 上段增高)\n * @returns 新高度表\n */\nexport function redistribute(\n heights: Record<SplitKey, number>,\n above: SplitKey,\n below: SplitKey,\n dy: number,\n): Record<SplitKey, number> {\n const clean = Math.round(Number.isFinite(dy) ? dy : 0)\n const next: Record<SplitKey, number> = { ...heights }\n const startAbove = heights[above] ?? MIN_H\n const startBelow = heights[below] ?? MIN_H\n const targetAbove = clampSectionHeight(startAbove + clean)\n const targetBelow = clampSectionHeight(startBelow - clean)\n next[above] = targetAbove\n next[below] = targetBelow\n // 夹取吸收量:>0 表示该段未能吃满 dy,按原方向补给另一段\n const lostAbove = startAbove + clean - targetAbove\n const lostBelow = startBelow - clean - targetBelow\n if (lostAbove > 0) next[below] = clampSectionHeight(targetBelow + lostAbove)\n else if (lostBelow > 0) next[above] = clampSectionHeight(targetAbove + lostBelow)\n return next\n}\n\n/**\n * 读高度表(缺失/损坏回退默认值)。\n * @author ddj 2026年09月21号\n * @param scope 状态作用域\n */\nexport function loadSectionHeights(scope: string): Record<SplitKey, number> {\n if (!scope) return { ...DEFAULT_HEIGHTS }\n try {\n const raw = localStorage.getItem(KEY_PREFIX + scope)\n return sanitizeHeights(raw ? JSON.parse(raw) : null)\n } catch {\n return { ...DEFAULT_HEIGHTS }\n }\n}\n\n/**\n * 写高度表(写失败静默;写入前归一化)。\n * @author ddj 2026年09月21号\n * @param scope 状态作用域\n * @param heights 高度表\n */\nexport function saveSectionHeights(scope: string, heights: Record<SplitKey, number>): void {\n try { localStorage.setItem(KEY_PREFIX + scope, JSON.stringify(sanitizeHeights(heights))) } catch { /* 忽略 */ }\n}\n","// @ts-nocheck\n/**\n * dsh-vscode-mode client — 侧边栏「调试」面板(对齐 CodeBuddy「运行和调试」视图)。\n * 顶部工具条:配置下拉 + 启动/继续 + 暂停 + 单步组 + 停止(禁用逻辑镜像编辑器浮动条)。\n * 四段折叠区(变量 / 监视 / 调用堆栈 / 断点,图2 顺序)+ 底部调试控制台(REPL);\n * 每段头部可折叠(状态按 scope 持久化)且带悬浮动作按钮。\n * 断点多方式管理(对齐 CodeBuddy 断点区):段头「新建断点」菜单(条件断点/记录点,\n * 落在活动编辑器光标行)、禁用/启用所有、删除所有;断点行右键菜单(编辑条件/命中次数/\n * 记录点/启停/删除)→ 行内展开编辑器(Enter 提交 / Escape 取消,字段语义同 BpWidget);\n * 行内点展示适配器回执(未验证 = 空心点 + tooltip)。\n * 数据自取:paused 时经 dapStore 拉栈/作用域/变量/监视求值;断点读写 dapStore 断点表;\n * 输出流 = host poll 事件缓存(outputs)。host 不可达或未暂停时各段空态降级。\n * 断点行整行可点:除启停 checkbox 与删除 × 外,点击任一处即打开并定位到该断点行。\n * 作者 ddj 2026年09月29号 / 2026年09月21号\n */\nimport React from 'react'\nimport { DAP_LAUNCH_REL } from '../../../shared/dap.js'\nimport { dapStore } from '../../dap/store.js'\nimport { bpJumpTargetOf } from '../../dap/breakpoints.js'\nimport { flattenVariableRows } from '../../dap/variableTree.js'\nimport { buildBpRowMenu } from '../../dap/bpRowMenu.js'\nimport { editorModelPathOf } from '../../dap/modelPath.js'\nimport { redistribute, loadSectionHeights, saveSectionHeights, type SplitKey } from '../../dap/panelSplit.js'\nimport { BP_MODE, MODES as BP_WIDGET_MODES, fieldOfMode } from '../../dap/BpWidget.js'\nimport { ContextMenu } from '../../ui/ContextMenu.js'\nimport { rpc } from '../../rpc.js'\nimport type { SidebarCtx } from '../types.js'\n\n/** 变量展开缓存上限(ref → 子级;防长会话累积)。 */\nconst VAR_CACHE_CAP = 200\n/** REPL 历史行上限。 */\nconst REPL_CAP = 200\n/** 监视持久化 key 前缀(CACHE_KEY 无调试段,自管命名空间)。 */\nconst WATCH_KEY = 'edrv.dap.watch.'\n/** 段折叠持久化 key 前缀(存折叠段名数组;损坏安全,默认全展开)。 */\nconst FOLD_KEY = 'edrv.dap.fold.'\n\n/** 调试配置文件(工作区相对路径;⚙ 按钮跳转/新建目标;与 VS Code 的 .vscode/launch.json 互不干扰)。 */\nconst LAUNCH_REL = DAP_LAUNCH_REL\n/** 新建调试配置模板(JSONC;示例按本机已装的 EmmyLua 适配器写)。 */\nconst LAUNCH_TEMPLATE = `{\n // DSH 调试配置(插件专属 .dsh/launch.json,支持注释;改完整页刷新生效)\n // type 来自本机已装扩展的 contributes.debuggers(EmmyLua:emmylua_attach / emmylua_launch / emmylua_new)\n \"version\": \"0.2.0\",\n \"configurations\": [\n {\n \"name\": \"附加 Unity (xLua)\",\n \"type\": \"emmylua_attach\",\n \"request\": \"attach\",\n \"processName\": \"Unity\",\n \"captureLog\": true\n }\n ]\n}`\n\n/** 相位徽标文案。 */\nconst PHASE_LABEL = { idle: '未启动', starting: '启动中…', waiting: '等待目标…', running: '运行中', paused: '已暂停', terminated: '已结束' }\n\n/** 读取监视表达式列表(损坏安全)。 */\nfunction loadWatches(scope) {\n if (!scope) return []\n try {\n const raw = window.localStorage.getItem(WATCH_KEY + scope)\n const list = raw ? JSON.parse(raw) : []\n return Array.isArray(list) ? list.filter((item) => typeof item === 'string' && item.trim()) : []\n } catch {\n return []\n }\n}\n\n/** 写监视表达式列表。 */\nfunction saveWatches(scope, list) {\n try { window.localStorage.setItem(WATCH_KEY + scope, JSON.stringify(list)) } catch { /* 忽略 */ }\n}\n\n/** 读折叠段名列表(损坏安全;非字符串项丢弃)。 */\nfunction loadFolds(scope) {\n if (!scope) return []\n try {\n const raw = window.localStorage.getItem(FOLD_KEY + scope)\n const list = raw ? JSON.parse(raw) : []\n return Array.isArray(list) ? list.filter((item) => typeof item === 'string' && item) : []\n } catch {\n return []\n }\n}\n\n/** 写折叠段名列表(写失败静默)。 */\nfunction saveFolds(scope, list) {\n try { window.localStorage.setItem(FOLD_KEY + scope, JSON.stringify(list)) } catch { /* 忽略 */ }\n}\n\n/**\n * 「调试」面板组件。\n * @param ctx 侧栏上下文(openFileAt 跳转 / scope 持久化 / cwd / editor 光标)\n */\nexport function DebugPanel({ ctx }) {\n const scope = ctx?.scope || ''\n const [, setTick] = React.useState(0)\n React.useEffect(() => dapStore.subscribe(() => setTick((t) => t + 1)), [])\n const snap = dapStore.getSnapshot()\n const paused = snap.phase === 'paused'\n const dapActive = snap.phase !== 'idle' && snap.phase !== 'terminated'\n\n // 数据状态(paused 变化/停帧变化时重拉)\n const [stacks, setStacks] = React.useState([])\n const [scopes, setScopes] = React.useState([])\n const [varCache, setVarCache] = React.useState(() => new Map())\n const [expanded, setExpanded] = React.useState(() => new Set())\n const [watches, setWatches] = React.useState(() => loadWatches(scope))\n const [watchHits, setWatchHits] = React.useState({})\n const [watchDraft, setWatchDraft] = React.useState('')\n const [replLog, setReplLog] = React.useState([])\n const [replDraft, setReplDraft] = React.useState('')\n // 段折叠(folded 段名集合;localStorage 按 scope 持久)\n const [folds, setFolds] = React.useState(() => new Set(loadFolds(scope)))\n // 分栏高度(四段 splitview;拖动 sash 相邻重分配,按 scope 持久)\n const [heights, setHeights] = React.useState(() => loadSectionHeights(scope))\n const [splitDragging, setSplitDragging] = React.useState(false)\n // 菜单态:断点行右键 / 段头「新建断点」下拉\n const [bpMenu, setBpMenu] = React.useState(null)\n const [newBpMenu, setNewBpMenu] = React.useState(null)\n // 断点行内编辑态:{ path, line, mode, drafts }(drafts 三字段同 BpWidget 记忆口径)\n const [bpEdit, setBpEdit] = React.useState(null)\n // 进程候选选择(candidates 非空时镜像浮动条的选择模式)\n const [pickPid, setPickPid] = React.useState(0)\n const watchInputRef = React.useRef(null)\n const stackTopKey = paused && snap.topFrame ? snap.topFrame.file + ':' + snap.topFrame.line : ''\n\n // 工作区同步 + 配置预拉(幂等;与 EditorView 的 cwd 副作用互不冲突)\n React.useEffect(() => {\n if (!ctx?.cwd) return\n dapStore.setWorkspace(ctx.cwd)\n void dapStore.ensureConfigs()\n }, [ctx?.cwd])\n\n // paused:拉调用栈 + 作用域 + 首帧变量 + 监视求值;非 paused 清空(reloadTick 手动刷新)\n const [reloadTick, setReloadTick] = React.useState(0)\n React.useEffect(() => { if (!paused) {\n setStacks([]); setScopes([]); setVarCache(new Map()); setExpanded(new Set()); setWatchHits({})\n return\n }\n let alive = true\n const load = async () => {\n const frames = await dapStore.stackTrace()\n if (!alive) return\n setStacks(frames)\n const list = await dapStore.scopes(snap.selectedFrameId)\n if (!alive) return\n setScopes(list)\n const first = list[0]\n if (first?.ref) {\n const vars = await dapStore.variables(first.ref)\n if (!alive) return\n setVarCache((prev) => new Map(prev).set(first.ref, vars))\n setExpanded((prev) => new Set(prev).add(first.ref))\n }\n const hits = {}\n for (const expr of watches) {\n const r = await dapStore.evaluate(expr, snap.selectedFrameId)\n hits[expr] = r\n }\n if (alive) setWatchHits(hits)\n }\n void load()\n return () => { alive = false }\n }, [paused, stackTopKey, snap.selectedFrameId, watches, reloadTick])\n\n // 展开变量节点(懒拉子级)\n const expandVar = async (ref) => {\n setExpanded((prev) => {\n const next = new Set(prev)\n if (next.has(ref)) next.delete(ref)\n else next.add(ref)\n return next\n })\n if (!varCache.has(ref)) {\n const vars = await dapStore.variables(ref)\n setVarCache((prev) => {\n const next = new Map(prev)\n next.set(ref, vars)\n if (next.size > VAR_CACHE_CAP) next.delete(next.keys().next().value)\n return next\n })\n }\n }\n\n const addWatch = () => {\n const expr = watchDraft.trim()\n if (!expr || watches.includes(expr)) { setWatchDraft(''); return }\n const next = [...watches, expr]\n setWatches(next)\n saveWatches(scope, next)\n setWatchDraft('')\n if (paused) void dapStore.evaluate(expr, snap.selectedFrameId).then((r) => setWatchHits((prev) => ({ ...prev, [expr]: r })))\n }\n\n const removeWatch = (expr) => {\n const next = watches.filter((item) => item !== expr)\n setWatches(next)\n saveWatches(scope, next)\n }\n\n /** 移除全部监视(段头动作;持久化与命中缓存同步清)。 */\n const clearWatches = () => {\n setWatches([])\n saveWatches(scope, [])\n setWatchHits({})\n }\n\n /** 聚焦监视新增输入(段折叠时先展开,二次点击聚焦)。 */\n const focusWatchInput = () => {\n if (folds.has('watch')) { toggleFold('watch'); return }\n watchInputRef.current?.focus?.()\n }\n\n const runRepl = async () => {\n const expr = replDraft.trim()\n if (!expr) return\n setReplDraft('')\n const r = await dapStore.evaluate(expr, snap.selectedFrameId)\n setReplLog((prev) => {\n const next = [...prev, { expr, result: r.result, type: r.type }]\n return next.length > REPL_CAP ? next.slice(next.length - REPL_CAP) : next\n })\n }\n\n /** 切换段折叠(持久化到 localStorage)。 */\n const toggleFold = (key) => {\n setFolds((prev) => {\n const next = new Set(prev)\n if (next.has(key)) next.delete(key)\n else next.add(key)\n saveFolds(scope, [...next])\n return next\n })\n }\n\n // 分栏拖动:进行中的清理句柄(pointerup 与组件卸载双路径移除 window 监听)\n const splitCleanupRef = React.useRef(null)\n React.useEffect(() => () => {\n const cleanup = splitCleanupRef.current\n if (cleanup) cleanup()\n }, [])\n\n /** 段间 sash 拖动:以起点高度为基准按 dy 相邻重分配;pointerup 持久化(镜像 dapbar 拖动模式)。 */\n const startSplitDrag = (above: SplitKey, below: SplitKey) => (e) => {\n e.preventDefault()\n const startY = e.clientY\n const startHeights = { ...heights }\n const onMove = (ev) => {\n setHeights(redistribute(startHeights, above, below, ev.clientY - startY))\n }\n const detach = () => {\n window.removeEventListener('pointermove', onMove)\n window.removeEventListener('pointerup', onUp)\n splitCleanupRef.current = null\n setSplitDragging(false)\n }\n const onUp = () => {\n detach()\n setHeights((prev) => { saveSectionHeights(scope, prev); return prev })\n }\n splitCleanupRef.current = detach\n window.addEventListener('pointermove', onMove)\n window.addEventListener('pointerup', onUp)\n setSplitDragging(true)\n }\n\n // 断点启停/删除/跳转(checkbox + 红点 + 文件名 + 目录 + 行号徽标;整行可点跳转)\n const cwd = ctx?.cwd || dapStore.workspace()\n const bpMap = dapStore.bpMapOf(scope)\n const bpRows = Object.entries(bpMap).flatMap(([path, list]) => list.map((entry) => ({ path, entry })))\n .sort((a, b) => a.path.localeCompare(b.path) || a.entry.line - b.entry.line)\n const allBpEnabled = bpRows.length > 0 && bpRows.every((row) => row.entry.enabled)\n\n const toggleBpEnabled = (row) => dapStore.setBpEnabled(scope, cwd, row.path, row.entry.line, !row.entry.enabled)\n const removeBp = (row) => dapStore.toggleAt(scope, cwd, row.path, row.entry.line)\n /** 删除所有断点(confirm 守卫;逐文件同步空载荷清空 Monaco 装饰与 host 断点)。 */\n const removeAllBps = () => {\n if (ctx?.confirm && !ctx.confirm('删除所有断点?')) return\n dapStore.removeAllBps(scope, cwd)\n setBpEdit(null)\n }\n // 跳转目标经纯函数守卫(路径缺失/行号非法的行不发起导航);openFileAt 内含 recordNav,\n // 故整行只挂这一个 handler,文件名按钮不再自带 onClick(防双触发双记导航历史)。\n const jumpBp = (row) => {\n const target = bpJumpTargetOf(row)\n if (target) ctx?.openFileAt?.(target.path, target.line, target.column)\n }\n\n // 断点行内编辑器(字段语义同 BpWidget:三字段独立草稿,提交全量落 store,空串清字段)\n const autoBpModeOf = (entry) => (\n entry?.logMessage ? BP_MODE.LOG_MESSAGE : entry?.hitCondition ? BP_MODE.HIT_COUNT : BP_MODE.EXPRESSION\n )\n const openBpRowEditor = (path, line, entry, mode) => {\n setBpEdit({\n path, line,\n mode: typeof mode === 'number' ? mode : autoBpModeOf(entry),\n drafts: {\n condition: entry?.condition || '',\n hitCondition: entry?.hitCondition || '',\n logMessage: entry?.logMessage || '',\n },\n })\n }\n const commitBpEdit = () => {\n if (!bpEdit) return\n dapStore.applyBpFields(scope, cwd, bpEdit.path, bpEdit.line, { ...bpEdit.drafts })\n setBpEdit(null)\n ctx?.notify?.('断点已更新')\n }\n\n /** 断点行右键菜单动作分发(菜单数据由 buildBpRowMenu 产出)。 */\n const runBpRowAction = (action, row) => {\n if (action === 'remove') { removeBp(row); return }\n if (action === 'enable' || action === 'disable') {\n dapStore.setBpEnabled(scope, cwd, row.path, row.entry.line, action === 'enable')\n return\n }\n const mode = action === 'edit-condition' ? BP_MODE.EXPRESSION\n : action === 'edit-hit-count' ? BP_MODE.HIT_COUNT\n : action === 'edit-logpoint' ? BP_MODE.LOG_MESSAGE\n : undefined\n openBpRowEditor(row.path, row.entry.line, row.entry, mode)\n }\n\n /** 段头「新建断点」:条件断点/记录点落在活动编辑器光标行(已有断点则直接编辑不翻转)。 */\n const addBpAtCursor = (mode) => {\n const ed = ctx?.editor?.()\n const path = editorModelPathOf(ed)\n const line = ed?.getPosition?.()?.lineNumber\n if (!path || !line || !Number.isFinite(line)) { ctx?.notify?.('无活动文件,无法添加断点'); return }\n const existing = (dapStore.bpMapOf(scope)[path] ?? []).find((it) => it.line === line)\n if (!existing) dapStore.toggleAt(scope, cwd, path, line)\n const entry = (dapStore.bpMapOf(scope)[path] ?? []).find((it) => it.line === line)\n if (entry) openBpRowEditor(path, line, entry, mode)\n }\n\n /** ⚙ 打开/新建调试配置:存在即跳转;缺失经确认后写模板(edrv.save 无 rev 仅用于新建,绝不覆盖已有文件)。 */\n const openLaunchConfig = async () => {\n if (!ctx?.cwd) { ctx?.notify?.('无工作区,无法定位 ' + LAUNCH_REL); return }\n try {\n const probe = await rpc('edrv.read', { sessionId: ctx?.sessionId, path: LAUNCH_REL }).catch(() => null)\n if (probe?.ok) { ctx?.openFile?.(LAUNCH_REL); return }\n } catch { /* 探活失败按缺失处理 */ }\n if (ctx?.confirm && !ctx.confirm('未找到 ' + LAUNCH_REL + ',是否创建调试配置模板?')) return\n try {\n const saved = await rpc('edrv.save', { sessionId: ctx?.sessionId, path: LAUNCH_REL, content: LAUNCH_TEMPLATE })\n if (!saved?.ok) { ctx?.notify?.(saved?.error || '创建 ' + LAUNCH_REL + ' 失败'); return }\n void dapStore.ensureConfigs(true)\n ctx?.openFile?.(LAUNCH_REL)\n ctx?.notify?.('已创建 ' + LAUNCH_REL)\n } catch (error) {\n ctx?.notify?.('创建 ' + LAUNCH_REL + ' 失败:' + String(error))\n }\n }\n\n /** 段头动作按钮(hover 显隐,样式见 .edrv-dapseg-act)。 */\n const segAct = (key, label, title, onClick) => React.createElement('button', {\n key, className: 'edrv-dapseg-act', title,\n onClick: (e) => { e.stopPropagation(); onClick(e) },\n }, label)\n\n /** 折叠段壳:chevron + 标题 + 悬浮动作区 + 可折叠主体(高度由分栏 state 内联接管)。 */\n const section = (title, key, variant, actions, children) => {\n const folded = folds.has(key)\n return React.createElement('div', { className: 'edrv-dapseg edrv-dapseg-' + variant, key },\n React.createElement('div', { className: 'edrv-dapseg-head', onClick: () => toggleFold(key) },\n React.createElement('span', { className: 'edrv-dapseg-chevron', title: folded ? '展开' : '折叠' }, folded ? '▸' : '▾'),\n React.createElement('span', { className: 'edrv-dapseg-title' }, title),\n React.createElement('span', { style: { flex: 1 } }),\n ...(folded ? [] : (actions || []))),\n ...(folded ? [] : [React.createElement('div', {\n className: 'edrv-dapseg-body', style: { height: (heights[key] ?? 200) + 'px' },\n }, ...children)]))\n }\n\n /** 段间分隔条(两侧段都展开时才渲染;拖动调整相邻两段高度占比)。 */\n const sash = (above: SplitKey, below: SplitKey) => (folds.has(above) || folds.has(below) ? null : React.createElement('div', {\n key: 'sash-' + above + '-' + below,\n className: 'edrv-dapseg-sash' + (splitDragging ? ' dragging' : ''),\n title: '拖动调整上下两段高度占比',\n onPointerDown: startSplitDrag(above, below),\n }))\n\n const renderVarRow = (row) => {\n const v = row.variable\n const depth = row.depth + 1\n return React.createElement('div', { key: row.key, className: 'edrv-dapvar', style: { paddingLeft: 8 + depth * 12 } },\n v.ref > 0\n ? React.createElement('button', {\n className: 'edrv-dapvar-tw', title: expanded.has(v.ref) ? '折叠' : '展开',\n onClick: () => { void expandVar(v.ref) },\n }, expanded.has(v.ref) ? '▾' : '▸')\n : React.createElement('span', { className: 'edrv-dapvar-tw' }, ''),\n React.createElement('span', { className: 'edrv-dapvar-name', title: v.name }, v.name),\n React.createElement('span', { className: 'edrv-dapvar-val', title: v.value }, v.value),\n (v.type ? React.createElement('span', { className: 'edrv-dapvar-type' }, v.type) : null))\n }\n\n const stackRows = stacks.length\n ? stacks.map((f) => React.createElement('div', {\n key: f.id,\n className: 'edrv-dapframe' + (f.id === snap.selectedFrameId ? ' selected' : ''),\n title: f.rawFile,\n onClick: () => {\n dapStore.selectFrame(f.id)\n const target = f.file || f.rawFile\n if (target) ctx?.openFileAt?.(target, f.line, 1)\n },\n },\n React.createElement('span', { className: 'edrv-dapframe-name' }, f.name || '(anonymous)'),\n React.createElement('span', { className: 'edrv-dapframe-loc' }, (f.file || f.rawFile) + ':' + f.line)))\n : [React.createElement('div', { key: 'empty', className: 'edrv-dapempty' }, paused ? '(无调用栈)' : '暂停时显示调用堆栈')]\n\n const scopeRows = scopes.flatMap((s) => [\n React.createElement('div', { key: 'scope' + s.name, className: 'edrv-dapscope' }, s.name),\n ...flattenVariableRows(varCache.get(s.ref) ?? [], expanded, varCache, { maxRows: 800 }).map(renderVarRow),\n ])\n const varRows = scopes.length ? scopeRows : [React.createElement('div', { key: 'e', className: 'edrv-dapempty' }, '暂停时显示变量')]\n\n const watchRows = watches.flatMap((expr) => {\n const hit = watchHits[expr]\n const rows = [React.createElement('div', { key: expr, className: 'edrv-dapwatch' },\n React.createElement('button', { className: 'edrv-dapwatch-x', title: '移除监视', onClick: () => removeWatch(expr) }, '×'),\n (hit?.ref > 0\n ? React.createElement('button', {\n className: 'edrv-dapvar-tw', title: expanded.has(hit.ref) ? '折叠 table' : '展开 table',\n onClick: () => { void expandVar(hit.ref) },\n }, expanded.has(hit.ref) ? '▾' : '▸')\n : React.createElement('span', { className: 'edrv-dapvar-tw' }, '')),\n React.createElement('span', { className: 'edrv-dapvar-name', title: expr }, expr),\n React.createElement('span', { className: 'edrv-dapvar-val', title: hit?.result || '' }, hit ? '= ' + hit.result : '= 不可用'),\n (hit?.type ? React.createElement('span', { className: 'edrv-dapvar-type' }, hit.type) : null))]\n if (hit?.ref > 0 && expanded.has(hit.ref)) {\n rows.push(...flattenVariableRows(varCache.get(hit.ref) ?? [], expanded, varCache, { maxRows: 500 }).map(renderVarRow))\n }\n return rows\n })\n const watchSection = section('监视', 'watch', 'watch', [\n segAct('watch-add', '+', '新增监视表达式', focusWatchInput),\n segAct('watch-clear', '🗑', '移除全部监视', clearWatches),\n ], [\n ...watchRows,\n React.createElement('div', { key: 'add', className: 'edrv-dapwatch-add' },\n React.createElement('input', {\n ref: watchInputRef,\n className: 'edrv-daprepl-in', placeholder: '新增监视表达式,回车确认',\n value: watchDraft, onChange: (e) => setWatchDraft(e.target.value),\n onKeyDown: (e) => { if (e.key === 'Enter') addWatch() },\n })),\n ])\n\n // 断点行 + 行内编辑行(编辑中的行紧随其后展开,对齐 VS Code 断点视图的行内编辑形态)\n const bpSectionChildren = bpRows.length\n ? bpRows.flatMap((row) => {\n const base = row.path.split('/').pop() || row.path\n const dir = row.path.includes('/') ? row.path.slice(0, row.path.lastIndexOf('/')) : ''\n const ack = dapStore.ackOf(row.path, row.entry.line)\n const unverified = Boolean(ack && !ack.verified)\n const editing = bpEdit && bpEdit.path === row.path && bpEdit.line === row.entry.line\n const rows = [React.createElement('div', {\n key: row.path + ':' + row.entry.line, className: 'edrv-dapbp',\n title: '跳转到 ' + row.path + ':' + row.entry.line\n + (unverified && ack.message ? '(' + ack.message + ')' : ''),\n onClick: () => jumpBp(row),\n onContextMenu: (e) => { e.preventDefault(); setBpMenu({ x: e.clientX, y: e.clientY, row }) },\n },\n React.createElement('input', {\n type: 'checkbox', checked: row.entry.enabled, title: row.entry.enabled ? '禁用断点' : '启用断点',\n onChange: () => toggleBpEnabled(row),\n // 启停不连带跳转(整行可点后必须阻断冒泡)\n onClick: (e) => e.stopPropagation(),\n }),\n React.createElement('span', {\n className: 'edrv-dapbp-dot'\n + (row.entry.enabled ? '' : ' off')\n + (unverified ? ' unverified' : ''),\n title: unverified && ack.message ? ack.message : undefined,\n }),\n React.createElement('button', { className: 'edrv-dapbp-file', title: row.path }, base),\n React.createElement('span', { className: 'edrv-dapbp-dir', title: dir }, dir),\n React.createElement('span', { className: 'edrv-dapbp-line' }, row.entry.line),\n React.createElement('button', {\n className: 'edrv-dapbp-x', title: '删除断点',\n // 删除不连带跳转\n onClick: (e) => { e.stopPropagation(); removeBp(row) },\n }, '×'))]\n if (editing) {\n const fieldKey = fieldOfMode(bpEdit.mode)\n const modeItem = BP_WIDGET_MODES.find((m) => m.mode === bpEdit.mode) ?? BP_WIDGET_MODES[0]\n rows.push(React.createElement('div', { key: row.path + ':' + row.entry.line + ':edit', className: 'edrv-dapbp-edit' },\n React.createElement('select', {\n className: 'edrv-bpwidget-mode', title: '断点类型', value: String(bpEdit.mode),\n onChange: (e) => setBpEdit({ ...bpEdit, mode: Number(e.target.value) }),\n },\n BP_WIDGET_MODES.filter((m) => m.mode !== BP_MODE.WAIT).map((m) => React.createElement('option', { key: m.mode, value: String(m.mode) }, m.label))),\n React.createElement('input', {\n className: 'edrv-bpwidget-input', autoFocus: true, spellCheck: false,\n placeholder: modeItem?.placeholder ?? '',\n hidden: fieldKey === null,\n value: fieldKey ? (bpEdit.drafts[fieldKey] || '') : '',\n onChange: (e) => setBpEdit({ ...bpEdit, drafts: { ...bpEdit.drafts, [fieldKey]: e.target.value } }),\n onKeyDown: (e) => {\n if (e.key === 'Enter') { e.preventDefault(); commitBpEdit(); return }\n if (e.key === 'Escape') { e.preventDefault(); setBpEdit(null) }\n },\n })))\n }\n return rows\n })\n : [React.createElement('div', { key: 'e', className: 'edrv-dapempty' }, '在编辑器行首点击或 F9 添加断点')]\n\n const bpSection = section('断点', 'breakpoints', 'breakpoints', [\n segAct('bp-new', '新建断点 ▾', '添加条件断点 / 记录点(落在当前编辑器光标行)', (e) => setNewBpMenu({ x: e.clientX, y: e.clientY })),\n (bpRows.length ? segAct('bp-toggle', allBpEnabled ? '⊘' : '◉', allBpEnabled ? '禁用所有断点' : '启用所有断点', () => dapStore.setAllBpEnabled(scope, cwd, !allBpEnabled)) : null),\n (bpRows.length ? segAct('bp-clear', '🗑', '删除所有断点', removeAllBps) : null),\n ], bpSectionChildren)\n\n const outputRows = dapStore.outputs().slice(-60).map((ev, idx) => React.createElement('div', { key: ev.seq + ':' + idx, className: 'edrv-daprepl-line out' }, ev.text?.trimEnd() || ''))\n\n // 顶部工具条:配置下拉(option 可用性置灰逻辑镜像编辑器浮动条)+ 控制按钮组\n const configReady = snap.configs.some((c) => snap.adapters.length === 0 || snap.adapters.find((a) => a.type === c.type)?.available === true)\n const toolbarBtn = (key, label, title, disabled, onClick) => React.createElement('button', {\n key, className: 'edrv-dappanel-run', title, disabled: disabled === true, onClick,\n }, label)\n\n // 断点行右键菜单(面板内行级操作:编辑字段 / 启停 / 删除;同 EditorView dapBpMenuEl 装配模式)\n const bpMenuEl = bpMenu\n ? React.createElement(ContextMenu, {\n x: bpMenu.x, y: bpMenu.y, onClose: () => setBpMenu(null),\n entries: buildBpRowMenu({ enabled: bpMenu.row.entry.enabled }).map((item) => ({\n id: item.id, label: item.label, separator: item.separator,\n onClick: () => runBpRowAction(item.id, bpMenu.row),\n })),\n })\n : null\n // 段头「新建断点」下拉(条件断点 / 记录点)\n const newBpMenuEl = newBpMenu\n ? React.createElement(ContextMenu, {\n x: newBpMenu.x, y: newBpMenu.y, onClose: () => setNewBpMenu(null),\n entries: [\n { id: 'add-conditional', label: '添加条件断点...', onClick: () => addBpAtCursor(BP_MODE.EXPRESSION) },\n { id: 'add-logpoint', label: '添加记录点...', onClick: () => addBpAtCursor(BP_MODE.LOG_MESSAGE) },\n ],\n })\n : null\n\n return React.createElement('div', { className: 'edrv-dappanel' },\n React.createElement('div', { className: 'edrv-dappanel-head' },\n ...(snap.candidates\n ? [\n React.createElement('select', {\n key: 'pick', className: 'edrv-dappanel-cfg-select', title: '选择附加目标进程(processName 命中多个候选)',\n value: String(pickPid || snap.candidates[0]?.pid || ''),\n onChange: (e) => setPickPid(Number(e.target.value)),\n },\n snap.candidates.map((it) => React.createElement('option', { key: it.pid, value: String(it.pid) },\n it.pid + ' : ' + it.name + (it.title ? ' — ' + it.title.slice(0, 44) : '')))),\n toolbarBtn('pick-ok', '✓', '附加到选中进程', false, () => dapStore.confirmPick(pickPid || snap.candidates![0]?.pid || 0)),\n toolbarBtn('pick-cancel', '✕', '取消', false, () => dapStore.cancelPick()),\n ]\n : [React.createElement('select', {\n key: 'cfg', className: 'edrv-dappanel-cfg-select',\n title: '调试配置(读取工作区 .dsh/launch.json;适配器由扩展清单 contributes.debuggers 提供)',\n value: snap.selectedConfig ?? '',\n onChange: (e) => dapStore.selectConfig(e.target.value),\n },\n snap.configs.length\n ? snap.configs.map((c) => {\n const adapter = snap.adapters.find((a) => a.type === c.type)\n const ready = snap.adapters.length === 0 || adapter?.available === true\n const suffix = ready ? '' : '(' + (adapter?.reason || '未发现该类型适配器') + ')'\n return React.createElement('option', { key: c.name, value: c.name, disabled: !ready }, c.name + suffix)\n })\n : React.createElement('option', { value: '' }, '无可用调试配置'))]),\n toolbarBtn('run', '▶', paused ? '继续(F5)' : '启动调试(F5)', !paused && (!configReady || dapActive), () => dapStore.startOrContinue()),\n toolbarBtn('cfg-gear', '⚙', '打开/新建调试配置(' + LAUNCH_REL + ')', !ctx?.cwd, () => { void openLaunchConfig() }),\n toolbarBtn('pause', '⏸', '暂停', !dapActive, () => { void dapStore.action('pause') }),\n toolbarBtn('next', '⤵', '单步跳过(F10)', !paused, () => { void dapStore.action('next') }),\n toolbarBtn('stepin', '↓', '单步步入(F11)', !paused, () => { void dapStore.action('stepIn') }),\n toolbarBtn('stepout', '↑', '单步步出(Shift+F11)', !paused, () => { void dapStore.action('stepOut') }),\n toolbarBtn('stop', '⏹', '停止(Shift+F5)', !dapActive, () => { void dapStore.stop() }),\n React.createElement('span', { className: 'edrv-dappanel-phase' + (paused ? ' paused' : '') }, PHASE_LABEL[snap.phase] || snap.phase),\n (snap.pid ? React.createElement('span', { className: 'edrv-dappanel-pid' }, 'pid ' + snap.pid) : null),\n React.createElement('span', { style: { flex: 1 } }),\n (snap.error ? React.createElement('span', { className: 'edrv-dappanel-err', title: snap.error }, '⚠') : null)),\n section('变量', 'variables', 'variables', [\n segAct('var-reload', '⟳', '刷新变量', () => setReloadTick((t) => t + 1)),\n ], varRows),\n sash('variables', 'watch'),\n watchSection,\n sash('watch', 'stack'),\n section('调用堆栈', 'stack', 'stack', [], stackRows),\n sash('stack', 'breakpoints'),\n bpSection,\n React.createElement('div', { className: 'edrv-daprepl' },\n React.createElement('div', { className: 'edrv-dapseg-head' }, '调试控制台'),\n React.createElement('div', { className: 'edrv-daprepl-log' },\n ...replLog.map((row, idx) => React.createElement('div', { key: idx, className: 'edrv-daprepl-line' },\n React.createElement('span', { className: 'edrv-dapvar-name' }, row.expr),\n React.createElement('span', { className: 'edrv-dapvar-val' }, '= ' + row.result))),\n ...outputRows),\n React.createElement('input', {\n className: 'edrv-daprepl-in', placeholder: paused ? '输入表达式求值,回车执行(如 self.itemId)' : '暂停时才可求值',\n disabled: !paused, value: replDraft,\n onChange: (e) => setReplDraft(e.target.value),\n onKeyDown: (e) => { if (e.key === 'Enter') void runRepl() },\n })),\n bpMenuEl,\n newBpMenuEl)\n}\n"],"mappings":"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"}
|