Uninote
Uninote
用户根目录
brdr
common
programming
docs
后端试题
问题讨论

阶段 2 桌面笔记库设计与验证

返回文档导航

  • 阶段 2 将编辑器从“逐个打开文件”扩展为本地优先的 Markdown 笔记库。
  • 笔记库就是用户选择的普通文件夹,不要求导入或转换文件。

笔记库与目录树

笔记库会话

  • 通过系统文件夹对话框打开笔记库,并自动恢复上次使用的笔记库。
  • 可从文件菜单或 Ctrl/Cmd+Shift+N 新建空白窗口;所有平台均可按 Ctrl+Shift+Alt+S 在当前已打开的应用窗口间循环切换;每个窗口使用独立的工作区管理器,可同时编辑不同笔记库,不会因其他窗口切换而改变当前库。
  • 最近笔记库不限制条目数,可从侧边栏、原生“文件 → 打开最近”菜单或全平台统一的 Ctrl+R 快捷选择面板切换;菜单和面板显示本地仓库名称与完整路径,并在打开、重命名或移除仓库后即时更新。
  • 每个笔记库拥有独立的打开标签与活动标签会话;切换笔记库时界面同步切换到该库上次打开的文件,没有打开笔记库时不持久化标签。
  • 启动恢复、最近列表切换、刷新或读取详情时若确认笔记库根目录已被移动或删除,会清除当前内存索引,并从最近列表及对应的最近文件/收藏状态中移除失效路径;其他扫描错误仍按原错误报告,不会误删记录。

仓库详情与移除

  • “刷新”旁的“仓库详情”按钮展示当前工作区名称、路径、本地 Markdown 数量及可用的托管同步身份和状态。
  • 详情界面的“修改本地名称”只更新保存在应用状态中的显示名称,侧边栏、最近仓库和详情页会立即刷新。
  • 修改本地名称不会改变磁盘上的仓库根目录、最近文件、收藏、后台同步设置和已打开标签路径。
  • 详情界面中“修改本地名称”之后的“移除仓库”按钮,会在二次确认后清除当前选择、最近文件、收藏和本地显示名称。
  • 移除仓库会删除仓库根目录下的 .mynote 元数据文件夹,但不会删除仓库目录或 Markdown 等笔记文件。
  • 若元数据删除失败,仓库会保留在列表中以便重试。

目录树与路径边界

  • 目录树展示普通文件夹及 .md.markdown.mdown.mkd 文件。
  • .mynote、符号链接和名称以 .app 结尾的 macOS 应用包不会进入目录树,也不会被递归扫描。
  • 根目录 .mynoteignore 只阻止尚未加入管理的新路径进入目录树。
  • 已经显示过的 Markdown 文件会继续显示和参与搜索,即使后来新增的规则命中了它。
  • 单个笔记库最多扫描 10000 个 Markdown 文件和 20000 个目录项;超过限制时明确报错。
  • 所有工作区 IPC 都再次校验真实路径,拒绝 .. 越界以及通过符号链接访问库外文件。
  • .mynote/outline-index-v1.json 是可删除、可重建的派生缓存,不进入目录树或应用同步协议。

.mynoteignore

笔记库根目录可创建 UTF-8 编码的 .mynoteignore。它使用 .gitignore 匹配语义,支持空行、# 注释、! 反选、*?**、以 / 锚定根目录以及以 / 结尾的目录规则。例如:

# 构建产物与临时文件
build/
*.tmp
/private.md
!important.tmp

规则与准入状态

  • .mynoteignore 最大 256 KB,必须是普通文件,不能是符号链接。
  • 配置文件本身不会显示在只展示 Markdown 的目录树中,但会参与托管同步,也不能被自身规则排除。
  • 规则是新路径的准入规则:已进入目录树或同步基线的文件不受后来规则影响。
  • 同一目录中新出现且命中规则的文件仍保持隐藏且不会加入同步。
  • 仓库级准入结果保存在 .mynote/managed-paths.json,因此重启应用后仍然有效。
  • .app 应用包和 .mynote 是不可反选、也不能被“已管理”状态绕过的内置排除项。

同步兼容边界

  • .mynoteignore 同步不兼容旧版客户端和服务端;启用前必须升级所有设备并重启同步服务。
  • 所有设备也应升级到支持“只限制新路径”的客户端;旧客户端仍会停止跟踪命中规则的已有文件。
  • 多个设备并发修改配置时,远端版本成为当前规则。
  • 并发修改产生的本地版本保存在 .mynote/sync-conflicts/mynoteignore-<设备>-r<revision>.txt,不会作为规则生效或再次同步。

文件操作

侧边栏支持:

  • 在当前文件夹新建 Markdown 文件或子文件夹;文件名未包含受支持的 Markdown 扩展名时自动补充 .md,已有 .md.markdown.mdown.mkd 时保持不变。
  • 重命名文件和文件夹。
  • 将条目移动到用户输入的库内目标文件夹。
  • 在原位置生成带“副本”后缀的文件或文件夹副本。
  • 将条目移入操作系统回收站,而不是直接永久删除。
  • 收藏和取消收藏 Markdown 文件。
  • 从目录树或已保存文件的标签页右键菜单复制系统绝对路径,或复制以笔记库根目录为基准、统一使用 / 的相对路径;库外文件的标签页只提供绝对路径。
  • 文件树与 Tab 上下文菜单可在系统文件管理器中显示对应条目;默认快捷键为 Shift+Alt+R,并可在快捷键设置中修改。
  • 默认使用 Shift+Alt+C 复制路径;复制相对路径使用 Ctrl+K Ctrl+Shift+C,macOS 对应 Cmd+K Cmd+Shift+C。两项快捷键均可在快捷键设置中修改。

目标位置已存在同名条目、移动到自身内部、操作符号链接或路径越界时,操作会被拒绝。打开且尚未保存的文件及其父文件夹不能被移动、重命名或删除,避免用磁盘版本覆盖内存中的修改。

移动或重命名打开的干净文档后,标签路径、正文基线和文件监听会一起迁移,不需要重新打开。

附件引用

移动、重命名或复制 Markdown 文件和文件夹时,应用会调整常见的内联图片相对路径:

![说明](../assets/image.png)
  • 文件单独移动时,引用继续指向原附件。
  • 文件夹整体移动或复制时,位于该文件夹内部的附件引用跟随新位置。
  • HTTP、HTTPS、根路径和锚点引用不会被修改。
  • 无法无损识别的复杂或未转义目的地址保持原文,不做猜测性修改。
  • 在应用内从一个已保存文档复制或剪切文本并粘贴到另一目录的已保存文档时,文本中的内联图片路径会以目标文档为基准重新计算。
  • 同目录粘贴和外部剪贴板文本保持原样。
  • 自定义剪切仍写入编辑器原生撤销历史,可用 Ctrl/Command+Z 撤销并重做。

该能力当前只处理 Markdown 图片语法,不会改写普通链接或 HTML 标签中的路径。

搜索与状态

  • 搜索匹配相对文件路径和 Markdown 正文,不区分大小写。
  • 侧栏搜索框在聚焦时使用与应用一致的蓝色焦点提示,并在窄侧栏中收缩到可用宽度,不使用可能溢出的系统原生高亮边框。
  • 搜索结果区域不会在零条或单条结果时被侧栏布局压扁;长路径和正文片段会省略显示,且不会产生横向滚动条。
  • 单文件超过 2 MB 时跳过正文搜索,但仍可通过目录树打开。
  • 每次最多返回 100 项,并显示正文命中片段。
  • 文件内容按修改时间和大小缓存;再次搜索无需重复读取未变化的文件。
  • 搜索框旁的“在编辑器中打开”会创建当前会话内的只读搜索快照;每次操作创建独立标签,应用重启后不恢复这些标签。
  • 搜索编辑器使用 .code-search 风格文本,包含查询、结果/文件统计、文件分组及源码行号;匹配行使用 :,上下文行使用 -
  • 搜索编辑器默认显示每个命中前后各一行上下文,相邻命中的重叠上下文只显示一次;页头开关可隐藏或恢复上下文,无需重新搜索。
  • 搜索编辑器页头提供查询输入框;输入停止 200 毫秒后重新搜索当前笔记库,并原位更新结果、标签标题和源码跳转映射,已有上下文显示状态保持不变。
  • 搜索编辑器支持 Ctrl/Command+FF3Shift+F3 页内查找。双击文件标题打开首行,双击匹配行会定位并选择仍位于记录位置的首个匹配,双击上下文行会定位到对应源码行。
  • 搜索编辑器最多覆盖 100 个文件和 10,000 个匹配行;达到限制时在快照中显示截断提示。仅路径匹配的文件和因超过 2 MB 而未搜索正文的路径仍可列出并打开。
  • 每个笔记库保存最多 20 个最近文件和 100 个收藏。
  • Ctrl/Command+P 打开类似 VS Code 的文件快速打开面板。
  • Ctrl+R 在所有平台(包括 macOS)打开使用相同交互样式的最近笔记库面板,可按名称或完整路径模糊筛选;该操作也注册为命令面板中的 workspace.openRecent 命令,macOS 的 Command+R 保留给重新加载。
  • View 菜单的“用 VS Code 打开当前仓库”注册为 workspace.openInVSCode 命令,可从命令面板执行,也可在快捷键设置中修改或添加自定义绑定;默认快捷键为 Alt+Shift+V
  • 普通快速打开支持按文件名或相对路径进行模糊、多词匹配,空查询优先显示最近文件。
  • 输入 @ 后搜索全库持久大纲,输入 @@ 后搜索当前编辑内容的即时大纲;未保存标题只会出现在 @@ 结果中。
  • 文件名、标题和路径均支持中文原文、无声调全拼、拼音首字母以及空格分隔的混合关键词。
  • 搜索结果以亮蓝色粗体高亮文件名、标题和路径中的匹配字符,支持不连续的模糊匹配;全拼和首字母匹配高亮对应汉字,空查询不高亮。
  • 全拼仅支持精确、前缀和连续子串匹配,不再按分散在多个音节中的字母进行跳字匹配,避免短关键词误命中无关结果。
  • 中文原文和拼音首字母仍支持按字符顺序跳字的模糊匹配;纯英文名称也保留这一行为。
  • 上述匹配规则同时适用于普通文件快速打开、@ 全库大纲和 @@ 当前文件大纲。
  • 大纲结果显示文件路径、标题层级和源码行号,确认后打开或激活文件并将对应源码行定位到顶部。
  • 启动、切换仓库和普通刷新会在后台比较文件修改时间与大小并增量更新 .mynote/outline-index-v1.json;更新期间 Quick Open 明确标记缓存仍在刷新。
  • 后台大纲索引状态变化会原位刷新已打开的全库大纲搜索,并保留用户当前选择的结果;若该结果已不存在,则保留最接近的结果位置。
  • 侧栏“重建索引”会忽略缓存元数据并重新解析全部受管理 Markdown;损坏或未知版本的索引会保留为诊断副本后自动重建。
  • 面板支持方向键选择、Enter 打开和 Escape 关闭。
  • Quick Open 关闭后恢复原先 textarea 或 input 的焦点、光标位置和选区方向;确认结果时先恢复输入位置,再由打开文件或跳转大纲设置目标位置。
  • 中文等输入法正在组合文字时,Enter 和方向键由输入法处理,不会误选并打开文件。

工作区状态保存在 Electron userData/workspace-state.json,使用原子写入。正文和附件始终保留在用户的普通文件夹中。

基础设置

设置对话框当前支持:

  • 编辑器字号,范围 12–24 px。

  • 未记录预览显示状态时,使用设置中的默认预览状态。

  • 侧栏、编辑区、预览区和大纲的显示开关自动保存在本机,重启应用及刷新或切换笔记库后恢复上次选择。

  • 搜索标签页的临时面板布局不会覆盖已保存的显示状态。

  • 保存设置时,预览默认显示选项也会更新当前及记住的预览显示状态。

  • 单击或使用 Enter/Space 激活大纲节点后是否把键盘焦点转移到编辑器。

  • 使用方向键或 Home/End 导航大纲时是否即时跳转,默认开启。

  • 外部冲突工具的可执行文件绝对路径和参数模板。

    • 参数支持 %local%remote%base%merged 四个占位符。
    • 应用将占位符替换结果作为独立参数直接启动程序,不经过 shell。
    • Beyond Compare 在 macOS 上应配置 /Applications/Beyond Compare.app/Contents/MacOS/bcomp
    • 若已有配置指向同目录的 BCompare 主程序,启动时会自动改用 bcomp 命令行桥接程序。
  • 设置与最近记录跨应用重启保留。

  • “取消”按钮或 Escape 关闭设置窗口时会丢弃未保存的表单修改,再次打开会显示最后一次已保存的配置。

性能基准

运行:

npm run benchmark:workspace

基准会创建 1000 个小型 Markdown 文件,测量目录扫描、首次正文搜索和缓存搜索。2026-08-14 开发环境的多次运行参考范围:

  • 扫描约 130–180 ms。
  • 首次搜索约 470–1200 ms。
  • 缓存搜索约 160–420 ms。

结果用于比较相对回退,不作为所有设备的硬性 SLA。当真实笔记库规模或延迟超过当前方案能力时,再评估 SQLite FTS。

自动化覆盖

  • 工作区扫描、文件读取、新建文件和文件夹。
  • 搜索、最近记录、收藏、设置持久化。
  • 外部删除笔记库后的失效选择清理与界面降级。
  • 重命名、移动、复制和系统回收站调用。
  • 文件操作及跨文档剪贴板中的 Markdown 相对图片路径重写。
  • 路径穿越、符号链接逃逸、名称冲突和递归移动拒绝。
  • 打开文档迁移后的状态更新。
  • Electron 冒烟测试覆盖工作区恢复、目录树、搜索和打开文件。
  • Electron 冒烟测试通过真实按钮点击覆盖新建文件、新建文件夹与手动刷新反馈。
  • 目录树选中态与键盘焦点在文件夹展开后保持;鼠标右键、Shift+F10、菜单聚焦与方向键导航均有自动化覆盖。
  • 目录树与非活动标签页的路径复制覆盖右键菜单、动态快捷键提示、绝对路径的原生分隔符以及跨平台相对路径快捷键。
  • 同步冲突的任一 Markdown.baseMarkdown.localMarkdown.remote 存在时,目录树在原 Markdown 旁显示警告标记。用户完成手动编辑后,可通过原文件右键菜单清理三个临时版本;临时版本本身不作为工作区 Markdown 节点或同步文件显示。
  • 同一冲突状态也会标记已打开文件的标签和左上角仓库名。只要仓库内仍有冲突版本,手动同步与后台自动同步都会被阻止;用户点击同步操作时会收到先处理冲突的提示。
  • 三个同步冲突版本完整且已配置工具时,原文件右键菜单可启动外部三方合并程序。程序路径必须是可执行文件,四个版本路径逐项替换参数占位符,文件名中的空格不会触发参数拆分或 shell 展开。
  • 目录树的上下移动、父子级导航、展开收起、首尾跳转和键盘打开文件均有自动化覆盖。
  • 文档大纲覆盖标题层级提取、代码块排除、实时更新、面板切换、跳转后顶部定位、导航即时跳转开关、双击聚焦、View 菜单快捷键聚焦和完整键盘导航。

人工平台验证

发布前仍需在 Windows/macOS 测试制品上检查:

  1. 系统文件夹对话框与最近笔记库切换。
  2. 中文、空格、长路径和只读目录。
  3. 回收站中的恢复操作。
  4. 文件夹跨层级移动及含附件目录的复制。
  5. 外部程序修改目录结构后手动刷新。
  6. 1000–10000 文件笔记库的滚动和搜索体验。
  • Search Open in Editor 自动高亮所有源码匹配位置(包括同一行的多次匹配);修改查询或切换上下文后同步更新,滚动时保持对齐,保留原生文本选择和页内查找。

  • 全文搜索、Search Open in Editor 和当前文件查找(编辑区及预览区)提供 Aa(区分大小写)与 Ab(全字匹配)开关,默认均关闭,可组合使用。

  • 全文搜索选项同时作用于文件路径和正文;打开搜索结果编辑器时继承选项,编辑器内可独立调整并自动刷新结果及全部匹配高亮。

  • 全字匹配要求查询前后不紧邻 Unicode 字母、组合标记、数字或下划线;例如 cat 不匹配 scattercat2cat_,中文连续字串也按此边界规则处理。

  • 全文搜索输入框聚焦时,按 Alt+Enter 在编辑器中打开当前搜索结果,继承大小写和全字匹配选项;空查询或正在打开结果时不会重复触发。

  • Ctrl/Cmd+Shift+F 显示侧边栏并聚焦“在文件中查找”;Ctrl/Cmd+Shift+R 同时展开替换输入并聚焦“在文件中替换”。两个命令均可在命令面板和快捷键设置中使用。

  • 全部替换仅修改 Markdown 正文匹配,不修改仅因路径命中的文件名。大小写和全字匹配选项与全文查找共享;写盘前通过应用内对话框确认影响文件数和替换数。

  • 全部替换使用原子写盘并保留 UTF-8 BOM 和 LF/CRLF 换行风格;命中已打开文件存在未保存修改时会阻止批量写盘,并要求先保存。成功后同步更新已打开文件、全文搜索结果、搜索编辑器和大纲索引。

  • 全文搜索栏、Search Open in Editor 查询栏、编辑区和预览区的当前文件查找栏统一支持 Alt+C 切换大小写敏感、Alt+W 切换全字匹配;焦点位于相应栏的输入框或按钮时生效,仅更新该搜索栏的选项和结果。

  • npm run test:smoke:workspace-search 在真实 Electron 渲染器中覆盖全文查找/替换快捷键、搜索编辑器、写盘替换、已打开文件刷新与恢复原文。

phase-1-reliability

phase-5-hosted-sync-beta

点赞(0) 阅读(13) 举报
目录
标题