feat(editor): 文件内查找——接入 @codemirror/search(Cmd/Ctrl+F) - #587
Conversation
- src/client/TextEditor.tsx: 共享扩展表新增 search({top:true}) + keymap.of(searchKeymap)
(Mod-f 打开、面板固定编辑器顶部、Mod-g / Shift-Mod-g 下一个 / 上一个、Mod-Alt-g
跳转到行、Escape 关闭)。搜索扩展与代码 / markdown 两个 viewer、只读「预览」与
编辑模式共用同一份扩展表,不存在仅可编辑的分支;search 注册在编辑器自有 keymap
之前,Escape 优先关面板(面板未开时 closeSearchPanel 返回 false,仍回落到
simplifySelection),保存键 Mod-s 位置与优先级不变。
- src/client/cm-search.ts(新增): 面板 chrome 走 --dsw-* 令牌(CodeMirror 自带
面板按 &light 上灰白配色,深色皮肤下会浮出一个白框);phrases facet 放进
Compartment,语言切换就地 reconfigure(文档 / 撤销历史 / keymap / 滚动不动)。
- i18n: 新增 15 个 search* key——zh/en 在 locales.ts,其余 19 份词典全量补译
(tests/locales.spec.ts 的 key-set 相等断言);locales.ts 新增 localeSignature(),
TextEditor 同时订阅 DSH locale 与 better-locale override(tab-cell memo 不比较
override,只靠父组件重渲染会漏掉 ja 切换)。
- README / README_EN: 快捷键表各加一行「文件内查找 / Find in file」。
- tests/editor-find.spec.tsx(新增): 扩展含 search keymap、Mod-f 开顶部面板、
Escape 关闭、语言热切换后重开面板文案跟随、Mod-s 保存键仍生效。
- tests/e2e/mount.e2e.ts: 打开 seed 文件后补 Ctrl/Cmd+F → .cm-search 面板可见、
Escape 关闭的真机断言(真实 Chromium + 懒加载 client-editor.js chunk)。
背景:package.json 里 @codemirror/search 一直是死依赖(src 零 import),编辑器
没有任何查找面板——Cmd+F 不被 CodeMirror 接管,长文件里浏览器原生查找只能命中
已渲染的行。本次只接入文件内查找,终端搜索(@xterm/addon-search)另开 PR。
|
@Menghuan1918 打扰一下:本 PR 的 workflow run 目前停在 同时补一份「提交前自检」( 上面 2 个失败文件是 本 PR 新增的两个 spec 在 Node 22 下全绿: 一个提醒:若在本地用 Node 26 跑 挂载冒烟本地也跑过(真实 Chromium + |
现状
src/client/TextEditor.tsx只 import 了@codemirror/state/view/commands,编辑器没有任何查找面板:Cmd/Ctrl+F 不被 CodeMirror 接管,长文件里浏览器原生查找只能命中已渲染(虚拟化)的行。package.json的dependencies里@codemirror/search@^6.7.1是死依赖:全仓库src零 import(grep -rn "@codemirror/search" src/无输出)。git log --all -S searchKeymap空,无search/find分支。README.md/README_EN.md快捷键表都没有查找条目。改动点
src/client/TextEditor.tsx):共享 extensions 数组新增...cmSearchExtensions()+searchPhrases.of()。搜索扩展对 code / markdown 两个 viewer、只读「预览」与编辑模式共用同一份扩展表,不是仅可编辑的分支。search({ top: true })把面板固定在编辑器顶部;keymap.of(searchKeymap)提供 Mod-f 打开、Mod-g / Shift-Mod-g 下一个 / 上一个、Mod-Alt-g 跳转到行、Escape 关闭。src/client/cm-search.ts:扩展装配 + 令牌化面板主题 +CmSearchPhrases(phrases 的 Compartment)。keymap.of([...])之前。与defaultKeymap唯一冲突键是Escape(默认simplifySelection)——放前面让「面板打开时 Escape 关面板」成立,而面板未开时closeSearchPanel返回false自动回落到原行为;Mod-s只存在于编辑器 keymap,位置与优先级零变化(单测断言api.fsWrite仍被调用)。search*key——zh/en在locales.ts,其余 19 份词典全量补译(tests/locales.spec.ts的 key-set 相等断言)。面板文案由 CodeMirror 的phrasesfacet 提供,语言切换经 Compartment 就地 reconfigure(文档 / 撤销历史 / keymap / 滚动不动)。locales.ts新增localeSignature(),TextEditor 同时订阅 DSH locale 与 better-locale override——tab-cell memo 只比较 DSHlocaleRevision,ja override 切换不会触发子组件重渲染,靠父组件重渲染会漏。README.md/README_EN.md快捷键表各加一行「文件内查找 / Find in file」。tests/editor-find.spec.tsx(4 例);tests/e2e/mount.e2e.ts打开 seed 文件后补一段真机断言。验证输出(真实粘贴)
失败项两边完全同集:
agent-pty/smoke(posix_spawnp failed,node-pty 在本机沙箱里无法 spawn)+free-window/sidebar-auto-activation/bottom-auto-terminal/free-window-restored-id(jsdom 的localStorage在 Node 26 下不可用)。本 PR 只新增 4 例,全绿。构建体积(
pnpm build,lib/被 gitignore,故只提交源码——git ls-files lib为空):即
@codemirror/search只进懒加载client-editor.js,核心 bundle 零引入。chunk 契约测试:挂载冒烟(真实 Chromium,
pnpm build && pnpm pack && pnpm test:mount):mount.e2e.ts里新增的断言走通:文件树打开 seed 文件 → 点击.cm-content→Meta/Control+f→.cm-panels-top .cm-search可见 →Escape关闭(真实浏览器 + 懒加载client-editor.jschunk)。唯一失败的desktop-layout.e2e.ts是 DSH 宿主「选择工作区目录」对话框未出现,在未改动的 main 上以同一报错复现(该用例不打开任何文件,与编辑器无关)。本地跑该 lane 需要 pnpm 11 +PLAYWRIGHT_BROWSERS_PATH(本机 playwright 缓存目录只读),与代码无关。取舍
search({ top: true }),与浏览器/IDE 查找条一致,且不遮挡光标行(CodeMirror 默认在底部)。display:none(mount.e2e.ts有互斥断言),Cmd+F 走浏览器原生查找(对渲染后的 DOM 有效),本 PR 不劫持它。若希望「在渲染预览里也走 CodeMirror 查找」,必须先自动切到原文模式,会改变现有模式语义,留待维护者定夺。betterSidebar词典。代价是新增 15 key 需要 20 个词典文件全量补译(与仓库既有做法一致,例如changesFoldLoading那次 20 文件 21 处);en值刻意与 CodeMirror 上游默认文案逐字一致,保证英文体验零变化。&light灰白配色(编辑器主题未声明dark),直接接入会在深色皮肤里浮出一个白框,因此新增令牌化面板主题(只覆盖 chrome:面板底/边框、输入框、按钮、关闭键;匹配高亮保留 CodeMirror 的半透明默认色,深浅两种皮肤都可读)。@xterm/addon-search)另开 PR;未 bump version、未打 tag、未发 npm。