From bb1f0b2f1fdf2e46a6dfd41ea078d1d3dc87180a Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 9 Oct 2026 06:36:29 +0000 Subject: [PATCH] Bug list: ElyTable import, filter and dialog findings; sections ordered Co-Authored-By: Claude Fable 5.1 Claude-Session: https://claude.ai/code/session_01TycnrQxWJyHRVUSpkoCs7e --- docs/BugList.md | 334 ++++++++++++++++++++++++++++-------------------- 1 file changed, 192 insertions(+), 142 deletions(-) diff --git a/docs/BugList.md b/docs/BugList.md index 82b8686..0a58a98 100644 --- a/docs/BugList.md +++ b/docs/BugList.md @@ -4,11 +4,12 @@ 编号前缀:T ElyTable,S ElyShow,P ElyPDF,D ElyDoc,M ElyMark,G ElyTree,K LOK 桥(`crates/ely-lok`),X 共用外壳(`ely-office`、`ely-files`、`ely-ui`、`ely-platform`、`ely-ipc`)。严重度:致命=崩溃、丢数据或功能不可用;高=常见路径结果错或功能坏;中=边缘路径坏或界面误导;低=小问题。 + ## 统计 | 节 | 致命 | 高 | 中 | 低 | 合计 | | --- | --- | --- | --- | --- | --- | -| T ElyTable 与 LOK 画布 | 1 | 1 | 3 | 2 | 7 | +| T ElyTable 与 LOK 画布 | 1 | 1 | 7 | 6 | 15 | | S ElyShow | 2 | 0 | 2 | 6 | 10 | | P ElyPDF | 1 | 3 | 4 | 6 | 14 | | D ElyDoc | 0 | 2 | 2 | 4 | 8 | @@ -16,7 +17,7 @@ | G ElyTree | 0 | 0 | 3 | 11 | 14 | | K LOK 桥 | 0 | 1 | 1 | 2 | 4 | | X 共用外壳与平台 | 1 | 2 | 4 | 7 | 14 | -| 合计 | 5 | 10 | 24 | 46 | 85 | +| 合计 | 5 | 10 | 28 | 50 | 93 | 致命:T-01 内核的图块与命中按像素网格,Ely 的光标、选区、表头按文档 twips,越远越错位;S-01 切换幻灯片后主画布不重画;S-03 ElyShow 的缩放一两帧后弹回“适合幻灯片”,缩放功能不可用;P-01 文件系统的 `PermissionDenied` 被拼成不存在的文案键,应用崩溃;X-01 设置窗口在前时 Cmd+Q 直接退出,跳过未保存询问并抹掉恢复点。 @@ -87,6 +88,55 @@ - 原因:列号、行号不会被光标移动改变,EXPECT 的保护在这里是多余的;而所有鼠标按下与松开(含拖选的每一步移动)都计入修订。 - 修法:`select.column`、`select.row`、`columns.width`、`rows.height` 不作编号命令(或 `run_in` 对它们不带 `at`),只保留对工作表、对象、参考线等真会被改动重排的编号做 EXPECT。 +### T-08 自动筛选的列菜单对光标所在的表而不是按钮所在的表筛选、排序 +- 严重度:中 | 置信度:可能(内核侧按补丁追到;取决于单元格光标在哪) +- 位置:`apps/ely-table/src/data.rs:412-437`(`column_asked` 发 `data.filter`/`data.sort`)、`:379-409`(`ask_column`);内核 `patches/libreoffice/0017-lok-calc-filter-validation-columns.patch` 的 `lcl_Query`(`rView.GetDBData()`)与 `SID_SORT` 路径(`GetDBData()`) +- 现象:单元格光标在筛选区之外(刚在别处键入)时点列头的筛选箭头、勾选值或“升序”:要么弹内核错误(`Check::Undoable` 失败),要么筛选、排序了光标所在的另一块数据。菜单本身能开,因为 `.uno:AutoFilterValues?col=&row=` 用的是按钮格。 +- 原因:内核自己的菜单对按钮格 `GetDBAtCursor(nCol, nRow)` 操作,补丁后的 `LaunchAutoFilterMenu` 不移动光标;Ely 的答复却经 `GetDBData()`(当前光标或选区)解析。 +- 修法:`column_asked` 先 `cell.goto` 到 `address(column, row)`(`Dialog::Column` 记下 `row`),或让补丁按按钮格取数据区。 + +### T-09 导入文本文件时整文件的 UTF-8 校验在界面线程跑 +- 严重度:中 | 置信度:已确认 +- 位置:`apps/ely-table/src/text.rs:241-245`(`in_window` 里 `Pending::new`)、`:58-63`、`:108-116`(`guess_encoding` 对全文 `from_utf8`) +- 现象:打开几百 MB 的 CSV,导入对话框出现前整窗冻结几百毫秒到数秒(树莓派更久)。 +- 原因:读字节在后台,`Pending::new`(编码与分隔符猜测)却在主线程闭包里。 +- 修法:猜测放进后台任务,`in_window` 只接现成的 `Pending`。 + +### T-10 CSV 导入对话框开着时打开任何别的对话框,待导入的文件静默消失 +- 严重度:中 | 置信度:已确认 +- 位置:`apps/ely-table/src/text.rs:254-262`(`next_import` 把 `Pending` 移进 `Dialog::Import`);无条件 `self.dialog = Some(..)` 的:`apps/ely-table/src/output.rs:218`、`rules.rs:146`、`:278`、`:341`、`analysis.rs:123`、`:149`、`page.rs:146`、`protect.rs:61`、`formulas.rs:119`、`:209`、`data.rs:231`、`:317`、`:397` +- 现象:访达双击 .csv 出现导入对话框,按 Cmd+E 再取消:`Pending`(已检查字节的唯一副本)被丢,文件再也不打开,无提示。 +- 修法:替换 `Dialog::Import` 时把它放回 `imports` 队头,或有对话框开着时拒绝再开。 + +### T-11 对话框比其标签活得久:导出、定义名称、重命名不可见却“开着”,挡住导入;名称表的“转到”激活已关闭的标签 +- 严重度:低 | 置信度:可能 +- 位置:`apps/ely-table/src/dialog.rs:644-648`(导出 `sheet_in(*tab)?`)、`:563-571`、`:542-545`;`apps/ely-table/src/text.rs:255-257`(`next_import` 要 `dialog.is_none()`);`apps/ely-table/src/formulas.rs:255-258`(`core.active = tab` 不核对) +- 现象:Cmd+E 后 Cmd+W 关掉该标签:对话框不画了但 `self.dialog` 仍为 `Some`,无法关闭,之后打开 .csv 没反应,直到再开关一次别的对话框;名称表的“转到”把 `core.active` 指到已关标签,正文显示“没有打开的文档”。ElyDoc 的 D-01 是同一类问题(那里直接崩溃)。 +- 修法:`Book` 实现 `Host::tab_closed` 清掉指向该标签的 `dialog` 与 `choices`;“转到”先核对 `tab(tab).is_some()`。 + +### T-12 打印区域是整列或整行时页面设置无法应用 +- 严重度:中 | 置信度:可能(内核以 `$A:$D` 格式化整列区域) +- 位置:`apps/ely-table/src/page.rs:75-83`(`cell_ok` 要求字母加数字)、`:86-97`(`areas`)、`:169-176`(`page_asked` 以 `table.page.bad_reference` 拒绝) +- 现象:Excel 文件的打印区域 `=Sheet1!$A:$D` 预填进对话框,只改方向或缩放再按应用也被拒“Write ranges like A1:D20…”;不重写区域就用不了页面设置。 +- 修法:`areas()` 接受 `COL:COL` 与 `ROW:ROW`(内核 `ParseAny` 本就接受),或内核给的原值免校验。 + +### T-13 打印失败报成“导出失败”(非 macOS 必现) +- 严重度:低 | 置信度:已确认 +- 位置:`apps/ely-table/src/output.rs:147-150`(`print` 把 `print_later` 的失败交给 `output_failed`,文案 `table.export.failed`)、`crates/ely-platform/src/print.rs:87-89` +- 修法:单独的 `table.print.failed` 文案;平台未实现时禁用或说明。 + +### T-14 导入扫描把整个文件的每个字段都建成字符串 +- 严重度:低 | 置信度:已确认(影响随文件大小) +- 位置:`apps/ely-table/src/text.rs:78-106`(`scan`)、`:158-173`(`split` 返回全部行的 `Vec>`) +- 现象:只需要 8 行预览与每列的类型标志,却为 200 MB 的 CSV 分配约 1–2 GB 堆,树莓派上可能耗尽内存。 +- 修法:`split` 改为迭代器,只留前 `SHOWN` 行与列标志。 + +### T-15 非 UTF-8 文本的默认编码跟系统区域而不是界面语言 +- 严重度:低 | 置信度:已确认 +- 位置:`apps/ely-table/src/text.rs:236`(`i18n::resolve(&locale::system())`) +- 现象:英文系统上把应用语言设成简体中文,打开 GB18030 的 CSV 默认仍是 Windows-1252(反之亦然),与 agents.md 的“中文界面 GB18030、英文界面 Windows-1252”不符。 +- 修法:用 `ely_ui::i18n` 解析后的当前语言。 + ## S ElyShow(Impress) ### S-01 切换幻灯片后主画布不重画 @@ -151,146 +201,6 @@ - 位置:`apps/ely-show/src/slideshow/start.rs:194-198`(标签或屏幕已不在 → 只记日志并 `discard`;选屏对话框开着时关掉标签再按开始可达)、`:123-125`(正在启动 → 只记日志) - 修法:两处都弹提示。 -## D ElyDoc(Writer) - -### D-01 导出或打印对话框开着时关闭其标签即崩溃 -- 严重度:高 | 置信度:已确认 -- 位置:`apps/ely-doc/src/actions.rs:84-86`(`self.tab(*tab).expect("a modal keeps its tab")`),对话框由 `apps/ely-doc/src/output.rs:38-48` 打开;关闭路径 `crates/ely-office/src/close.rs:38-42`、`:142-154`、`:191-221` -- 现象:开着“导出…”或“打印…”对话框按 Cmd+W、点窗口关闭钮或 Cmd+Q,标签被移除后下一帧渲染 `expect` 失败,进程崩溃;Cmd+Q 时先于其余脏标签的保存询问崩溃,这些标签只剩 10 秒一次的恢复点。 -- 原因:`Dialog::Output` 记着标签号,`dialog_element` 每帧无条件解包;没有任何地方在标签关闭时清 `self.dialog`(`Docs` 未实现 `Host::tab_closed`),`release_tab` 还把 `output()` 排队的 `when_settled` 续动作丢掉。其他对话框(`Ask`、`Link`、`Reference`、外壳的 `Unsaved`)都是防御性写法。 -- 复现:打开任一文档 → 文件›导出… → Cmd+W。 -- 修法:`dialog_element` 在 `tab()` 为 `None` 时清掉对话框并返回 `None`;`Docs` 实现 `tab_closed` 丢掉指向该标签的 `Dialog::Output`。 - -### D-02 邮件合并以当前标签为模板,预览后生成的每份都是同一条记录 -- 严重度:高 | 置信度:已确认 -- 位置:`apps/ely-doc/src/merge.rs:88-94`(`source()` 返回 `core.active`)、`:152-164`(预览)、`:178-195`(生成);`apps/ely-doc/src/merge/run.rs:351-371`(预览经 `load_into` 开新标签)、`crates/ely-office/src/open.rs:231`(新标签成为当前) -- 现象:选 CSV、插字段、点“预览”(填好的副本开成新标签并成为当前标签,合并面板仍在右侧)再点“生成”:模板成了预览副本,字段早已替换成第 N 条记录,N 个输出文件内容相同,文件名还带预览标签名;再点预览是预览的预览。无任何提示。 -- 原因:`Merge` 不记来源标签,每次点击时取 `core.active`;单测 `a_merge_keeps_its_source_when_the_tab_changes` 直接传 `source`,没覆盖界面路径。 -- 复现:任一含 `«Name»` 的文档 → 邮件合并 → 三行 CSV → 预览 → 生成。 -- 修法:选 CSV 或插字段时记下来源标签号(或在 `Extra` 标记预览标签),面板显示来源名,预览与生成都用它,当前标签是预览副本时拒绝。 - -### D-03 界面线程同步持 worker 锁读内核(样式、字体、书签、公式、分节名) -- 严重度:中 | 置信度:已确认 -- 位置:`apps/ely-doc/src/insert.rs:318-324`(`insert_section`)、`apps/ely-doc/src/refs.rs:81-86`(`read`,书签、交叉引用、公式对话框用)、`apps/ely-doc/src/props.rs:116-122`(`read_fonts`)、`:133-137`(`read_styles`,每次切标签与 `Reported` 都跑) -- 现象:保存大文档、邮件合并几百条记录(每条载入、替换、另存、关闭都持锁)期间,切标签或打开“插入›书签…”整窗冻结到锁空出来为止。 -- 原因:违反 2026-10-05 决策“界面线程不碰 worker”,这四处直接 `worker.lock()` 而不走 `read_in`/`read_off`。 -- 修法:改为后台读取,回来时核对仍是同一标签与视图。 - -### D-04 一条批注的时间读不出,全部批注与修订都不显示 -- 严重度:中 | 置信度:可能(内核对无日期批注写 `0-00-00`,`utl::toISO8601` 的空日期即如此) -- 位置:`apps/ely-doc/src/review.rs:164-167`、`:373-393`(`threads` 遇第一个解析失败即整体 `Err`)、`:179-181` -- 现象:打开含无日期批注的 DOCX(`w:comment` 无 `w:date`),批注与修订两栏都空,并弹引擎错误提示;每次审阅事件重读再失败再弹。 -- 原因:单条解析失败被提升为整表失败,`and_then` 连已解析的 `changes` 一起丢掉。 -- 修法:逐条解析时间,失败的那条用占位时间;`changes` 不因批注失败而丢。 - -### D-05 邮件合并某条记录失败时内核文档泄漏 -- 严重度:低 | 置信度:已确认 -- 位置:`apps/ely-doc/src/merge/run.rs:464-470` -- 原因:`fill`/`save_as` 以 `?` 提前返回,`close_doc` 不执行,`Doc` 无 `Drop`;每次重试多漏一份,worker 的 `N documents open` 计数漂移。 -- 修法:先取结果再一律 `close_doc`,最后传出首个错误。 - -### D-06 导航栏大纲点击按当前列表取下标,后台重读后可能越界 -- 严重度:低 | 置信度:可能 -- 位置:`apps/ely-doc/src/navigate.rs:277-283`(`navigator.outline[at]`) -- 修法:用 `get(at)`,或在渲染时把目标矩形放进行的闭包。 - -### D-07 导航栏隐藏时仍随每次光标移动重读大纲与书签 -- 严重度:低 | 置信度:已确认 -- 位置:`apps/ely-doc/src/chrome.rs:236-245`(`left_view` 不看 `navigating` 就 `navigator.show(tab)`)、`apps/ely-doc/src/navigate.rs:79`、`:91-123` -- 现象:关掉导航栏后每次按键仍排两次内核读取,与键入争 worker 锁(规则 9:空闲不做事)。 -- 修法:隐藏时 `show(None)`,显示时重读一次。 - -### D-08 Linux、Windows 上“打印…”可用,导出 PDF 后才报“此平台未构建” -- 严重度:低 | 置信度:已确认 -- 位置:`apps/ely-doc/src/output.rs:28-30`、`:80-88`;`crates/ely-platform/src/print.rs:87-89` -- 现象:菜单与页码范围对话框都正常,最后一步弹出带临时路径的错误提示。各文档应用同(见 X-13)。 -- 修法:平台未实现时禁用菜单项或在对话框里写明;错误文字去掉路径。 - -## G ElyTree(Git) - -### G-01 打开“文件历史”或“逐行追溯”后,中间区不再响应任何别的选择 -- 严重度:中 | 置信度:已确认 -- 位置:`apps/ely-tree/src/view.rs:185-187`(`body` 先于 `match self.side` 返回 `look_pane`);入口 `apps/ely-tree/src/hist_pane.rs:43-66`、`apps/ely-tree/src/pane.rs:483` -- 现象:按下差异标题栏的“文件历史”或“逐行追溯”后,点改动列表里另一个文件、历史里另一个提交、分支或储藏,中间区都不变;只有历史面板的小叉能退出。 -- 原因:`show()`(`pick.rs:302`)、`pick_commit`、`pick_place`、`set_side` 都不清 `self.look`,只有 `close_look` 与 blame 的 `show_commit` 清。 -- 修法:任何新选择都清 `self.look`,或只在 `side == Changes` 且所选文件不变时画它。 - -### G-02 进行中操作读取失败被吞掉;`git am` 冲突无提示条无错误 -- 严重度:中 | 置信度:已确认(`git am` 细节为可能) -- 位置:`apps/ely-tree/src/ops.rs:81-98`(`doing`)、`apps/ely-tree/src/moves.rs:74`、`apps/ely-tree/src/conflict_pane.rs:62`、`:106-109` -- 现象:`doing()` 出错时 `opened.doing = Some(Err(..))`,没有任何显示或日志;冲突文件列出来了,却没有“继续/跳过/中止”提示,冲突栏两侧退回泛称。 -- 原因:`rebase-apply` 一律当变基读 `onto`,`git am` 的 `rebase-apply/` 没有 `onto`,整个读取 `NotFound`;`describe()` 失败(如 `MERGE_HEAD` 指向已被清理的对象)同样整体失败。违反规则 2。 -- 复现:终端里 `git am` 停在冲突,在 ElyTree 打开该仓库。 -- 修法:`Some(Err)` 以提示条显示 Git 原话并记日志;无 `onto` 的 `rebase-apply` 视为 `git am` 进行中。 - -### G-03 新建的空仓库在“仓库”页显示两段 Git 致命错误(引用日志、LFS) -- 严重度:中 | 置信度:可能 -- 位置:`apps/ely-tree/src/recover.rs:50-69`(`reflog … HEAD --`)、`apps/ely-tree/src/structure.rs:137-138`(`git lfs ls-files`)、`apps/ely-tree/src/places.rs:40-50`、`apps/ely-tree/src/side_places.rs:261-264`、`:279-281` -- 现象:“新建仓库…”后仓库页出现 “fatal: bad revision 'HEAD'” 与 “Git can't resolve ref: HEAD” 两块红字;仓库没有问题,空列表才是正确状态。 -- 原因:HEAD 未诞生时显式传 `HEAD` 的 `reflog show` 以 128 退出,`run_or_one` 不接受;`git lfs ls-files` 同样先解析 HEAD。 -- 修法:`status.head.oid` 为空时两项直接给空列表。 - -### G-04 停止取回/拉取/推送失败的提示写成“克隆没有停下” -- 严重度:低 | 置信度:已确认 -- 位置:`apps/ely-tree/src/network.rs:126`(`stop_remote` 复用 `tree.error.stop`)、`crates/ely-ui/src/i18n/tree.rs:53` -- 修法:加一条不限动词的文案。 - -### G-05 合并结果保存失败报成“Git 失败”,`tree.error.save` 是死文案 -- 严重度:低 | 置信度:已确认 -- 位置:`apps/ely-tree/src/work.rs:424`(`(_, Err(error)) => failed("tree.error.write", …)`)、`crates/ely-ui/src/i18n/tree_ops.rs:127`、`:255`(定义却无人用,规则 6) -- 修法:`written()` 加 `(Write::Save, Err)` 分支用 `tree.error.save`。 - -### G-06 首次提交后紧接着取消暂存,按过期的“已有提交”判定跑成 `git rm --cached` -- 严重度:低 | 置信度:可能(竞争窗口为一次状态重读) -- 位置:`apps/ely-tree/src/work.rs:352`(`born` 取自缓存的 `opened.status`)、`:426-427`(`read` 异步、`next_write` 同步)、`:85-93`、`:103-112` -- 现象:新仓库里暂存、提交,列表刷新前按“全部取消暂存”:第二条写操作仍按 `oid: None` 跑 `rm --cached -f -r -q -- .`,把刚提交的全部文件标为删除(可恢复,但吓人)。 -- 修法:写操作执行前在后台 `rev-parse --verify -q HEAD` 判定,不用缓存状态。 - -### G-07 任一引用没有创建日期,整个分支页读不出 -- 严重度:低 | 置信度:可能 -- 位置:`apps/ely-tree/src/branches.rs:33`(`%(creatordate:unix)`)、`:106`(空串解析失败整体 `Err`)、`apps/ely-tree/src/side_refs.rs:227-235` -- 复现:`git tag blobtag HEAD:README.md`,打开分支页。 -- 修法:日期可缺(显示“—”),或跳过非提交对象的引用。 - -### G-08 清理预览后文件被外部删除,对话框只给裸 OS 错误 -- 严重度:低 | 置信度:已确认 -- 位置:`apps/ely-tree/src/work.rs:270`(`symlink_metadata(&at)?`)、`:415-422` -- 现象:标题“Git did not do it”,正文 “No such file or directory (os error 2)”,没有路径,Git 并未运行。 -- 修法:映射成带路径的“自预览后已变”文案。 - -### G-09 后台读取回来的对话框覆盖用户同时打开的对话框 -- 严重度:低 | 置信度:已确认 -- 位置:`apps/ely-tree/src/network.rs:186`(推送选远程)、`:237`(强制推送)、`apps/ely-tree/src/recovering.rs:116`(移动分支) -- 现象:按“推送”(无上游)后立刻按“储藏改动…”并开始键入,`git remote` 回来时储藏对话框连同输入被换掉。 -- 修法:只在 `tree.ask` 仍为空(或仍是本次请求)时赋值。 - -### G-10 选中的分支、标签、位置是窗口级的,跨仓库标签串台 -- 严重度:低 | 置信度:已确认 -- 位置:`apps/ely-tree/src/tree.rs:107-108`(`picked_ref`、`picked_place` 在 `Tree` 上)、`apps/ely-tree/src/refs_pane.rs:25-33`、`apps/ely-tree/src/side_refs.rs:238-245` -- 现象:仓库 A 选中 `main`,切到仓库 B,B 的分支页显示它自己的 `main` 为已选并带动作按钮。 -- 修法:移入 `Opened`,或 `activate()` 时清掉。 - -### G-11 已选边的冲突块再选另一边,提示“结果已手改” -- 严重度:低 | 置信度:已确认 -- 位置:`apps/ely-tree/src/conflict.rs:219-224` -- 修法:给“该块已选定”单独文案,或支持改选。 - -### G-12 符号链接父目录下,当前打开的工作树被当成别的工作树而可“移除” -- 严重度:低 | 置信度:可能 -- 位置:`apps/ely-tree/src/places_pane.rs:253-255`、`:265-271`、`apps/ely-tree/src/structure.rs:245-247` -- 原因:`here` 用 `git worktree list` 记录的原始路径比对已规范化的 `opened.repo.root`(macOS `/tmp` → `/private/tmp`)。 -- 修法:比对前 `canonicalize`。 - -### G-13 非 macOS 平台的死入口 -- 严重度:低 | 置信度:已确认 -- 位置:`apps/ely-tree/src/running.rs:167-173`(停止远程命令非 Unix 报未构建)、`apps/ely-tree/src/tools.rs:109-115`(“在终端中打开”非 macOS 报未构建)、`crates/ely-ui/src/i18n/tree_places.rs:147`、`:281`(“在访达中显示”文案在 Linux、Windows 照样显示) -- 修法:按 `cfg` 禁用或隐藏,`reveal` 换平台中性文案。 - -### G-14 `repo.rs` 的孤立文档注释 -- 严重度:低 | 置信度:已确认 -- 位置:`apps/ely-tree/src/repo.rs:10`(“How many repositories the recent list keeps.” 的常量早已移到 `ely_files::recent`,注释挂到了 `struct Repo` 上) -- 修法:删掉。 - ## P ElyPDF(MuPDF) ### P-01 文件系统的 `PermissionDenied` 被拼成不存在的文案键,应用崩溃 @@ -378,6 +288,61 @@ - 现象:ToUnicode 坏掉的文件文字里有 U+0001–U+001F,`text_blocks` 解析失败,编辑工具永远读不到该页,并落入 P-08 的循环。 - 修法:`text`、`font` 用 `ely_json_string` 写。 +## D ElyDoc(Writer) + +### D-01 导出或打印对话框开着时关闭其标签即崩溃 +- 严重度:高 | 置信度:已确认 +- 位置:`apps/ely-doc/src/actions.rs:84-86`(`self.tab(*tab).expect("a modal keeps its tab")`),对话框由 `apps/ely-doc/src/output.rs:38-48` 打开;关闭路径 `crates/ely-office/src/close.rs:38-42`、`:142-154`、`:191-221` +- 现象:开着“导出…”或“打印…”对话框按 Cmd+W、点窗口关闭钮或 Cmd+Q,标签被移除后下一帧渲染 `expect` 失败,进程崩溃;Cmd+Q 时先于其余脏标签的保存询问崩溃,这些标签只剩 10 秒一次的恢复点。 +- 原因:`Dialog::Output` 记着标签号,`dialog_element` 每帧无条件解包;没有任何地方在标签关闭时清 `self.dialog`(`Docs` 未实现 `Host::tab_closed`),`release_tab` 还把 `output()` 排队的 `when_settled` 续动作丢掉。其他对话框(`Ask`、`Link`、`Reference`、外壳的 `Unsaved`)都是防御性写法。 +- 复现:打开任一文档 → 文件›导出… → Cmd+W。 +- 修法:`dialog_element` 在 `tab()` 为 `None` 时清掉对话框并返回 `None`;`Docs` 实现 `tab_closed` 丢掉指向该标签的 `Dialog::Output`。 + +### D-02 邮件合并以当前标签为模板,预览后生成的每份都是同一条记录 +- 严重度:高 | 置信度:已确认 +- 位置:`apps/ely-doc/src/merge.rs:88-94`(`source()` 返回 `core.active`)、`:152-164`(预览)、`:178-195`(生成);`apps/ely-doc/src/merge/run.rs:351-371`(预览经 `load_into` 开新标签)、`crates/ely-office/src/open.rs:231`(新标签成为当前) +- 现象:选 CSV、插字段、点“预览”(填好的副本开成新标签并成为当前标签,合并面板仍在右侧)再点“生成”:模板成了预览副本,字段早已替换成第 N 条记录,N 个输出文件内容相同,文件名还带预览标签名;再点预览是预览的预览。无任何提示。 +- 原因:`Merge` 不记来源标签,每次点击时取 `core.active`;单测 `a_merge_keeps_its_source_when_the_tab_changes` 直接传 `source`,没覆盖界面路径。 +- 复现:任一含 `«Name»` 的文档 → 邮件合并 → 三行 CSV → 预览 → 生成。 +- 修法:选 CSV 或插字段时记下来源标签号(或在 `Extra` 标记预览标签),面板显示来源名,预览与生成都用它,当前标签是预览副本时拒绝。 + +### D-03 界面线程同步持 worker 锁读内核(样式、字体、书签、公式、分节名) +- 严重度:中 | 置信度:已确认 +- 位置:`apps/ely-doc/src/insert.rs:318-324`(`insert_section`)、`apps/ely-doc/src/refs.rs:81-86`(`read`,书签、交叉引用、公式对话框用)、`apps/ely-doc/src/props.rs:116-122`(`read_fonts`)、`:133-137`(`read_styles`,每次切标签与 `Reported` 都跑) +- 现象:保存大文档、邮件合并几百条记录(每条载入、替换、另存、关闭都持锁)期间,切标签或打开“插入›书签…”整窗冻结到锁空出来为止。 +- 原因:违反 2026-10-05 决策“界面线程不碰 worker”,这四处直接 `worker.lock()` 而不走 `read_in`/`read_off`。 +- 修法:改为后台读取,回来时核对仍是同一标签与视图。 + +### D-04 一条批注的时间读不出,全部批注与修订都不显示 +- 严重度:中 | 置信度:可能(内核对无日期批注写 `0-00-00`,`utl::toISO8601` 的空日期即如此) +- 位置:`apps/ely-doc/src/review.rs:164-167`、`:373-393`(`threads` 遇第一个解析失败即整体 `Err`)、`:179-181` +- 现象:打开含无日期批注的 DOCX(`w:comment` 无 `w:date`),批注与修订两栏都空,并弹引擎错误提示;每次审阅事件重读再失败再弹。 +- 原因:单条解析失败被提升为整表失败,`and_then` 连已解析的 `changes` 一起丢掉。 +- 修法:逐条解析时间,失败的那条用占位时间;`changes` 不因批注失败而丢。 + +### D-05 邮件合并某条记录失败时内核文档泄漏 +- 严重度:低 | 置信度:已确认 +- 位置:`apps/ely-doc/src/merge/run.rs:464-470` +- 原因:`fill`/`save_as` 以 `?` 提前返回,`close_doc` 不执行,`Doc` 无 `Drop`;每次重试多漏一份,worker 的 `N documents open` 计数漂移。 +- 修法:先取结果再一律 `close_doc`,最后传出首个错误。 + +### D-06 导航栏大纲点击按当前列表取下标,后台重读后可能越界 +- 严重度:低 | 置信度:可能 +- 位置:`apps/ely-doc/src/navigate.rs:277-283`(`navigator.outline[at]`) +- 修法:用 `get(at)`,或在渲染时把目标矩形放进行的闭包。 + +### D-07 导航栏隐藏时仍随每次光标移动重读大纲与书签 +- 严重度:低 | 置信度:已确认 +- 位置:`apps/ely-doc/src/chrome.rs:236-245`(`left_view` 不看 `navigating` 就 `navigator.show(tab)`)、`apps/ely-doc/src/navigate.rs:79`、`:91-123` +- 现象:关掉导航栏后每次按键仍排两次内核读取,与键入争 worker 锁(规则 9:空闲不做事)。 +- 修法:隐藏时 `show(None)`,显示时重读一次。 + +### D-08 Linux、Windows 上“打印…”可用,导出 PDF 后才报“此平台未构建” +- 严重度:低 | 置信度:已确认 +- 位置:`apps/ely-doc/src/output.rs:28-30`、`:80-88`;`crates/ely-platform/src/print.rs:87-89` +- 现象:菜单与页码范围对话框都正常,最后一步弹出带临时路径的错误提示。各文档应用同(见 X-13)。 +- 修法:平台未实现时禁用菜单项或在对话框里写明;错误文字去掉路径。 + ## M ElyMark(CEF) ### M-01 键入期间外部以相同内容重写文件,丢掉上次停顿之后键入的全部文字 @@ -463,6 +428,91 @@ - 位置:`apps/ely-mark/src/export.rs:276-282`(渲染回调里 `inline`、`read_to_string`、`fs::write`);对照 `:172-176` 的 `write_output` 已在后台 - 修法:暂存步骤移到 `background_spawn`。 +## G ElyTree(Git) + +### G-01 打开“文件历史”或“逐行追溯”后,中间区不再响应任何别的选择 +- 严重度:中 | 置信度:已确认 +- 位置:`apps/ely-tree/src/view.rs:185-187`(`body` 先于 `match self.side` 返回 `look_pane`);入口 `apps/ely-tree/src/hist_pane.rs:43-66`、`apps/ely-tree/src/pane.rs:483` +- 现象:按下差异标题栏的“文件历史”或“逐行追溯”后,点改动列表里另一个文件、历史里另一个提交、分支或储藏,中间区都不变;只有历史面板的小叉能退出。 +- 原因:`show()`(`pick.rs:302`)、`pick_commit`、`pick_place`、`set_side` 都不清 `self.look`,只有 `close_look` 与 blame 的 `show_commit` 清。 +- 修法:任何新选择都清 `self.look`,或只在 `side == Changes` 且所选文件不变时画它。 + +### G-02 进行中操作读取失败被吞掉;`git am` 冲突无提示条无错误 +- 严重度:中 | 置信度:已确认(`git am` 细节为可能) +- 位置:`apps/ely-tree/src/ops.rs:81-98`(`doing`)、`apps/ely-tree/src/moves.rs:74`、`apps/ely-tree/src/conflict_pane.rs:62`、`:106-109` +- 现象:`doing()` 出错时 `opened.doing = Some(Err(..))`,没有任何显示或日志;冲突文件列出来了,却没有“继续/跳过/中止”提示,冲突栏两侧退回泛称。 +- 原因:`rebase-apply` 一律当变基读 `onto`,`git am` 的 `rebase-apply/` 没有 `onto`,整个读取 `NotFound`;`describe()` 失败(如 `MERGE_HEAD` 指向已被清理的对象)同样整体失败。违反规则 2。 +- 复现:终端里 `git am` 停在冲突,在 ElyTree 打开该仓库。 +- 修法:`Some(Err)` 以提示条显示 Git 原话并记日志;无 `onto` 的 `rebase-apply` 视为 `git am` 进行中。 + +### G-03 新建的空仓库在“仓库”页显示两段 Git 致命错误(引用日志、LFS) +- 严重度:中 | 置信度:可能 +- 位置:`apps/ely-tree/src/recover.rs:50-69`(`reflog … HEAD --`)、`apps/ely-tree/src/structure.rs:137-138`(`git lfs ls-files`)、`apps/ely-tree/src/places.rs:40-50`、`apps/ely-tree/src/side_places.rs:261-264`、`:279-281` +- 现象:“新建仓库…”后仓库页出现 “fatal: bad revision 'HEAD'” 与 “Git can't resolve ref: HEAD” 两块红字;仓库没有问题,空列表才是正确状态。 +- 原因:HEAD 未诞生时显式传 `HEAD` 的 `reflog show` 以 128 退出,`run_or_one` 不接受;`git lfs ls-files` 同样先解析 HEAD。 +- 修法:`status.head.oid` 为空时两项直接给空列表。 + +### G-04 停止取回/拉取/推送失败的提示写成“克隆没有停下” +- 严重度:低 | 置信度:已确认 +- 位置:`apps/ely-tree/src/network.rs:126`(`stop_remote` 复用 `tree.error.stop`)、`crates/ely-ui/src/i18n/tree.rs:53` +- 修法:加一条不限动词的文案。 + +### G-05 合并结果保存失败报成“Git 失败”,`tree.error.save` 是死文案 +- 严重度:低 | 置信度:已确认 +- 位置:`apps/ely-tree/src/work.rs:424`(`(_, Err(error)) => failed("tree.error.write", …)`)、`crates/ely-ui/src/i18n/tree_ops.rs:127`、`:255`(定义却无人用,规则 6) +- 修法:`written()` 加 `(Write::Save, Err)` 分支用 `tree.error.save`。 + +### G-06 首次提交后紧接着取消暂存,按过期的“已有提交”判定跑成 `git rm --cached` +- 严重度:低 | 置信度:可能(竞争窗口为一次状态重读) +- 位置:`apps/ely-tree/src/work.rs:352`(`born` 取自缓存的 `opened.status`)、`:426-427`(`read` 异步、`next_write` 同步)、`:85-93`、`:103-112` +- 现象:新仓库里暂存、提交,列表刷新前按“全部取消暂存”:第二条写操作仍按 `oid: None` 跑 `rm --cached -f -r -q -- .`,把刚提交的全部文件标为删除(可恢复,但吓人)。 +- 修法:写操作执行前在后台 `rev-parse --verify -q HEAD` 判定,不用缓存状态。 + +### G-07 任一引用没有创建日期,整个分支页读不出 +- 严重度:低 | 置信度:可能 +- 位置:`apps/ely-tree/src/branches.rs:33`(`%(creatordate:unix)`)、`:106`(空串解析失败整体 `Err`)、`apps/ely-tree/src/side_refs.rs:227-235` +- 复现:`git tag blobtag HEAD:README.md`,打开分支页。 +- 修法:日期可缺(显示“—”),或跳过非提交对象的引用。 + +### G-08 清理预览后文件被外部删除,对话框只给裸 OS 错误 +- 严重度:低 | 置信度:已确认 +- 位置:`apps/ely-tree/src/work.rs:270`(`symlink_metadata(&at)?`)、`:415-422` +- 现象:标题“Git did not do it”,正文 “No such file or directory (os error 2)”,没有路径,Git 并未运行。 +- 修法:映射成带路径的“自预览后已变”文案。 + +### G-09 后台读取回来的对话框覆盖用户同时打开的对话框 +- 严重度:低 | 置信度:已确认 +- 位置:`apps/ely-tree/src/network.rs:186`(推送选远程)、`:237`(强制推送)、`apps/ely-tree/src/recovering.rs:116`(移动分支) +- 现象:按“推送”(无上游)后立刻按“储藏改动…”并开始键入,`git remote` 回来时储藏对话框连同输入被换掉。 +- 修法:只在 `tree.ask` 仍为空(或仍是本次请求)时赋值。 + +### G-10 选中的分支、标签、位置是窗口级的,跨仓库标签串台 +- 严重度:低 | 置信度:已确认 +- 位置:`apps/ely-tree/src/tree.rs:107-108`(`picked_ref`、`picked_place` 在 `Tree` 上)、`apps/ely-tree/src/refs_pane.rs:25-33`、`apps/ely-tree/src/side_refs.rs:238-245` +- 现象:仓库 A 选中 `main`,切到仓库 B,B 的分支页显示它自己的 `main` 为已选并带动作按钮。 +- 修法:移入 `Opened`,或 `activate()` 时清掉。 + +### G-11 已选边的冲突块再选另一边,提示“结果已手改” +- 严重度:低 | 置信度:已确认 +- 位置:`apps/ely-tree/src/conflict.rs:219-224` +- 修法:给“该块已选定”单独文案,或支持改选。 + +### G-12 符号链接父目录下,当前打开的工作树被当成别的工作树而可“移除” +- 严重度:低 | 置信度:可能 +- 位置:`apps/ely-tree/src/places_pane.rs:253-255`、`:265-271`、`apps/ely-tree/src/structure.rs:245-247` +- 原因:`here` 用 `git worktree list` 记录的原始路径比对已规范化的 `opened.repo.root`(macOS `/tmp` → `/private/tmp`)。 +- 修法:比对前 `canonicalize`。 + +### G-13 非 macOS 平台的死入口 +- 严重度:低 | 置信度:已确认 +- 位置:`apps/ely-tree/src/running.rs:167-173`(停止远程命令非 Unix 报未构建)、`apps/ely-tree/src/tools.rs:109-115`(“在终端中打开”非 macOS 报未构建)、`crates/ely-ui/src/i18n/tree_places.rs:147`、`:281`(“在访达中显示”文案在 Linux、Windows 照样显示) +- 修法:按 `cfg` 禁用或隐藏,`reveal` 换平台中性文案。 + +### G-14 `repo.rs` 的孤立文档注释 +- 严重度:低 | 置信度:已确认 +- 位置:`apps/ely-tree/src/repo.rs:10`(“How many repositories the recent list keeps.” 的常量早已移到 `ely_files::recent`,注释挂到了 `struct Repo` 上) +- 修法:删掉。 + ## K LOK 桥(`crates/ely-lok` 的 worker、客户端、事件) T-01、T-04、T-07 与 S-01 的根源都在这一层,这里只列此外的问题。