- Normalize line endings in Markdown export for DOCX files. - Improve selection serialization to Markdown with better handling of empty documents. - Add a new `updateFile` function to the file system for updating file properties. - Introduce video transcoding capabilities using FFmpeg, supporting various video formats. - Update AGENTS.md for clearer plugin structure and responsibilities. - Add scoped styles for TreeNodeItem component to improve UI consistency. - Implement cross-origin isolation headers in Vite configuration for enhanced security. - Remove obsolete test_cross.py file.
3.5 KiB
3.5 KiB
Plugins 插件层指引
本文件适用于 src/plugins/ 下的插件代码。
插件层职责
- 承接 Milkdown/ProseMirror 与业务逻辑之间的粘合层。
- 负责 AI 补全 ghost text、文档块节点、Mermaid 预览等编辑器级行为。
- 这里的代码状态性很强,误改后通常会出现“看起来还能编译,但交互细节坏掉”的问题。
文件分工
- copilotPlugin.ts:AI 补全主逻辑,包含 ghost text、请求调度、取消、语言识别、隐藏上下文注入和大小限制。
- docBlockPlugin.ts:文档块节点、remark 适配和视图逻辑。
- mermaidPlugin.ts:Mermaid 代码块预览和渲染。
- index.ts:导出入口。
- types.ts:公共类型。
copilotPlugin 的真实职责
- 维护 ghost suggestion 的 plugin state。
- 用 mark + decoration 表示 ghost text,而不是简单的纯字符串缓存。
- 为每个 EditorView 维护 runtime:
- enabled
- debounceTimer
- abortController
- ctx
- requestSeq
- docVersion
- 推断当前光标语言,处理 fenced code、latex、mermaid 等上下文。
- 提取 OCR 缓存和文档块内容,拼到隐藏上下文里。
- 控制请求失效和中止,避免旧请求把新文档状态覆盖掉。
- 在结果插入后恢复合理的光标位置和选择状态。
先看哪些函数
- getCursorLanguageId:判断当前上下文语言
- extractDocBlocksFromMarkdown:从文档块生成隐藏上下文
- doFetchSuggestion:真正发起补全请求
- clearRuntimeRequests:中止定时器和请求
- insertGhostText / insertPlainText:把建议插回编辑器
编辑规则
- 不要把隐藏 OCR 上下文或文档块上下文直接变成最终可见文本,除非需求明确要求。
- 不要破坏 requestSeq 和 AbortController 这套旧请求失效机制。
- 不要随意改 ghost text 的 mark/decorations 表示方式;这会影响显示、接受、拒绝和同步。
- parserCtx 和 serializerCtx 是和 Milkdown 集成的关键上下文,改解析插入逻辑时要一起考虑。
- 插件行为并不完全自洽,很多配置和启停逻辑是在 components/MilkdownEditor.vue 里接上的;不要只在插件内部脑补整体行为。
容易踩坑的点
- 大小限制既有插件常量,也有编辑器 UI 层联动。
- 图片节点类型不止一种名字,代码已经兼容 image、image-block、imageBlock。
- 上下文语言识别会影响 Prompt 行为,改错以后通常不是“报错”,而是补全质量或补全边界变差。
- Mermaid、LaTeX、文档块这几类上下文都和“是否允许补全、是否允许上传”相关。
- 这是状态机式代码;局部改动后要优先验证交互,而不是只看类型通过。
调试顺序
- 如果是“为什么没有发请求”,先查 enabled、size limit、cursor context、debounce 和 abort。
- 如果是“为什么结果插错位置”,先查 ghost range、mapping、selection 恢复。
- 如果是“为什么上下文不对”,先查 OCR 缓存、文档块摘录和语言识别。
- 如果是“为什么改了插件没生效”,再回看 MilkdownEditor.vue 里的 use/config/watch 是否也要一起改。
改动建议
- 先做最小改动。
- 先验证单个交互问题,不要一口气同时改 ghost 插入、语言识别和请求时机。
- 当改动影响请求 payload 时,再考虑是否需要同步后端 Prompt 测试。
- 只有在确认插件本身是控制点时,才在这里改;很多行为实际上是在上层组件里决定的。