资讯动态

MooTool 原生版文本对比工作区深度解析:Electron 对齐、UTF-16 差异引擎与边界设计

发布时间:2026/10/16 6:22:59 来源:尧图企业网站定制
桌面应用开发工具【免费下载链接】MooToolHandy tool set for developers项目地址https://gitcode.com/gh_mirrors/mo/MooTool点击查看免费下载导读本文聚焦 MooTool 原生 macOS 版next-macos-nativeSwift/AppKit 实现中的文本对比Text Diff工作区围绕其设计文档 docs/text-diff-workspace.md 展开。该工作区以 Electron 版的next/src/features/diff/页面为功能基准用原生控件重建了双编辑器对比、统一差异视图、差异导航、历史记录与工作区持久化等能力并提供了独立的 Swift 差异引擎 TextDiffEngine。读完本文你将掌握该工具的操作入口与三语界面、比较引擎的算法与 UTF-16 字符范围计算、输入限额与长行回退规则、忽略空白的实现语义以及核心用例与自动化验收的覆盖口径。一、功能定位以 Electron 页面为基准的原生重建根据 docs/parity.md 的对齐口径文本对比是 MooTool 26 个工具入口之一。原生版0.8.0 起重建为双编辑器工作区与 Electron 页面对齐的是功能入口、面板顺序与主要操作语义而非逐像素复刻。原生版保留的完整操作集合见 TextDiffWorkspace.swift 中commands、navigationButtons、choices三个工具栏分组比较 / 清空 / 交换 / 复制差异比较按钮带强调样式并绑定 ⌘Return 快捷键keyboardShortcut(.return, modifiers: .command)清空同时清空左右输入与输出交换直接互换左右文本复制差异仅在有统一补丁时可用复制内容为comparison.unified。上一处 / 下一处在可见差异段中循环定位同时选中左右编辑器对应行首状态栏显示第 x / y 处差异。忽略空白复选开关仅影响高亮显示不删改真实补丁。三种高亮模式行与字符both、仅字符characters、仅行lines。左右/统一视图左右对比side与统一差异unified两种显示模式统一视图在双编辑器下方显示只读的三行上下文补丁。历史入口位于窗口工具栏clock.arrow.circlepath图标以 sheet 形式打开HistoryView(toolID: textDiff)。界面多语言方面工作区标题、工具栏、分栏标签、状态栏以及输入超限等引擎错误文案全部通过textDiff.*这一组本地化键随general.language三语切换zh-CN / en-US / ja-JP。三套文案完整定义在 AppLocalization.swiftzh-CN 位于第 1025 行附近en-US 位于 2359 行附近ja-JP 位于 3693 行附近例如状态栏统计文案分别是新增 %d · 删除 %d · 修改 %d、%d · −%d · ~%d、追加 %d · 削除 %d · 変更 %d。二、工作区布局分栏、同步滚动与窄窗口适配左右编辑器使用PersistedHSplit实现可调整宽度的分栏默认左栏 420pt、最小 240pt、最大 900pt分栏宽度与编辑器状态均持久化。左右输入在 side 视图下双向同步滚动——editorPersistence在检测到一侧滚动偏移变化后会驱动另一侧enclosingScrollView滚动到相同坐标两侧正文保持对齐见 TextDiffWorkspace.swift。统一视图unified模式下布局变为上下两段上半部分是双编辑器保留可调整宽度与同步滚动下半部分是一个只读的统一补丁面板面板标题统一差异、字符数统计与高亮都基于comparison.unified及其行/字符级 span 渲染editable: false。窄窗口适配工具栏使用ViewThatFits(in: .horizontal)做自适应——宽度充足时保持单行工具栏940px 以下自动改为两行工具栏第一行放比较/清空/交换/复制命令第二行放导航按钮、分隔线与高亮/视图/忽略空白选项操作集合与单行模式完全一致。三、核心比较引擎TextDiffEngine 与 UTF-16 差异计算原生版没有复用 Electron 的 JS 实现而是在 TextDiff.swift 中实现了独立的 Swift 引擎TextDiffEngine。其注释明确说明这是对 Electron 差异页行补丁与 UTF-16 字符范围的独立 Swift 实现而 Electron 侧 diffTools.ts 又注释说明自己镜像了 Java Swing 文本对比工具的DiffService契约行级 Myers diff、配对的字符级改动、三向 UI 范围、三行上下文统一补丁。三方实现遵循同一契约这是跨版本一致性的关键。3.1 算法链路TextDiffEngine.compare(_:_:ignoreWhitespace:language:)的调用链路输入校验左右文本 UTF-16 单元总数 ≤ 500,000否则抛textDiff.error.totalLength左右行数乘积 ≤ 10,000,000否则抛textDiff.error.tooManyLines错误文案三语见 AppLocalization.swift。行切分splitLines识别全部 Unicode 行终止符\n、\v、\f、\r、NEL U0085、LS U2028、PS U2029\r\n作为单一行结束处理并保留末尾空行——与 JavaString.split(\\R, -1)语义一致。行级补丁patch基于 SwiftCollectionDifference生成 insert / delete / change 三类 delta本质是行级最短编辑序列等价 Myers 行差异。配对行做字符级比较对 change delta 中的配对行把行内容按 UTF-16 单元拆成数组再做一次patch得到字符级新增/删除/修改段。生成统一补丁unified/unifiedGroup生成带--- old/ new头与 -起行,行数 起行,行数 块的补丁文本上下文固定为 3 行。3.2 UTF-16 字符范围所有位置与长度均以UTF-16 单元为基准通过lineStarts预计算每行起始偏移再叠加行内字符 delta 的偏移量最终产出TextDiffSegmentkind.insert/.delete/.changeleft/right对应侧的NSRange(location:length:)缺失侧为NSRange(location: NSNotFound, length: 0)invalidRangewholeLine标记该段是否覆盖整行行级段或仅为行内字符段。以测试用例testTextDiffElectronRangesAndUnifiedPatchCoreTests.swift为例比较one\ntwo\n与one\nthree\nplus\n得到 change 段left 5..7 / right 5..9two→three 的行内字符修改与 insert 段right 10..14整行新增 plus。这个断言与 Electron 测试 diffTools.test.ts 中 Java 兼容字符范围的断言完全一致。3.3 差异统计与结果模型TextDiffResult携带added/removed/changed三个计数insert 段计入新增delete 段计入删除change 段按配对行数计入修改多出的行分别归入新增或删除。状态栏据此显示新增 x · 删除 y · 修改 z。四、自动比较、历史与草稿恢复4.1 160ms 自动比较输入变化后约160 毫秒自动触发一次比较。实现上SwiftUI 视图用.task(id: comparisonKey)监听comparisonKey由左右文本与忽略空白开关拼成先Task.sleep(160ms)再执行calculate(recordHistory: false)。Electron 侧同样是setTimeout(..., 160)见 TextDiffTool.tsx两端一致。4.2 历史写入与恢复自动比较不会写历史只有点击比较按钮或按 ⌘ReturnrecordHistory: true时才把左右原文与统一补丁写入历史store.record(textDiff)历史记录写入统一补丁到draft.output。历史 sheet 打开后恢复历史条目时会回填左右文本并重新计算高亮因为高亮总是由引擎实时产出不依赖历史里缓存的展示状态。4.3 工作区持久化与旧草稿兼容TextDiffOptions显示模式、高亮模式、忽略空白、左右编辑器与统一编辑器的选择/滚动状态整体写入ToolDraft.textDiff并随本产品独立工作区workspace.json持久化重启后恢复。兼容性要点旧版本工作区草稿只包含左右文本input/secondary没有textDiff选项字段——加载时按默认选项读取draft.textDiff nil时初始化默认TextDiffOptions()。测试testTextDiffWhitespaceTrailingLinesAndBounds中明确验证了旧草稿无textDiff字段可正常解码、新草稿字段可完整往返CoreTests.swift。首次打开且左右文本为空时工作区会自动填充一组演示文本MooTool\nquiet desktop tools\nold line\n与MooTool\nquiet desktop toolkit\nnew line\n与 Electron 页面的 fallback 草稿一致。五、边界与性能保护限额、长行回退与后台执行为避免最坏情况比较占用过多资源引擎设置了双重限额限额项上限超限行为左右 UTF-16 单元总数500,000抛textDiff.error.totalLength错误左右行数乘积10,000,000抛textDiff.error.tooManyLines错误单对比较行合计长度4,000 UTF-16 单元不再做字符级比较改用行级高亮长行回退的具体语义TextDiff.swift当before.utf16.count after.utf16.count 4000时直接生成wholeLine: true的 change 段跳过该行内的字符 patch但统一补丁仍保留完整内容补丁文本不受影响只是不做行内字符高亮。测试testTextDiffWhitespaceTrailingLinesAndBounds用 3000 字符对 3000 字符验证了首段wholeLine true且unifiedCharacters为空。比较在后台执行calculate通过Task.detached(priority: .userInitiated)调用引擎完成后校验输入未被改动draft.input left draft.secondary right options.ignoreWhitespace ignore与任务未被取消才更新comparison从而保证输入变化时不会用过期结果覆盖当前工作区。需要说明的原生高亮差异原生版使用 NSTextView 的临时文本背景layoutManager.temporaryAttribute(.backgroundColor, ...)着色颜色映射为 insert→绿色、delete→红色、change→橙色通过 alpha 0.34强/ 0.16弱区分字符与行背景尚未包含Monaco 的行侧边标记及完整编辑装饰Electron 侧对应 CodeMirror 的cm-diff-line-*/cm-diff-character-*decoration。六、验证体系核心用例、真实窗口 smoke 与安装包复测6.1 核心引擎用例check-core.shscripts/check-core.sh用swiftc -parse-as-library -D STANDALONE_CHECK将 CoreTests.swift 与核心库对象文件链接成独立检查程序运行文本对比部分对照 Electron 测试样例逐项检查字符范围与增删改计数testTextDiffElectronRangesAndUnifiedPatch校验 change/insert 段的精确 NSRange 与added/removed/changed统计统一补丁格式校验--- old\n new\n -1,3 1,4 \n one\n-two\nthree\nplus\n完整输出与行 span 类型序列header/hunk/removed/added忽略空白testTextDiffWhitespaceTrailingLinesAndBounds验证忽略空白时 segments 为空、unifiedCharacters为空但统一补丁仍包含-one two/one two末尾空行插入same\nnew\n、删除old\n的整行 insert/delete 段长行回退30003000 字符对改用行级高亮、统一补丁字符 span 为空旧草稿兼容无textDiff字段的旧草稿按默认选项解码。6.2 真实窗口 smoke 验收smoke.sh --window-capture --diff-onlyscripts/smoke.sh动作逻辑在 NativeSmoke.swift通过 NativeDiffAcceptance.swift 操作实际的比较/导航按钮与 NSTextView注入样例文本并等待统一补丁输出更新检查左右编辑器的字符差异临时背景是否生效点击比较按钮确认历史保存了右侧正文点击下一处确认双侧编辑器光标定位到同一位置切到统一视图确认只读面板内容与draft.output一致开启忽略空白后再次比较确认补丁仍含空白差异行从历史恢复草稿并保存新进程重启后校验工作区恢复。同一脚本的--window-capture分支还会对textDiff-side-light/dark、textDiff-unified-light/dark、textDiff-compact共 5 个布局场景截图其中textDiff-compact以940×630窗口验证verifyCompactLayout——逐一检查 left/right/unified 三个编辑区域的最小 X 与最大 X 均在窗口边界内未被裁切。6.3 安装包复测安装包dist/下的独立副本会再次执行文本对比核心用例验证打包产物中的引擎行为与源码一致防止源码绿、安装包红的偏差。七、实践小结如何用好文本对比工作区快捷键⌘Command Return 等价于点按比较同时写入本产品历史自动比较输入后 160ms不写历史。导航技巧在仅字符高亮模式下上一处/下一处只遍历行内字符差异visibleSegments过滤wholeLine段适合逐字审阅改动。忽略空白语义它只隐藏空白差异的高亮统一补丁与复制的差异文本始终保持原始内容——不要把忽略空白当作删除补丁。大数据量输入控制左右合计在 50 万 UTF-16 单元、行数乘积在 1000 万以内单行超过 4000 单元会自动退化为行级高亮但统一补丁内容完整保留。视图切换左右对比适合行对齐审阅统一视图下方只读补丁适合复制分享复制差异按钮输出的就是该补丁文本。参考文档与代码索引工作区设计文档docs/text-diff-workspace.md功能对齐口径docs/parity.md原生实现TextDiffWorkspace.swift、TextDiff.swiftElectron 参照TextDiffTool.tsx、diffTools.ts、diffTools.test.ts测试与验收CoreTests.swift、NativeDiffAcceptance.swift、scripts/check-core.sh、scripts/smoke.sh三语文案定义AppLocalization.swift赞分享桌面应用开发工具【免费下载链接】MooToolHandy tool set for developers项目地址https://gitcode.com/gh_mirrors/mo/MooTool点击查看免费下载相关推荐MooTool Vault MCP 只读工具对齐 Electron vaultAccess.test.ts严格 UTF-8 解码、搜索分页与安全边界的 Vitest 对齐实践DIFF-461MooTool Vault MCP 只读工具对齐 Electron vaultAccess.test.ts 严格 UTF 8 解码、搜索分页与安全边界的 Vi桌面应用开发工具MooTool Compose 版设置数值边界规范化对齐 Electron mergeSettings 的 clampNumber 契约解析MooTool Compose 版设置数值边界规范化对齐 Electron mergeSettings 的 clampNumber 契约解析 本文基于 Moo桌面应用开发工具MooTool 原生版格式化工作区解析文本/文件双模式、内嵌解析器与安全边界MooTool 原生版格式化工作区解析文本/文件双模式、内嵌解析器与安全边界 MooTool 是一款面向开发者的桌面工具箱其在 Electron 版之外还提桌面应用开发工具上一篇在本地 Docker 集群上部署 Prisma 数据库服务prisma local 完整实战指南下一篇Roc 编译器快照测试深度解析以 Dec 类型注解dec_annotation为例透视 tokenize→parse→canonicalize→type-check 全管线创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑