MooTool Compose 版 Host 工具查找条替换行为对齐:单次替换成功后清空状态栏 notice
桌面应用开发工具【免费下载链接】MooToolHandy tool set for developers项目地址https://gitcode.com/gh_mirrors/mo/MooTool点击查看免费下载导读本文围绕 MooTool 跨平台新一代 Compose 桌面版next-compose中 Host 主机文件编辑工具的一次精细行为修正设计文档 DIFF-306展开当用户在 Host 查找条中执行**单次「替换」**并成功时工具应像「全部替换」和 JSON 查找条一样将状态栏session.notice清空避免残留旧的「已保存/已导出」等提示文案造成误导。读完本文你将理解该状态栏 notice 机制的完整语义、替换类操作在 Compose 与 Electron 两端的对齐策略以及如何通过会话快照与桌面测试验证该行为。一、问题背景替换成功后状态栏残留旧文案在 MooTool 的工具框架中每个工具会话Session都带有一个状态栏字段notice用于展示「已保存」「已导出」「已复制」等一次性操作反馈。此前 Host 工具的替换行为存在一个不一致点「全部替换」DIFF-301已规定成功时session.notice 不再写入匹配数文案单次「替换」此前只更新正文与findReplacedCount已替换计数不会主动清空session.notice于是状态栏可能残留上一次操作的旧提示例如用户先点击「保存」看到「已保存」再执行单次替换状态栏仍显示「已保存」与实际状态不符。与此同时JSON 工具的查找条在单次「替换」成功时已经会同时清空notice与copyState对齐 Electron 的replaceCurrent而 Host 端此前缺少这一处理。Electron 版的HostTool本身没有状态栏notice字段因此不存在此问题Compose 版要补齐对齐就规定替换类操作成功后统一清空提示。二、行为定义F10 单次替换成功即清空 noticeDIFF-306 规定的目标行为非常明确F10查找条单次「替换」成功session.notice 与全部替换相同。即无论单次替换还是全部替换只要替换动作真实发生有匹配被替换状态栏 notice 一律置空无匹配的情况不走 notice而是走独立的 toast 提示toastFindNoMatches()仅弹出find.noMatches信息不改工具状态栏与 Electron 端toast.info(findReplace.noMatches)对齐。三、源码实现HostScreen.kt FindBar 替换分支Compose 端的关键实现位于 HostScreen.kt 的FindBar私有可组合函数中。单次「替换」按钮的完整处理逻辑如下MooButton(container.t(find.replace), onClick { val selection contentField.selection val caret maxOf(selection.start, selection.end) val (next, match) FindReplace.replaceCurrent( session.content, session.findQuery, session.replaceText, session.findOptions, caret, selection.start, selection.end, ) if (match null) { container.toastFindNoMatches() } else { session.content next session.findReplacedCount 1 session.notice onContentFieldChange( HostFindNavigation.afterReplaceAndSelectNext( next, session.findQuery, session.findOptions, contentField, match ) ) } onChanged() }, p5Toolbar true)关键点拆解命中判定调用FindReplace.replaceCurrent(...)后通过返回的match是否为 null 判断本次替换是否成功成功分支更新session.content、findReplacedCount 1并执行session.notice 即 DIFF-306 的核心变更跳转续替通过HostFindNavigation.afterReplaceAndSelectNext(...)在替换后自动选中下一处匹配便于连续替换无匹配分支只调用container.toastFindNoMatches()不触碰 notice。相邻的「全部替换」按钮HostScreen.kt#L1003-L1014遵循同样的清空约定count 0时 toast 无匹配否则更新findReplacedCount count并session.notice 。两处合在一起就是「替换类操作成功后统一清空提示」这一统一约定。四、与 JSON 查找条的横向对齐DIFF-306 明确要求 Host 单次替换对齐 Compose JSON 查找条。JSON 端的对应实现位于 JsonScreen.ktMooButton(container.t(find.replace), onClick { onEdt { if (!RstaFindNavigation.replaceAndSelectNext(session.editor, session.findQuery, session.replaceText, session.findOptions)) { container.toastFindNoMatches() } else { session.findReplacedCount 1 session.clearJsonPathQueryResult() session.notice session.copyState CopyFeedbackPolicy.IDLE } onChanged() } })可以看到 JSON 端在成功分支里除了session.notice 外还会清空copyState复制按钮反馈状态与 JSONPath 查询结果Host 端由于不涉及copyState与 JSONPath 结果只需清空 notice 即可达到同样的「不留旧提示」效果。这是典型的最小化对齐只引入目标语义需要的字段改动避免过度设计。五、与 Electron HostTool 的跨端对齐DIFF-306 提到的对照基准是 Electron 端 HostTool.tsx 的replaceCurrent(all: boolean)函数。Electron 实现的关键差异在于function replaceCurrent(all: boolean): void { if (!find) return if (all) { const result replaceAllMatches(content, find, replace, findOptions) if (result.count 0) actions.toast.info(t(findReplace.noMatches)) else { setContent(result.content) setReplacedCount(result.count) } return } const result replaceCurrentMatch(content, find, replace, findOptions, editorRef.current?.getSelection() ?? null) if (!result.replaced) { actions.toast.info(t(findReplace.noMatches)) return } setContent(result.content) setReplacedCount((count) count 1) // ... }Electron 版单次替换成功时只做两件事更新正文setContent(...)、累计replacedCount。由于 Electron 的HostTool没有状态栏notice字段状态反馈一律通过 toast 通道完成无 notice 可写、也无旧 notice 可残留因此 Compose 端引入session.notice 恰好把两者对齐到同一语义替换成功不产生任何持久化状态栏文案。六、计数与会话快照findReplacedCount 的完整链路本次清空 notice 并不影响已替换计数的展示。查找条尾部始终渲染find.replacedPrefixfindReplacedCount见 HostScreen.kt#L1015-L1019单次替换1、全部替换设为count。替换计数还需要随会话快照持久化。HostSession与HostSessionSnapshot定义在 SessionManager.ktHostSessionSnapshot可序列化字段中包含findReplacedCount: Int 0同时携带findQuery、replaceText、matchCase、wholeWord、regex等查找条件HostSession对应维护var findReplacedCount: Int 0snapshotState()将其写入快照restore()时读回值得注意的细节restore()中快照恢复后 notice 会被重置为空字符串notice 也就是说重启/恢复会话后状态栏本来就不保留历史 notice这进一步佐证了「notice 属于瞬时操作反馈、不应跨操作残留」的设计意图。DIFF-288引入的规则同样值得回顾打开/关闭查找条、修改查找词或切换选项大小写/整词/正则时findReplacedCount都要归零避免计数与当前查找条件不一致。七、测试与验证DIFF-306 的验证手段包括源码对照比对 HostTool.tsx 的replaceCurrent无 notice与 Compose JSONFindBar替换分支JsonScreen.kt 上文已给出确认语义一致桌面单元测试运行./gradlew :composeApp:desktopTest --offline。替换计数的快照往返由独立测试 HostSessionSnapshotTest.kt 覆盖Test fun snapshot_roundTrips_findReplacedCount() { val session HostSession() session.findReplacedCount 5 val restored HostSession().also { it.restore(session.snapshotState()) } assertEquals(5, restored.findReplacedCount) }该测试验证snapshotState()/restore()能正确保留findReplacedCount确保替换计数在会话持久化过程中不丢失从而与「替换成功清空 notice、但计数照常累加」的行为闭环一致。八、关联设计文档脉络本次改动属于 MooTool Compose 版「查找条状态栏语义」系列迭代的一部分相关设计文档均位于 next-compose/docs/diff 目录下DIFF-288Host 查找条已替换计数 「共找到」文案引入findReplacedCount及其归零规则并约定替换成功不写json.find.matchesDIFF-301Host/随手记「全部替换」成功不写 matches 状态栏将「全部替换」的 notice 置空推广到 Host 与随手记DIFF-306Host 单次替换成功清空状态栏 notice本次主题补齐「单次替换」这一最后缺口。三步迭代完成后Compose 版所有工具Host、JSON、随手记等的查找条替换行为达成统一约定替换成功 正文更新 计数累加 notice 清空无匹配 仅 toast 提示。小结DIFF-306 是一次小而关键的状态栏语义修正通过session.notice 让 Host 单次替换与全部替换、JSON 查找条乃至 Electron 端行为完全对齐杜绝了旧提示文案残留造成的状态误读。理解这一改动有助于掌握 MooTool 工具会话状态栏 notice 的生命周期约定瞬时反馈、操作后清空、不随快照持久化以及 Compose 与 Electron 跨端行为对齐的具体落地方式。若需深入可直接查阅上述HostScreen.kt、JsonScreen.kt、HostTool.tsx与SessionManager.kt中的对应实现。赞分享桌面应用开发工具【免费下载链接】MooToolHandy tool set for developers项目地址https://gitcode.com/gh_mirrors/mo/MooTool点击查看免费下载相关推荐MooTool Next Compose 查找条「查找」按钮补齐与 JSON 替换后 notice 清空DIFF-289 对齐 Electron 的实现剖析MooTool Next Compose 查找条「查找」按钮补齐与 JSON 替换后 notice 清空DIFF 289 对齐 Electron 的实现剖析桌面应用开发工具MooToolCompose 桌面版Host 查找替换单次替换后自动选中下一处匹配的实现解析MooToolCompose 桌面版Host 查找替换单次替换后自动选中下一处匹配的实现解析 导读 MooTool 的 Compose Multiplat桌面应用开发工具MooTool Compose 桌面端 Host 与随手记「全部替换」状态栏行为对齐实战DIFF-301 深度解析MooTool Compose 桌面端 Host 与随手记「全部替换」状态栏行为对齐实战DIFF 301 深度解析 本指南围绕 MooTool 新一代 Co桌面应用开发工具上一篇终极B站视频下载指南使用bilidown轻松收藏哔哩哔哩内容下一篇Leaflet Realtime错误处理与调试常见问题解决指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考