ElyMark: a merge taken from disk leaves the tab saved (M-03)

Every path that takes the disk text as saved goes through
adopt_disk, which sets the tab's mark and the view's baseline
together; the merge branch no longer repeats it by hand.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
ZacharyZhang-NYandClaude Opus 5.5 committed 2026-10-10 04:19:53 -04:00
1 parent 42bbc4e8fb
commit d5f94e6e7a
6 files changed
+17 -22

No files matched your search

+3 -13
View File
@@ -112,20 +112,10 @@ impl Desk {
if open > 0 {
return log::error!("mark: a merge with {open} open conflicts");
}
let Some(tab) = self.tab_mut(id) else {
return;
};
if let Err(error) = tab.session.reload_at(fingerprint) {
let why = error.to_string();
return self.set_outside(id, Outside::Unread(why), cx);
// Disk text is saved; the merge edits it.
if let Some(view) = self.adopt_disk(id, &disk, fingerprint, cx) {
view.update(cx, |view, cx| view.adopt(merged, cx));
}
tab.extra.base = disk.text.clone();
tab.mark = crate::engine::mark(&disk.text);
tab.extra.restart_autosave();
tab.doc.lock().expect("the text lock").source = disk;
let view = tab.view.clone();
view.update(cx, |view, cx| view.adopt(merged, cx));
self.set_outside(id, Outside::Clear, cx);
}
}
}
+6 -8
View File
@@ -236,11 +236,7 @@ impl Desk {
match (disk.text == current, dirty) {
// The same text: only the file underneath is new.
(true, _) => {
if let Some(view) = self.adopt_disk(id, &disk, fingerprint, cx) {
// What shows is now saved: the tab is clean.
let saved = crate::engine::mark(&disk.text);
view.update(cx, |view, cx| view.saved(&saved, cx));
}
self.adopt_disk(id, &disk, fingerprint, cx);
}
// The text as last saved: the edits stay unsaved.
(false, true) if kept => self.keep_edits(id, disk, fingerprint, cx),
@@ -294,8 +290,8 @@ impl Desk {
self.save_after_pause(id, cx);
}
/// The tab takes the file as saved; returns its view.
fn adopt_disk(
/// The tab and its view take the file as saved.
pub(crate) fn adopt_disk(
&mut self,
id: u64,
disk: &Source,
@@ -309,7 +305,8 @@ impl Desk {
}
tab.extra.base = disk.text.clone();
// The file holds the disk's text: it is saved.
tab.mark = crate::engine::mark(&disk.text);
let saved = crate::engine::mark(&disk.text);
tab.mark = saved.clone();
tab.extra.restart_autosave();
// Its bytes (BOM, line ends) are what saves keep now.
tab.doc.lock().expect("the text lock").source = disk.clone();
@@ -322,6 +319,7 @@ impl Desk {
log::warn!("mark: the replaced file did not register: {error}");
}
self.set_outside(id, Outside::Clear, cx);
view.update(cx, |view, cx| view.saved(&saved, cx));
Some(view)
}
+1 -1
View File
@@ -63,7 +63,7 @@
- [x] D-08 Linux、Windows 上“打印…”可用,导出 PDF 后才报“此平台未构建” — 未构建平台禁用打印、不绑快捷键、错误不带路径;命令面板先查禁用
- [x] M-01 键入期间外部以相同内容重写文件,丢掉上次停顿之后键入的全部文字 — 先等页面送出未送的键;同文只接过文件与字节、标签为已保存;磁盘回到上次保存的文字时保留编辑并恢复自动保存;R1–R4 字节、自动保存、在途写入、已保存基线;R5 PASS
- [x] M-02 `refresh` 归零版本计数却不换代,在途的一键让标签一直“未落定” — 刷新即换代、归零并结束欠下的渲染(tally.rs);R1 渲染回调悬空、无在途消息的测试;R2 测试未证旧代归零;R3 PASS
- [ ] M-03 干净标签接过磁盘文字后关闭仍问“是否保存”
- [x] M-03 干净标签接过磁盘文字后关闭仍问“是否保存” — 接过磁盘文字的各路(同文、干净重载、合并)都经 adopt_disk,标签与视图的保存基线同设;R1 合并采用未同步视图基线;R2 注释超长;R3 PASS
- [ ] M-04 第二次打印或导出 PDF 悄悄取消第一次,没有文件也没有错误
- [ ] M-05 点页面里的链接什么也不发生
- [ ] M-06 `on_app_quit` 无条件删恢复点与崩溃锁,AppKit 直接终止时丢未保存内容
+3
View File
@@ -0,0 +1,3 @@
FAIL
apps/ely-mark/src/compare.rs:123 — 合并采用只把 `tab.mark` 改成磁盘文字的散列,没有同步 `MarkView.saved`;`view.adopt` 也不更新这个基线,`MarkView::modified` 仍与最初载入的文字比较。具体场景:打开 `base\n`,本地改成 `ours\n`,外部改成 `theirs\n`;比较时冲突选磁盘侧,再按“使用合并结果”。文字回报落定后,内存与磁盘都是 `theirs\n`,历史也等于新的 `tab.mark`,视图却仍报告 modified,`request_close` 在自动保存前仍弹保存询问,M-03 未完整修复(PRD FILE-02、§14.4)。Windows 与 WSL 的提取状态探针使用实际 `mark`、`modified` 和本行赋值,均得到“text equals disk: true; history equals tab mark: true; view modified: true”,同步视图基线后断言通过;这是状态探针,未运行 macOS 窗口测试。证据保留在 `C:/Users/zhang/Documents/M03-windows-probe.log` 与 WSL `~/M03-linux-probe.log`,探针目录已删除。相关 Cargo 测试在 WSL 通过;Windows 除已归属 W-02 的尾随空格路径用例外通过。修复方向:合并采用时同时把视图的保存基线设为磁盘文字,再把合并结果作为可撤销编辑采用;补测合并恰等于磁盘时无需保存、合并不同于磁盘时仍需保存及关闭询问。
+3
View File
@@ -0,0 +1,3 @@
FAIL
apps/ely-mark/src/compare.rs:115 — 本轮新增注释 `The disk is the saved text; the merge an edit on it.` 共 12 个词,违反 agents.md 第 5 条的十词上限。具体复现:运行 `tests/scripts/comments.py`,Windows 与 WSL 均在此行报 `comments break the one-line ten-word rule`;Windows 仅扫描本轮两个改动文件也失败。修复方向:将此注释缩至十词以内,或删除。
+1
View File
@@ -0,0 +1 @@
PASS