Skip to content

fix(live-preview): map table rows to source lines via AST positions - #353

Open
c19881230 wants to merge 2 commits into
floatboatai:mainfrom
c19881230:fix/table-row-line-mapping
Open

c19881230 wants to merge 2 commits into
floatboatai:mainfrom
c19881230:fix/table-row-line-mapping

Conversation

@c19881230

@c19881230 c19881230 commented Sep 19, 2026

Copy link
Copy Markdown

Summary / 摘要

表格行改为按自身在文档中的位置定位源码行,不再靠匹配行内容| - | - |内容全是短横线的数据行不会再导致其后每一行的行号错位。

Motivation / 背景与动机

分隔行原本靠"这行内容是不是全是短横线"来判断,而内容全是短横线的数据行与它无从区分,于是被一并跳过,导致其后每一行都错位一位:后面那行拿不到行号,改动被丢弃;全横线行则拿到了后一行的行号,提交时把后一行覆盖掉。这四处调用点共用同一份错位数组。分隔行在解析结果里没有对应节点,因此行号只能按各行自身的位置来算 —— 这也是单元格早就在用的方式。

  • Issue: N/A
  • Roadmap (docs/ROADMAP.md): N/A — bug fix
  • OpenSpec change: N/A — bug fix, no public API change

Changes / 变更内容

  • packages/core:
    新增两个函数按行自身位置算出行号,分隔行改为"没有任何一行认领的那一行";原来五处扫内容的代码全部收敛到同一个函数。
  • packages/core: 加列只给真正的分隔行补---`,定位不到时退回旧判断;拖拽换行序仍按当前源码算行号,因为传入的快照整行重写过。
  • packages/plugin-*: N/A
  • apps/electron-demo: N/A
  • openspec/: N/A — no public API change.

Testing / 测试

  • pnpm test passes / 全绿 —— 899 通过 / 10 失败;10 个失败均为预先存在且与本改动无关(见下方环境说明)
  • Affected packages build (pnpm build) / 受影响包构建通过 —— 退出码 0,14 个包全部通过
  • New / updated vitest cases / 新增或更新的 vitest 用例:11 个,位于 packages/core/test/live-preview.test.ts
  • Manual UI check in electron-demo / electron-demo 手动验证:两个版本各自从源码打包后并排人工对比,四个现象都只在旧版复现。录屏见下。
  • 把源码换回改动前的版本重跑单测:11 个里 9 个失败,失败信息与上述四个现象一致
  • 真实 Electron 渲染进程(Chromium 134)端到端:7 个场景用真实 DOM 事件驱动,修复后 7/7 通过,旧版 0/7
  • git diff --check

Manual side-by-side check / 人工并排对比验证

旧版(修复前)表格输入进去的时候会出现四个问题:

  1. 修改 x 所在格子,改动会消失,表格里依然是 x
  2. 光标放在行左侧出现的握把,拖拽不能实现换行,表格在操作后依然不变。
  3. 选中 | - | - | 行并按 Delete 时,删除的是 x|y 那一行。
  4. 更改 | - | - | 行里的内容时,x|y 格子的内容变成修改后的值,而 | - | - | 行保持不变。

经过修复:修改单个表格内容可以丝滑实现,拖拽换行功能成功运行,选中的删除项不会出现混淆。

本地环境说明: 本机 pnpm test 为 899 通过 / 10 失败。这 10 个失败均为预先存在,集中在 apps/electron-demo/test/plugin-host-broker.test.ts,报错为 EPERM: operation not permitted, symlink —— Windows 在未开启开发者模式或提权时不允许创建符号链接,而那几个用例测的正是基于符号链接的越权防护。与本改动无关,CI(Linux)上不会出现。

Compliance / 合规自检

  • CLA signed — first-time contributors will be prompted automatically by the CLA bot / 首次贡献者按 CLA 机器人提示签署
  • AI disclosure:
    AI 使用说明:本 PR 是考核任务的一部分,考核明确允许使用 AI 工具(不限工具与用法)。设计与功能实现由贡献者与 AI 编码工具(Claude Code)协作完成,功能代码主要由 AI 生成。已知 GOVERNANCE.md §6.2 对主要由 AI 生成的实现类 PR 有明确限制,此处如实披露,不声称符合该条政策。贡献者已逐行审阅代码,并确认了每一处设计决策 ,这些理由均已写入代码注释,可在评审中逐条说明。
  • New dependencies (if any) listed with license & rationale (none if blank): 无
  • No build artifacts committed (dist/, dist-electron/, compiled .js from .ts) / 未提交构建产物
  • No secrets / .env / personal vault data committed / 无敏感信息

Checklist / 自检清单

  • Title follows Conventional Commits / 标题遵循 Conventional Commits —— fix(live-preview): …
  • Public API changes update package README / types — 改了公共 API 已同步 README 与类型;本次无公共 API 变更,packages/core 未新增任何导出
  • Touched live-preview-table.ts → walked through the 12 Table Widget rules in CLAUDE.md / 已核对 12 条表格规则 ,本改动只涉及行号解析,不触碰交互状态机。
  • New capability / breaking change → OpenSpec proposal linked / 新 capability 或破坏性变更已附 OpenSpec —— 不适用(bug 修复)。
  • Change aligns with project scope (GOVERNANCE.md §4) / 改动符合 GOVERNANCE.md §4 的项目范围 —— core 的 bug 修复

Screenshots / Recordings · 截图或录屏 (UI changes)

default.mp4
default.mp4

c19881230 and others added 2 commits September 18, 2026 20:06
Table rows were mapped to source lines by sniffing line content: any line
whose cells are all dashes was treated as the delimiter row and dropped from
the row index. A data row written `| - | - |` matched too, shifting every
subsequent index.

Two silent failures followed. The row after an all-dash row lost its mapping,
so `rememberCellSourceEdit` returned early and edits in it were discarded;
the all-dash row meanwhile carried the following row's index, so committing
it rewrote that source line and destroyed its content. `deleteRow`,
`moveRow`, range paste and the selection Delete handler shared the same
misindexing.

Rows already carry their own absolute offsets — `adaptTable` records
`position(c.from, c.to)` for every TableHeader and TableRow — and the widget
already reads cell positions the same way. Resolve the line from the row's
own position instead of guessing from content; the delimiter row is the one
line no row claims.

`addColumn` now treats only that line as the delimiter, falling back to the
content predicate when it cannot be resolved, so a degenerate AST cannot make
the command refuse to edit.

`estimateTableHeight` still uses the content predicate; it affects height
estimation only and is left for a follow-up.

Co-Authored-By: Claude Code <noreply@anthropic.com>
The fix that resolved table rows to source lines via AST positions shipped
with tests for the mapping itself and for `addColumn`, but the four other
call sites it corrected had no coverage: `deleteRow`, `moveRow`, range paste
and the selection Delete handler. All four resolve their lines through the
same function, so a regression in it would have re-appeared silently.

Each test drives the real interaction rather than calling internals: a row
grip click plus Delete for `deleteRow`, a grip mousedown/mousemove/mouseup
sequence for `moveRow`, and a cross-cell range selection for the paste and
Delete paths. The paste case reaches the table through its input target
provider, which is the path a real paste takes.

Verified in both directions. Against the pre-fix source all four fail, with
symptoms matching the bug report: Delete removes the wrong row, the drag is
a silent no-op, and the paste lands on the wrong line. Against the fix all
pass.

Co-Authored-By: Claude Code <noreply@anthropic.com>
@CLAassistant

CLAassistant commented Sep 19, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@c19881230 c19881230 changed the title Fix/table row line mapping fix(live-preview): map table rows to source lines via AST positions Sep 19, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants