- 知识管理
- 知识库
- 开发工具
- MCP 服务
【免费下载链接】foam
A personal knowledge management and sharing system for VSCode
导读
Smart Folders(智能文件夹)是 Foam 在 VS Code 资源管理器中呈现"已保存查询"的方式:每个智能文件夹都是一个存放在.foam/queries/<id>.yaml下的查询文件,按需实时执行并把匹配到的笔记以树形或列表形式展示在侧边栏。本文将以 docs/user/features/smart-folders.md 为核心,结合foam-vscode与foam-core的源码实现,系统讲解智能文件夹的创建、编辑、删除、视图选项,以及底层查询语法与存储机制,帮助你在大规模工作区中摆脱僵化的标签层级,用查询代替手动的目录组织。
Smart Folders 是什么
Smart Folders 的核心思想是:文件夹不存储文件,只存储"筛选条件"。它由三部分组成:
- 一个 YAML 查询文件(位于工作区
.foam/queries/目录,文件名即查询 id); - Foam 查询引擎(
@foam/core中的executeQuery)——按查询描述符在工作区中筛选笔记; - VS Code 树视图(
SmartFoldersProvider)——把匹配结果渲染到侧边栏。
典型场景是:创建一个名为 "Work in Progress" 的智能文件夹,只显示打了#wip标签、且没有#archive标签的笔记,见 foam-queries 中保存查询的示例。这样笔记物理上可以分散在任何目录,但视图上始终聚合在同一个逻辑分组下,非常适合跨目录检索大型工作区。
从源码结构看,智能文件夹与内联查询(foam-query代码块)共享同一套查询语法和引擎:saved-store.ts 中的QueryStore负责读写.foam/queries/下的 YAML 文件,而树视图直接调用@foam/core的executeQuery执行查询(见 smart-folders-explorer.ts),因此"保存的查询"和"内联查询"可以互相复制、完全等价。
创建 Smart Folder
通过面板或命令创建
创建智能文件夹有两种入口(见 create-smart-folder.ts):
- 打开资源管理器中的Smart Folders面板,点击Create Smart Folder(对应命令
foam-vscode.views.smart-folders.create); - 或在命令面板运行Foam: Create Smart Folder。
创建流程分两步交互:
- 输入名称(例如
Work in Progress); - 多选要包含的标签(可选,按 Esc 跳过,直接进入 YAML 手动编辑)。
完成后 Foam 会在.foam/queries/<name>.yaml生成查询文件并自动打开编辑。
名称如何变成文件名
输入的名称会先经过sanitizeQueryId处理成文件系统安全 id(实现见 saved.ts):
- 全部转小写;
- 空白与非法字符替换为
-; - 去掉首尾的
-,合并连续-。
例如Work in Progress→work-in-progress.yaml,research/animals→research-animals.yaml。如果生成的 id 已存在,创建逻辑会自动追加序号(-2、-3……)直到不冲突(见 create-smart-folder.ts)。若名称无法产生有效 id(例如只含符号),Foam 会提示改用字母、数字、连字符或下划线。
标签选择背后的过滤逻辑
多选标签后,Foam 会构建一个"或"过滤器(buildOrFilter):
- 只选 1 个标签 →
filter: { tag: "#wip" }; - 选择多个标签 →
filter: { or: [ { tag: "#a" }, { tag: "#b" } ] },即匹配任意一个所选标签的笔记都会出现; - 工作区没有任何标签,或按 Esc 跳过选择 → 生成
filter: "*"(匹配全部笔记),留待你在 YAML 中细化。
生成的文件随后通过QueryStore.save写入磁盘(见 saved-store.ts),文件名由 id 决定,因此重命名文件即重命名查询。
编辑 Smart Folder
编辑有两种方式:
- 点击面板中智能文件夹旁边的铅笔图标(命令
foam-vscode.views.smart-folders.edit),会自动打开对应的 YAML 文件; - 直接打开
.foam/queries/<id>.yaml手动编辑。
改动会自动生效:SmartFolderStorage为.foam/queries/*.{yaml,yml}注册了FileSystemWatcher,文件创建、修改、删除都会触发树视图刷新(见 smart-folder-storage.ts 与 index.ts)。此外,工作区图谱(foam.graph)的更新同样会触发刷新,因此笔记标签、链接变化后智能文件夹的结果也会随之更新。
YAML 文件结构
一个保存的查询文件把查询字段直接放在 YAML 根级,可选两个包装字段:
name: Work in Progress # 可选;缺省时由文件名转成人类可读形式 description: Notes I am editing # 可选 filter: and: - tag: "#wip" - not: tag: "#archive" sort: title ASC limit: 50最简有效文件只需一行:filter: "#wip"。
字段说明(完整语法见 foam-queries):
filter:选择包含哪些笔记;select:选择展示哪些字段(默认title和path);sort:排序,例如title ASC或backlink-count DESC;被排序的字段需同时出现在select中,否则投影后不可用;limit/offset:限制返回条数 / 跳过前 n 条;format:list、table或count。
从解析器源码(saved.ts)看,根级只允许name、description以及filter、select、sort、limit、offset、format这些字段,出现未知字段会被记为解析警告(warning 而非硬错误),并在树视图中以"errors"条目呈现。
filter 支持的筛选键
tag:拥有该标签的笔记(如tag: "#research");type:指定类型的笔记(如type: "daily-note");path:路径匹配正则的笔记(如path: "^/projects/");title:标题匹配正则的笔记;links_to/links_from:链接到 / 被链接自某笔记 id 的笔记,可用"$current"指代当前笔记;jexl:针对每条笔记求值的 Jexl 表达式(如"resource.tags|length > 2"),可访问resource对象及length、lower、upper等内建变换;and/or/not:逻辑组合;- 简单快捷形式:
"#tag"、"[[note-id]]"、"/regex/"、"*"(全部笔记)。
删除 Smart Folder
点击智能文件夹旁的垃圾桶图标并确认即可删除,对应的 YAML 文件会被移除。源码实现(create-smart-folder.ts)会先弹出模态确认框,只有选择Delete才调用storage.delete(id);QueryStore.delete会检查文件存在再删除(见 saved-store.ts)。删除后FileSystemWatcher的onDidDelete事件会清掉内存缓存并刷新视图。
视图选项
面板标题栏提供两个开关:
- Group By Folder / Flat list:把匹配的笔记按工作区路径分组为目录树,或以扁平列表展示。该偏好通过
ContextMemento持久化在foam-vscode.views.smart-folders.group-by状态中(默认folder,见 smart-folders-explorer.ts),由命令foam-vscode.views.smart-folders.group-by:folder和group-by:off控制; - Refresh:按需重新执行所有查询。
refresh()会清空结果缓存(uriCache)并重建树(见 smart-folders-explorer.ts)。
树视图本身由SmartFoldersProvider驱动(smart-folders-explorer.ts),其行为要点:
- 顶层条目:每个已保存查询一个条目,图标为
folder-library,描述显示匹配笔记数;若文件存在解析错误,则显示为带警告图标、描述为errors的SmartFolderErrorTreeItem,点击可直接打开查询文件(见 smart-folders-explorer.ts); - 分组模式:
buildFolderTree把匹配 URI 按工作区相对路径拆分为嵌套目录节点,每个目录节点显示叶子数,子项按名称排序(smart-folders-explorer.ts); - 错误隔离:单个查询执行失败不会拖垮整个面板——异常被捕获并记录日志,该文件夹显示为空结果(对应测试见 smart-folders-explorer.spec.ts);
- 信任工作区:查询可包含 Jexl 表达式,仅在受信任(trusted)工作区执行,与
foam-query块的信任门槛一致,未信任时默认() => false保证安全(见 smart-folders-explorer.ts)。
底层存储与文件约定
理解以下几点可以更安全地手工管理智能文件夹:
- 目录与扩展名:查询文件固定存放在
.foam/queries/,glob 为*.{yaml,yml}(常量QUERIES_GLOB,见 saved-store.ts);注意这是查询专用目录,Foam 普通笔记数据存储通常只覆盖**/*.md,不会误扫到这些 YAML; - id 来自文件名:查询 id 由文件名(去掉
.yaml/.yml扩展名)推导(idFromQueryFilename),不写在 YAML 内容里;重命名文件即重命名查询(见 saved.ts); - 显示名缺省规则:YAML 中省略
name时,显示名由 id 经humanizeQueryId自动生成,例如work-in-progress→Work In Progress;序列化时若name与缺省值相同会被省略(saved.ts); - 缓存与观察:
SmartFolderStorage在内存中缓存解析结果,配合FileSystemWatcher增量更新,避免每次刷新重读所有 YAML(smart-folder-storage.ts);查询执行结果也有uriCache,在每次refresh()时清空(smart-folders-explorer.ts)。
与 Foam Queries 的关系
智能文件夹与 Foam Queries 是同一能力的两种形态:
- 内联形态:在笔记中写
foam-query代码块,结果渲染在 Markdown 预览中; - 持久形态:把同样的字段写入
.foam/queries/下的 YAML,侧边栏的 Smart Folders 面板即为其展示层。
两者的语法完全一致,保存的查询文件与内联块可以互相复制。区别在于渲染位置与用途:智能文件夹适合常驻侧边栏的"工作视图"(如进行中的项目、待办聚合),内联查询适合放在某篇笔记里按需展示。若需要把查询结果嵌入到其他笔记,可参考 embeds。
小结
Smart Folders 把"组织笔记"从手工建目录、维护层级,转变为编写并保存查询:创建、编辑、删除、视图切换四个核心操作均可在面板内完成,所有改动即时生效;底层由foam-core的QueryStore+executeQuery与foam-vscode的树视图、文件监听器协作实现。掌握 查询语法(filter 组合、排序、limit、Jexl 表达式等),即可组合出如"#wip且非#archive""指向某主题的所有笔记""按回链数排序的 TOP 10"等动态视图,让侧边栏真正反映笔记内容而非目录结构。
- 知识管理
- 知识库
- 开发工具
- MCP 服务
【免费下载链接】foam
A personal knowledge management and sharing system for VSCode
相关推荐
i茅台自动预约神器:5分钟快速上手的完整指南
i茅台自动预约神器:5分钟快速上手的完整指南 还在为每天手动预约茅台而烦恼吗?还在担心错过预约时间而遗憾不已吗?这款i茅台自动预约系统将彻底解放你的双手,让茅台
后端前端任务调度工作流自动化VS Code 侧边栏看不到 Kilo Code 图标怎么排查?
VS Code 侧边栏看不到 Kilo Code 图标怎么排查? 安装完 Kilo Code 扩展后,最常见的“失踪”现象是:在 VS Code 左侧(Prim
人工智能大模型AI Agent代码智能体工具调用交互助手CLI如何用GTweak优化网络?从协议到防火墙的完整流程
如何用GTweak优化网络?从协议到防火墙的完整流程 GTweak 是一款免费的便携式 Windows 优化工具,无需安装即可一键完成网络优化、系统清理和隐私设
桌面应用
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考