Repository navigation
Conversation
…dirty VS Code silently refuses to reload a dirty text document when its file changes on disk (no event fires). The markdown editor applies webview input to the document via applyEdit and only writes the file on save, so the document is dirty almost constantly: external writers (formatters, AI agents, other editors) vanish from an open editor view, and the next save clobbers their changes with the stale buffer. The Handler already owned a FileSystemWatcher whose fileChange events were never consumed. This change consumes them: - add src/service/markdown/externalChangeGuard.ts: pure decision core (strict UTF-8 normalization — non-UTF-8 files are left alone — and shouldAskAboutDiskChange: ask iff dirty, disk differs from every current/recent buffer form, and the text was not already declined) - on divergence, prompt 'Load disk version' / 'Keep my edits' (ext.markdown.externalFileChange, localized in all 10 package.nls files). Load re-reads the disk right before applying, clears the pending sync, applies the edit, saves and pushes the content to the webview; Keep (and prompt dismissal) records the declined text — asked once per distinct disk content, so streaming writers do not spam - saves are parked via workspace.onWillSaveTextDocument while a decision is pending, so autosave or a reflexive Ctrl+S cannot silently overwrite the change the prompt is asking about - recent pre-flush document snapshots suppress echo prompts when a save was triggered with focus outside the webview - a failed save after loading warns instead of failing silently (ext.markdown.externalSaveFailed, all 10 locales) - unit tests for the decision core (npm run test:unit, node:test) Known limitations (deliberately out of scope): duplicate prompts when the same file is open in two panels (pre-existing shared-document model); watcher blind spots for non-workspace virtual schemes, file names containing glob metacharacters, and deletes/renames; millisecond read-modify-write races around Load; a save hangs until the user answers a prompt they relegated to the notification center. The unit-test script requires Node >= 22.6 (native TS type stripping). Design reference: ONEGAYI/vscode-markdown-editor-hardened (external-change-watcher).
This was referenced Sep 16, 2026
ONEGAYI
added a commit
to ONEGAYI/vscode-office
that referenced
this pull request
Sep 17, 2026
- 进行中工作索引:上游待合并 PR 增补 cweijan#613(列表 marker 上游移植); fork issues 行改写为已全部修复关闭,逐条标注修复提交 (e166a00 / a117f6b / 8638b2f / 1fbe850)及 v4.3.0-fork.1 交付 - 架构关键事实:外部变更兜底的 watcher 覆盖与双面板限制改为 已在 fork 内修复(1fbe850),上游侧待 cweijan#611 合并后发 PR, 避免后续误读为待修
Author
|
Closing due to inactivity — no review feedback after ~3 weeks. The commits remain available via |
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.
Problem
VS Code never reloads a dirty text document when its file changes on disk — no reload, no event. The markdown editor applies webview input to the document via
applyEditand only writes the file on save, so the document is dirty almost constantly. As a result:This is very visible when an agent edits files while the user has them open in the WYSIWYG markdown editor.
Fix
The
Handleralready owns a FileSystemWatcher whosefileChangeevents were never consumed by anyone — this PR consumes them for the markdown editor:src/service/markdown/externalChangeGuard.ts): strict UTF-8 normalization (non-UTF-8 files are left alone — VS Code may decode documents with other encodings, and adopting a mojibake interpretation would corrupt them) andshouldAskAboutDiskChange: ask iff the document is dirty, the disk text differs from every current/recent buffer form (echo suppression), and the user has not already declined that exact text.ext.markdown.externalFileChange, localized in all 10package.nlsfiles).document.save()+ pushes the content to the webview. Same contract as VS Code's own conflict flow: local unsaved edits are discarded.workspace.onWillSaveTextDocument+event.waitUntilparks saves of the document while a decision is pending, so autosave or a reflexive Ctrl+S cannot silently overwrite the change the prompt is asking about.ext.markdown.externalSaveFailed).npm run test:unit(node:test; 10 cases incl. GBK/UTF-16 rejection, echo orderings, emptied disk). Note: requires Node ≥ 22.6 for native TS type stripping.Known limitations (deliberately out of scope)
report[1].md) silently fail to match; deletes/renames produce no promptValidation
npm run test:unit— 10/10 passnpm run build— passnpx eslinton changed files — cleanDesign reference: ONEGAYI/vscode-markdown-editor-hardened (external-change-watcher), adapted to this extension's handler/sync model with two review rounds of hardening (UTF-8 strictness, prompt serialization, save-guard deadlock avoidance, echo rings).
Note: this PR touches the import block of
markdownEditorProvider.tsand adds the same two config lines (test script / tsconfig exclude) as #610 — expect a trivial merge conflict if that lands first.