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

引用与反向查找实现

本文记录笔记库内 Markdown 文件引用的生成、插入和反向查找实现。用户可见的操作规则以 功能说明 和 引用查找 为准。

引用生成

入口与目标

  • 标签、文件树右键菜单和命令面板调用 src/renderer/runtime/outline-path-copy.mts。
  • 仅已保存、位于当前笔记库内的 Markdown 文件可作为引用目标。支持 .md、.markdown、.mdown 和 .mkd。
  • “复制引用”由 workspaceDocumentMarkdownLink 生成文件顶部链接;“复制引用(大纲)”由 workspaceOutlineMarkdownLink 生成标题链接。这两个函数位于 src/renderer/workspace/path-copy.mts。
  • 快速打开中的 Ctrl/Cmd+Enter 插入引用复用同一组链接构造函数,入口在 src/renderer/runtime/quick-open-actions.mts。标题结果先从已打开编辑器或磁盘取得正文,再根据匹配的标题行计算片段。

文件路径和标题锚点

  • 链接目的地以 / 开头,表示笔记库根相对路径。路径逐段做 URI 编码,链接文字转义反斜杠和方括号。
  • 大纲引用根据目标文档保留的 caret 位置,选择该位置或之前最近的 Markdown 标题。反向选择使用活动选择端。
  • headingAtCaret 使用 extractMarkdownOutline 提取标题,再用 markdownHeadingFragments 生成片段;重复标题得到 -1、-2 等唯一后缀。中文等字母和数字在片段中保持可读,特殊字符编码。
  • 文件未打开、caret 位于首个标题之前或没有标题时,大纲复制退化为文件链接。复制只写剪贴板,不改变编辑器位置或导航历史。
  • 生成结果示例:[目标.md](/目录/目标.md)、[章节](/目录/目标.md#章节)。

反向查找调用链

  1. src/renderer/runtime/references.mts 的 findContextReferences 从标签、文件树或当前文档确定目标。findReferencesForPath 对“当前标题”模式调用 headingAtCaret;没有可用标题时查询整个文件。
  2. 渲染进程创建或复用一个 reportType: 'references' 的只读报告标签。referenceBuffers 读取当前窗口所有已打开、已命名 Markdown 页面的实时正文,不触发保存;未打开文件由主进程从磁盘读取。
  3. refreshReferenceReport 经预加载层的 findWorkspaceReferences 调用 workspace:find-references IPC。主进程的 src/main/workspace-handlers.ts 传入当前笔记库根路径及文件清单,src/main/references.ts 执行扫描。
  4. src/renderer/search/references.mts 把结果转换成只读文本、逐行导航目标和目的地高亮范围。报告按来源文件分组,列出每处链接的行号、目的地和源码行。

扫描与匹配

  • 主进程先校验请求、Markdown 扩展名、目标是否属于文件清单,以及缓冲区快照的路径和类型。请求最多携带 10,000 个缓冲区;标题片段最长 10,000 字符。
  • 目标和每个来源都经 realpath 检查,拒绝越出笔记库的路径和符号链接。即使来源正文来自渲染进程快照,也必须通过真实路径检查。
  • 扫描范围是当前笔记库文件清单中的 Markdown 文件,按清单顺序逐个读取。已打开文件用请求时的正文快照覆盖磁盘内容。
  • 链接解析复用 src/main/broken-links.ts 的 parseMarkdownLinks 和 decodeDestination:识别 Markdown 行内链接、引用式链接、HTML href;代码围栏及行内代码不会产生链接。图片、外部地址、无效 URI 编码不计入结果。
  • 相对路径、笔记库根路径及空路径的同文件锚点由 resolveWorkspaceMarkdownLink 解析。最终比较真实文件路径;Windows 上路径比较忽略大小写。
  • 文件查询统计指向该文件的全部链接,包括带标题片段的链接。标题查询先在目标当前正文中确定标题行,再把每处链接的片段解析为标题行;只有同一标题行才匹配,因此重复标题的唯一锚点可以区分。
  • 同一源码行的多个链接各计一次。最多收集 10,000 处;超限设置 truncated。单个来源读取失败会记录在 failures 并继续扫描;目标不存在或指定标题已消失则整个请求报错。

报告生命周期与导航

  • 报告是一次查询快照。点击“刷新引用”重新收集打开文档正文并扫描;普通输入不会自动刷新。
  • 每次刷新递增报告的请求令牌。异步响应仅在笔记库未切换、报告仍存在且令牌仍为当前值时写入,避免旧结果覆盖新查询。
  • 结果行与来源文件、行号关联。双击打开来源并进入现有前进/后退历史;F4 和 Shift+F4 在各处引用间循环。导航仍指向来源行,不选中链接文字。
  • 报告不保存为普通笔记,也不写回来源文件。引用跳转的历史机制另见 编辑器导航历史。

验证入口

  • node scripts/run.mts node --test test/references.test.js 覆盖路径解析、标题锚点、重复引用、未保存快照、无效请求、读取失败、结果上限及符号链接逃逸。
  • npm run test:smoke:references 覆盖界面查找、报告导航、刷新和失效链接报告流程。

phase-5-hosted-sync-beta

renderer-development

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