Repository navigation
feat(markdown): 预览态就地编辑(VS Code 式锁 / 笔滑钮) - #27
Merged
Merged
Conversation
xhqing
enabled auto-merge (squash)
November 6, 2026 13:30
…ck toggle The markdown panel could only be read (rendered preview) or edited as the whole document (NSTextView source mode). Add a third mode that keeps the rendered document and lets a block be edited where it is. Design: the renderer stamps every top-level block with the byte range it came from, so committing an edit replaces exactly that slice of the file. Nothing is ever re-serialized from HTML, which means blocks the user did not touch — tables, code fences, frontmatter, manual line breaks — keep their original bytes. VS Code's own Markdown Editor engine could not be reused: @vscode/markdown-editor constructs an EditContext, a Chromium-only API that WKWebView does not have (verified: ReferenceError on boot). Milkdown round-trips through remark and rewrites untouched blocks, so it would need a source map to be safe. Block ranges over the existing renderer give the same guarantee with no new engine. The panel gets a pencil button that enters the mode; inside it a lock/pencil pill (VS Code's design pins to the top-right. Clicking content while locked only flashes a shine across the pill. Cmd+S flushes the open block first; switching modes commits before leaving. Verified offscreen in WKWebView (no focus stealing): block ranges tile the whole source with no gaps or overlaps and round-trip byte-identically on README.md, PATCHES.md and a CHANGELOG slice; clicking a block loads its raw markdown, committing posts the edited document, and the locked pill shines instead of opening an editor. Co-Authored-By: pi <noreply@pi.dev> EOF )
xhqing
force-pushed
the
feat/markdown-editor
branch
from
November 6, 2026 13:32
2e07bac to
586ea64
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
背景
Markdown 面板只有「只读渲染」和「整篇源码」两种形态,想改一句话要切到源码模式里找。目标是在渲染结果里直接改内容,交互参照 VS Code 新版 Markdown Editor:右上角「锁 / 笔」滑动开关,锁定时点击内容只闪一道镜面光泽提醒,解锁后点某一块即可就地编辑。
为什么不是「搬 VS Code 的那套」
@vscode/markdown-editor(MIT)在 WebKit 里启动即ReferenceError: Can't find variable: EditContext—— 它用 Chromium 专有的EditContext做文本输入,WKWebView 没有这个 API(本机离屏 WKWebView 实测)。getMarkdown()往返会改写未编辑的块:实测把| --- | --- |写成| -- | -- |、把$$ 块公式 $$变成行内$…$。做法
渲染后把
marked的顶层 token 与渲染出的 DOM 子节点并行走一遍,给每个块打上它在源文件里的[start, end)区间(并做一次平铺校验,保证区间无空隙、无重叠)。点块 → 该块换成这段原文的浮层编辑器;提交 → 只替换这一段字节。因此没动过的块一个字节都不会变:表格、代码围栏、frontmatter、手工换行都保真。只读渲染路径本身没有改动,编辑层只在
.editor模式安装、切回去就卸载。交互
eye回只读、doc.plaintext回整篇源码。Cmd+S先提交正在编辑的块再落盘;切换模式前也会先提交。markdown.editor.locked,下一个文档沿用(和 VS Code 一样)。验证
离屏 WKWebView(不抢焦点):
README.md:24 块 / 4804 字节;PATCHES.md:71 块 / 13968 字节;CHANGELOG.md前 120 行:42 块 / 14362 字节——非空白字节全部落在块内、无空隙、无重叠、拼接后与原文件逐字节相同(roundTrip: true)。swiftc -parse通过;lint-pbxproj-test-wiring/ config schema / latency guardrails / gitleaks 均通过。已知边界