← Back to home@DoggyHU

dsh-sidebar-editor

给 DSH 官方右侧栏文档预览追加「编辑器」视图:CodeMirror 源码编辑 + 渲染视图里直接改 Markdown(表格加行加列、Enter 换行、划词批注送进对话框)

Stars
0
Language
JavaScript
Created
Oct 21, 2026
Updated
Oct 21, 2026

Introduction

dsh-sidebar-editor

给 DSH 桌面版侧边栏文档预览增加可编辑视图的补充式插件。

官方预览与官方代码预览保持原样:这个插件只是多注册两个实现,用工具栏的视图下拉切换。官方升级时,插件的排序、slot 与渲染体契约都沿用公开接口,不需要跟着改渲染代码。

版本 1.0.0 · 当前状态与边界见 docs/STATE.md

两个视图

视图适用文件说明
渲染式编辑器(dsh-sidebar-editor-md).md / .markdown默认视图(priority: 'preferred',排序在官方 Markdown 预览之前)。编辑渲染结果,写回 Markdown
编辑器(dsh-sidebar-editor)115 种代码后缀CodeMirror 6 + 官方排版令牌(--ds-font-family-code、--dsw-font-markdown-*)

渲染视图的每个块由官方组件 MarkdownText(@deepseek-ai/dsh-client-ui-primitives)画出,插件运行时 require 它(产物里是外部引用,不打包)。

编辑模型

渲染出来的 DOM 就是编辑面(contenteditable),所以段落、标题、列表、引用、表格在编辑时仍然是渲染形态,不会切到源码。

写盘刻意攒批(边打字边写会重渲染、丢光标):

触发行为
块 → 块(编辑器内部)不写盘(否则点下一个块会因重排丢焦点,需要点两次)
焦点离开整个编辑器写回所有挂起的块
Ctrl/Cmd+S先写回挂起块,再保存文件
页面隐藏 / 切走先写回挂起块
在编辑器外面动一下(点聊天框、敲键)立刻写回 —— 保证"我改完了,按我的意见改"发出去前文件已落盘
文档被关闭(切换对话、关标签页)卸载时写回挂起编辑并立即保存 —— 聚焦的块收不到 focusout,所以这一步必须在卸载时做

写回的是等价 Markdown:* 列表会变成 -、缩进规整;不是逐字节保真。粘贴按纯文本处理。

回车语义:

在哪按 Enter行为
代码块里代码内换行
段落 / 标题 / 列表 / 表格另起一个块(写入 \n\n,光标到新行)—— 表格要加行就手动敲一行 `

表格写回时保留原有的列对齐符(:--- / ---:),不会被拉平成 ---。

代码块是特例:官方代码卡片结构复杂(头部工具条 + 可能的 user-select: none),优先尝试把代码区设为可编辑;不行则给一个**常显的「✎ 编辑」**按钮切到源码模式。

注释(Codex 同款)

选中文字 → 浮出「+ 注释」→ 写意见(Enter 保存 / Shift+Enter 换行 / Esc 取消)→ 底部面板:

  • 面板默认只有 注释 · N + 展开 / 全部发送 / 删除;展开后每条是 编辑 / 删除
  • 「全部发送」通过官方 inputActions.insertText 把 绝对路径 + 行号 + 原文引用 + 意见插进对话输入框,回车即进上下文
  • 拿不到 inputActions 时退化为复制到剪贴板并提示
  • 渲染块上的注释高亮用 CSS Custom Highlight API(不改 DOM,不与 React 打架)

生效方式

  • 客户端产物 lib/client.js:硬刷新即可(Ctrl+Shift+R)
  • 宿主半 src/index.js(路由):需要完全退出并重开 DSH

插件已通过 link: 装进 desktop profile 的 dsh.profile.bundles。

命令

pnpm build        # 打包 src/client → lib/client.js
pnpm test         # 9 套:产物/宿主/真实连接/沙箱写盘/cordis 挂载/编辑器体/渲染体/端到端/注释
pnpm test:layout  # 真实 Chromium:700px 侧边栏量 scrollWidth vs clientWidth(需要本机 Chromium)
pnpm check:live   # 实机自检(读宿主日志 + 客户端报告)

排查

客户端任何失败都会写进宿主日志,找 client: 行:

%TEMP%\dsh-sidebar-editor-host.log

包括:挂载失败(mount)、注释层异常(annotation-layer)、块序列化/写回异常(flush-*、enter-*)、 代码块找不到可编辑面(code-attach,附真实 DOM 前 1500 字符)、块渲染失败(block-render)。

已知边界

  • 写回是等价 Markdown,不是逐字节保真
  • 代码块优先原地编辑、失败退源码模式;编辑期间不做实时高亮(离开块后重新渲染恢复)
  • 块级编辑粒度:一段/一个标题/一张表是一个编辑单元

文件地图

src/index.js                     宿主半:/api/dsh-sidebar-editor/* 路由 + 文件读写 + 沙箱策略
src/client/index.js              客户端入口:注册两个 documentPreview 实现与 slot 渲染体
src/client/EditorBody.jsx        编辑体:CodeMirror、自动保存、冲突处理、注释接线
src/client/blockWidget.js        块渲染 + 原地编辑 + 写回(StateField / Widget)
src/client/markdownSerialize.js  渲染 DOM → Markdown(等价写回)
src/client/officialMarkdown.js   官方 MarkdownText 的挂载与错误边界
src/client/annotations.js        注释:选取浮层、存储、高亮、消息格式
src/client/AnnotationPanel.jsx   注释面板(折叠摘要 + 展开编辑)
src/client/markdownPreview.js    行内装饰(用于源码块的 live preview)
src/client/rendered.js           渲染视图的扩展集合
src/client/languages.js          后缀 → 语法
src/client/theme.js              代码编辑器外观
src/client/address.js            资源地址解析
src/client/channel.js            宿主调用
src/client/extensions.js         CodeMirror 扩展集合
tests/                           9 套测试 + 真实 Chromium 布局测量
docs/STATE.md                    当前状态(版本、行为、边界、排查)
docs/layout-*.png                布局修复前后的实测截图(700px 侧边栏)

附:早期实测留下的标记

以下两行是用户当时在编辑器里手动输入的内容,保留作为"保存链路打通"的痕迹:

333
11 222