这是一个用Lua编写的Neovim插件,用于编写和浏览Obsidian知识库。
专为那些热爱Obsidian概念 —— 一个简单的、基于markdown的笔记应用 —— 但又过于热爱Neovim以至于无法忍受在其他任何地方输入字符的人而设计。
如果你是Obsidian新手,我强烈推荐观看这个优秀的YouTube视频,它提供了一个很好的概览。
请记住,这个插件并不是要取代Obsidian,而是要补充它。Obsidian应用本身非常强大;它有移动应用,并且具有许多在Neovim中难以实现的功能,比如图形浏览视图。尽管如此,这个插件本身也很强大。你不一定需要与Obsidian应用一起使用它。
▶️ 自动补全: 通过nvim-cmp提供超快速、异步的笔记引用和标签自动补全(通过输入[[触发wiki链接,[触发markdown链接,或#触发标签),由ripgrep提供支持。
🏃 导航: 在任何指向另一个笔记的链接上输入gf即可在整个知识库中导航。
📷 图片: 将图片粘贴到笔记中。
💅 语法: 为引用、标签和复选框提供额外的markdown语法高亮、隐藏和扩展标记。
:ObsidianOpen [查询] 在Obsidian应用中打开一个笔记。
此命令有一个可选参数:用于通过ID、路径或别名解析要打开的笔记的查询。如果未提供,将打开当前缓冲区对应的笔记。
:ObsidianNew [标题] 创建一个新笔记。
此命令有一个可选参数:新笔记的标题。
:ObsidianQuickSwitch 快速切换到(或打开)知识库中的另一个笔记,使用ripgrep通过名称搜索,并使用你偏好的选择器(参见下面的插件依赖)。
:ObsidianFollowLink [vsplit|hsplit] 跟随光标下的笔记引用,可选择在垂直或水平分割窗口中打开。
:ObsidianBacklinks 获取当前缓冲区的引用列表选择器。
:ObsidianTags [标签 ...] 获取给定标签的所有出现的列表选择器。
:ObsidianToday [偏移量] 打开/创建一个新的每日笔记。此命令还接受一个可选的天数偏移量,例如使用:ObsidianToday -1可以转到昨天的笔记。与:ObsidianYesterday和:ObsidianTomorrow不同,此命令不区分工作日和周末。
:ObsidianYesterday 打开/创建上一个工作日的每日笔记。
:ObsidianTomorrow 打开/创建下一个工作日的每日笔记。
:ObsidianDailies [偏移量 ...] 打开每日笔记的列表选择器。例如,:ObsidianDailies -2 1列出从2天前到明天的每日笔记。
:ObsidianTemplate [名称] 从模板文件夹插入一个模板,使用你偏好的选择器从列表中选择。更多信息请参见"使用模板"。
:ObsidianSearch [查询] 使用ripgrep和你偏好的选择器在你的知识库中搜索(或创建)笔记。
:ObsidianLink [查询] 将内联可视选择的文本链接到一个笔记。
此命令有一个可选参数:用于通过ID、路径或别名解析笔记的查询。如果未提供,将使用选中的文本作为查询。
:ObsidianLinkNew [标题] 创建一个新笔记并将其链接到内联可视选择的文本。
此命令有一个可选参数:新笔记的标题。如果未提供,将使用选中的文本作为标题。
:ObsidianLinks 将当前缓冲区中的所有链接收集到一个选择器窗口中。
:ObsidianExtractNote [标题] 将可视选择的文本提取到一个新笔记中并链接到它。
:ObsidianWorkspace [名称] 切换到另一个工作区。
:ObsidianPasteImg [图片名称] 将剪贴板中的图片粘贴到光标位置的笔记中,通过将其保存到知识库并添加一个markdown图片链接。你可以使用attachments.img_folder选项配置保存图片的默认文件夹。
:ObsidianRename [新名称] [--dry-run] 用于重命名当前缓冲区的笔记或光标下的引用,并更新整个知识库中的所有反向链接。由于这个命令还相对较新,可能会对您的知识库进行大量修改,我强烈建议在运行之前提交知识库的当前状态(如果您使用版本控制的话),或者先通过在命令末尾添加"--dry-run"进行试运行,例如 :ObsidianRename new-id --dry-run。
:ObsidianToggleCheckbox 用于循环切换复选框选项。
:ObsidianNewFromTemplate [标题] 用于从模板文件夹中的模板创建新笔记。使用您首选的选择器从列表中选择。
此命令有一个可选参数:新笔记的标题。
:ObsidianTOC 用于将当前笔记的目录加载到选择器列表中。
vim.fs,该功能仅在0.8版本中添加)。$PATH中。
安装选项请参见ripgrep#installation。某些特定操作系统还需要额外的依赖项才能使用obsidian.nvim的全部功能:
wsl-open来使用:ObsidianOpen命令。pngpaste(brew install pngpaste)来使用:ObsidianPasteImg命令。:ObsidianPasteImg命令。搜索功能(例如通过:ObsidianSearch和:ObsidianQuickSwitch命令)还需要一个选择器,如telescope.nvim(参见下面的插件依赖)。
要配置obsidian.nvim,您只需要使用所需的选项调用require("obsidian").setup({ ... })。
以下是使用不同插件管理器的一些示例。完整的插件依赖和配置选项列表如下。
⚠️ 警告:如果您从最新发布版本安装(推荐以获得稳定性),而不是从
main分支安装,请注意main分支上的README可能会引用尚未发布的功能。因此,我建议查看最新发布版本标签上的README,而不是main分支。
lazy.nvimreturn { "epwalsh/obsidian.nvim", version = "*", -- 推荐,使用最新发布版本而不是最新提交 lazy = true, ft = "markdown", -- 如果您只想为知识库中的markdown文件加载obsidian.nvim,请将上面的行替换为以下内容: -- event = { -- -- 如果您想在这里使用主目录快捷方式'~',需要调用'vim.fn.expand'。 -- -- 例如 "BufReadPre " .. vim.fn.expand "~" .. "/my-vault/*.md" -- -- 更多示例请参考`:h file-pattern` -- "BufReadPre path/to/my-vault/*.md", -- "BufNewFile path/to/my-vault/*.md", -- }, dependencies = { -- 必需。 "nvim-lua/plenary.nvim", -- 完整的可选依赖列表见下方 👇 }, opts = { workspaces = { { name = "personal", path = "~/vaults/personal", }, { name = "work", path = "~/vaults/work", }, }, -- 完整的选项列表见下方 👇 }, }
packer.nvimuse({ "epwalsh/obsidian.nvim", tag = "*", -- 推荐,使用最新发布版本而不是最新提交 requires = { -- 必需。 "nvim-lua/plenary.nvim", -- 完整的可选依赖列表见下方 👇 }, config = function() require("obsidian").setup({ workspaces = { { name = "personal", path = "~/vaults/personal", }, { name = "work", path = "~/vaults/work", }, }, -- 完整的选项列表见下方 👇 }) end, })
唯一必需的插件依赖是plenary.nvim,但还有一些可选依赖可以增强obsidian.nvim的体验。
补全:
选择器:
语法高亮:
其他:
如果您选择使用这些插件中的任何一个,应该将它们包含在插件管理器的obsidian.nvim插件规范的"dependencies"或"requires"字段中。
以下是可以传递给require("obsidian").setup()的所有选项的完整列表。以下设置不一定是默认值,但代表了合理的默认设置。请仔细阅读 每个选项并根据您的需求进行自定义:
{ -- 工作区名称、路径和配置覆盖的列表。 -- 如果您使用Obsidian应用程序,工作区的'path'通常应该是 -- 您的知识库根目录(.obsidian文件夹所在的位置)。 -- 当插件管理器加载obsidian.nvim时,它会自动将工作区 -- 设置为列表中第一个'path'是当前正在编辑的markdown文件 -- 父目录的工作区。 workspaces = { { name = "personal", path = "~/vaults/personal", }, { name = "work", path = "~/vaults/work", -- 可选,覆盖某些设置。 overrides = { notes_subdir = "notes", }, }, }, -- 或者 - 为了向后兼容 - 您可以将'dir'设置为单一路径,而不是 -- 'workspaces'。例如: -- dir = "~/vaults/work", -- 可选,如果您将笔记保存在知识库的特定子目录中。 notes_subdir = "notes", -- 可选,设置obsidian.nvim的日志级别。这是一个对应于vim.log.levels.*定义的 -- 日志级别之一的整数。 log_level = vim.log.levels.INFO, }
daily_notes = { -- 可选,如果你将每日笔记存放在单独的目录中。 folder = "notes/dailies", -- 可选,如果你想更改每日笔记ID的日期格式。 date_format = "%Y-%m-%d", -- 可选,如果你想更改每日笔记默认别名的日期格式。 alias_format = "%B %-d, %Y", -- 可选,为每个新创建的每日笔记添加的默认标签。 default_tags = { "daily-notes" }, -- 可选,如果你想自动插入模板目录中的模板,如'daily.md' template = nil },
-- 可选,使用nvim-cmp完成wiki链接、本地markdown链接和标签。 completion = { -- 设置为false以禁用完成功能。 nvim_cmp = true, -- 在2个字符时触发完成。 min_chars = 2, },
-- 可选,配置按键映射。这些是默认设置。如果你不想以这种方式设置任何按键映射, -- 则设置'mappings = {}'。 mappings = { -- 覆盖'gf'映射,以在你的知识库内的markdown/wiki链接上工作。 ["gf"] = { action = function() return require("obsidian").util.gf_passthrough() end, opts = { noremap = false, expr = true, buffer = true }, }, -- 切换复选框。 ["<leader>ch"] = { action = function() return require("obsidian").util.toggle_checkbox() end, opts = { buffer = true }, }, -- 根据上下文进行智能操作,要么跟随链接,要么切换复选框。 ["<cr>"] = { action = function() return require("obsidian").util.smart_action() end, opts = { buffer = true, expr = true }, } },
-- 放置新笔记的位置。有效选项为 -- * "current_dir" - 将新笔记放在当前缓冲区所在的目录中。 -- * "notes_subdir" - 将新笔记放在默认的笔记子目录中。 new_notes_location = "notes_subdir",
-- 可选,自定义如何根据可选标题生成笔记ID。 ---@param title string|? ---@return string note_id_func = function(title) -- 以Zettelkasten格式创建笔记ID,包含时间戳和后缀。 -- 在这种情况下,标题为'My new note'的笔记将被赋予一个看起来 -- 像'1657296016-my-new-note'的ID,因此文件名为'1657296016-my-new-note.md' local suffix = "" if title ~= nil then -- 如果给定标题,将其转换为有效的文件名。 suffix = title:gsub(" ", "-"):gsub("[^A-Za-z0-9-]", ""):lower() else -- 如果标题为nil,只需在后缀中添加4个随机大写字母。 for _ = 1, 4 do suffix = suffix .. string.char(math.random(65, 90)) end end return tostring(os.time()) .. "-" .. suffix end,
-- 可选,自定义如何根据ID、目标目录和标题生成笔记文件名。 ---@param spec { id: string, dir: obsidian.Path, title: string|? } ---@return string|obsidian.Path 新笔记的完整路径。 note_path_func = function(spec) -- 这等同于默认行为。 local path = spec.dir / tostring(spec.id) return path:with_suffix(".md") end,
-- 可选,自定义wiki链接的格式。你可以将其设置为以下之一: -- * "use_alias_only", 例如 '[[Foo Bar]]' -- * "prepend_note_id", 例如 '[[foo-bar|Foo Bar]]' -- * "prepend_note_path", 例如 '[[foo-bar.md|Foo Bar]]' -- * "use_path_only", 例如 '[[foo-bar.md]]' -- 或者你可以将其设置为一个接收选项表并返回字符串的函数,如下所示: wiki_link_func = function(opts) return require("obsidian.util").wiki_link_id_prefix(opts) end,
-- 可选,自定义markdown链接的格式。 markdown_link_func = function(opts) return require("obsidian.util").markdown_link(opts) end,
-- 'wiki'或'markdown'。 preferred_link_style = "wiki",
-- 可选,布尔值或一个接收文件名并返回布尔值的函数。
-- true表示你不希望obsidian.nvim管理前置元数据。
disable_frontmatter = false,
-- 可选,或者你可以自定义前置元数据。 ---@return table note_frontmatter_func = function(note) -- 将笔记标题添加为别名。 if note.title then note:add_alias(note.title) end
local out = { id = note.id, aliases = note.aliases, tags = note.tags }
-- `note.metadata`包含任何手动添加到前置元数据中的字段。
-- 所以这里我们只是确保这些字段保留在前置元数据中。
if note.metadata ~= nil and not vim.tbl_isempty(note.metadata) then
for k, v in pairs(note.metadata) do
out[k] = v
end
end
return out
end,
-- 可选,用于模板(见下文)。 templates = { folder = "templates", date_format = "%Y-%m-%d", time_format = "%H:%M", -- 自定义变量的映射,键应为变量,值为函数 substitutions = {}, },
-- 可选,默认情况下,当你在外部URL的链接上使用:ObsidianFollowLink时,
-- 它会被忽略,但你可以在这里自定义这个行为。
---@param url string
follow_url_func = function(url)
-- 在默认网络浏览器中打开URL。
vim.fn.jobstart({"open", url}) -- Mac OS
-- vim.fn.jobstart({"xdg-open", url}) -- linux
-- vim.cmd(':silent exec "!start ' .. url .. '"') -- Windows
-- vim.ui.open(url) -- 需要Neovim 0.10.0+
end,
-- 可选,默认情况下,当你在图片文件的链接上使用:ObsidianFollowLink时,
-- 它会被忽略,但你可以在这里自定义这个行为。
---@param img string
follow_img_func = function(img)
vim.fn.jobstart { "qlmanage", "-p", img } -- Mac OS 快速查看预览
-- vim.fn.jobstart({"xdg-open", url}) -- linux
-- vim.cmd(':silent exec "!start ' .. url .. '"') -- Windows
end,
-- 可选,如果你使用Obsidian Advanced URI插件,设置为true。 -- https://github.com/Vinzent03/obsidian-advanced-uri use_advanced_uri = false,
-- 可选,设置为true以强制':ObsidianOpen'将应用程序置于前台。 open_app_foreground = false,
picker = { -- 设置你喜欢的选择器。可以是'telescope.nvim'、'fzf-lua'或'mini.pick'之一。 name = "telescope.nvim", -- 可选,为选择器配置按键映射。这些是默认设置。 -- 并非所有选择器都支持所有映射。 note_mappings = { -- 从你的查询创建一个新笔记。 new = "<C-x>", -- 插入所选笔记的链接。 insert_link = "<C-l>", }, tag_mappings = { -- 向当前笔记添加标签。 tag_note = "<C-x>", -- 在当前位置插入标签。 insert_tag = "<C-l>", }, },
-- 可选,按"path"、"modified"、"accessed"或"created"排序搜索结果。
-- 推荐值是"modified",并将sort_reversed设为true,这意味着,例如,
-- :ObsidianQuickSwitch将显示按最近修改时间排序的笔记
sort_by = "modified",
sort_reversed = true,
-- 设置执行某些搜索时从磁盘上读取笔记的最大行数。 search_max_lines = 1000,
-- 可选,决定某些命令如何打开笔记。有效选项是: -- 1. "current"(默认) - 始终在当前窗口中打开 -- 2. "vsplit" - 如果还没有垂直分割,则在垂直分割中打开 -- 3. "hsplit" - 如果还没有水平分割,则在水平分割中打开 open_notes_in = "current",
-- 可选,定义你自己的回调以进一步自定义行为。
callbacks = {
-- 在require("obsidian").setup()结束时运行。
---@param client obsidian.Client
post_setup = function(client) end,
},
-- 每次进入笔记缓冲区时运行。
---@param client obsidian.Client
---@param note obsidian.Note
enter_note = function(client, note) end,
-- 每次离开笔记缓冲区时运行。 ---@param client obsidian.Client ---@param note obsidian.Note leave_note = function(client, note) end,
-- 在写入笔记缓冲区之前运行。 ---@param client obsidian.Client ---@param note obsidian.Note pre_write_note = function(client, note) end,
-- 每次设置/更改工作区时运行。 ---@param client obsidian.Client ---@param workspace obsidian.Workspace post_set_workspace = function(client, workspace) end, },
-- 可选,配置额外的语法高亮/extmarks。
-- 这要求你将 conceallevel 设置为 1 或 2。详情请参见 :help conceallevel。
ui = {
enable = true, -- 设置为 false 以禁用所有额外的语法功能
update_debounce = 200, -- 文本更改后的更新延迟(毫秒)
max_file_length = 5000, -- 对超过此行数的文件禁用 UI 功能
-- 定义各种复选框的显示方式
checkboxes = {
-- 注意:'char' 值必须是单个字符,高亮组在下面定义。
[" "] = { char = "", hl_group = "ObsidianTodo" },
["x"] = { char = "", hl_group = "ObsidianDone" },
[">"] = { char = "", hl_group = "ObsidianRightArrow" },
["~"] = { char = "", hl_group = "ObsidianTilde" },
["!"] = { char = "", hl_group = "ObsidianImportant" },
-- 如果你没有补丁字体,请用以下内容替换上面的内容:
-- [" "] = { char = "☐", hl_group = "ObsidianTodo" },
-- ["x"] = { char = "✔", hl_group = "ObsidianDone" },
-- 你也可以添加更多自定义的...
},
-- 为非复选框列表使用项目符号标记。
bullets = { char = "•", hl_group = "ObsidianBullet" },
external_link_icon = { char = "", hl_group = "ObsidianExtLinkIcon" },
-- 如果你没有补丁字体,请用以下内容替换上面的内容:
-- external_link_icon = { char = "", hl_group = "ObsidianExtLinkIcon" },
reference_text = { hl_group = "ObsidianRefText" },
highlight_text = { hl_group = "ObsidianHighlightText" },
tags = { hl_group = "ObsidianTag" },
block_ids = { hl_group = "ObsidianBlockID" },
hl_groups = {
-- 这些选项直接传递给 vim.api.nvim_set_hl()。详见 :help nvim_set_hl。
ObsidianTodo = { bold = true, fg = "#f78c6c" },
ObsidianDone = { bold = true, fg = "#89ddff" },
ObsidianRightArrow = { bold = true, fg = "#f78c6c" },
ObsidianTilde = { bold = true, fg = "#ff5370" },
ObsidianImportant = { bold = true, fg = "#d73128" },
ObsidianBullet = { bold = true, fg = "#89ddff" },
ObsidianRefText = { underline = true, fg = "#c792ea" },
ObsidianExtLinkIcon = { fg = "#c792ea" },
ObsidianTag = { italic = true, fg = "#89ddff" },
ObsidianBlockID = { italic = true, fg = "#89ddff" },
ObsidianHighlightText = { bg = "#75662e" },
},
},
-- 指定如何处理附件。
attachments = {
-- :ObsidianPasteImg 命令放置图像的默认文件夹。
-- 如果这是一个相对路径,它将被解释为相对于保险库根目录。
-- 你可以通过传递完整路径而不是仅文件名来覆盖每个图像的设置。
img_folder = "assets/imgs", -- 这是默认值
-- 可选,自定义通过 :ObsidianPasteImg 粘贴图像时的默认名称或前缀。
---@return string
img_name_func = function()
-- 用时间戳为图像名称添加前缀。
return string.format("%s-", os.time())
end,
-- 一个函数,用于确定粘贴图像时插入到笔记中的文本。
-- 它接受两个参数,obsidian.Client 和图像文件的 obsidian.Path。
-- 这是默认实现。
---@param client obsidian.Client
---@param path obsidian.Path 图像文件的绝对路径
---@return string
img_text_func = function(client, path)
path = client:vault_relative_path(path) or path
return string.format("", path.name, path)
end,
},
}
### 配置说明
#### 工作区
对于大多数 Obsidian 用户来说,你在 obsidian.nvim 配置中配置的每个工作区应该对应一个唯一的 Obsidian 保险库,在这种情况下,每个工作区的 `path` 应该设置为相应的保险库根路径。
例如,假设你在 `~/vaults/personal` 有一个 Obsidian 保险库,那么配置中的 `workspaces` 字段应该如下所示:
```lua
config = {
workspaces = {
{
name = "personal",
path = "~/vaults/personal",
},
}
}
然而,obsidian.nvim 的工作区概念比保险库更加通用,因为配置一个不对应保险库的工作区,或为单个保险库配置多个工作区也是有效的。后一种情况在你想要将单个保险库分割成多个目录,并对每个目录应用不同的设置时很有用。例如:
config = { workspaces = { { name = "project-1", path = "~/vaults/personal/project-1", -- 这里的 `strict=true` 告诉 obsidian 使用 `path` 作为工作区/保险库根目录, -- 即使实际的 Obsidian 保险库根目录可能是 `~/vaults/personal/`。 strict = true, overrides = { -- ... }, }, { name = "project-2", path = "~/vaults/personal/project-2", strict = true, overrides = { -- ... }, }, } }
obsidian.nvim 还支持"动态"工作区。这些只是 path 设置为 Lua 函数(返回路径)而不是硬编码路径的工作区。这在多种情况下都很有用,比如当你想要一个 path 总是设置为当前缓冲区父目录的工作区时:
config = { workspaces = { { name = "buf-parent", path = function() return assert(vim.fs.dirname(vim.api.nvim_buf_get_name(0))) end, }, } }
当你想在"固定"保险库之外的 markdown 文件上使用此插件的部分功能时,动态工作区也很有用。 参见在工作区/Obsidian 保险库之外使用 obsidian.nvim。
当你在保险库目录内的 markdown 缓冲区中时,obsidian.nvim 会自动将自己设置为 nvim-cmp 源,你不需要手动指定此插件作为 cmp 源。
请注意,为了在 YAML 前置元数据中触发标签补全,你仍然需要在标签开始处输入 "#"。当你在标签补全项上按回车时,obsidian.nvim 会移除 "#"。
如果你使用 nvim-treesitter,你的配置应该包括 "markdown" 和 "markdown_inline" 两个源:
require("nvim-treesitter.configs").setup({ ensure_installed = { "markdown", "markdown_inline", ... }, highlight = { enable = true, }, })
如果你使用 vim-markdown,你可能想要禁用它的前置元数据语法高亮(vim.g.vim_markdown_frontmatter = 1),因为我发现它工作得不是很好。
如果你希望使用格式隐藏功能,你需要将 conceallevel 设置为允许的值(1 或 2),例如:
在 viml 中使用 set conceallevel=1 或在 lua 配置中使用 vim.opt.conceallevel = 1。
notes_subdir和note_id_func选项并不互斥。你可以同时使用它们。例如,使用上述两种设置的组合,一个名为"My new note"的新笔记将被分配一个类似notes/1657296016-my-new-note.md的路径。
gf透传如果你想要gf透传功能,但已经覆盖了gf键绑定,只需将你的gf映射定义改为如下:
vim.keymap.set("n", "gf", function() if require("obsidian").util.cursor_on_markdown_link() then return "<cmd>ObsidianFollowLink<CR>" else return "gf" end end, { noremap = false, expr = true })
然后确保在你的obsidian.nvim配置中注释掉gf键绑定:
mappings = { -- ["gf"] = ... },
或者你也可以将obsidian.nvim的跟随功能映射到不同的键:
mappings = { ["fo"] = { action = function() return require("obsidian").util.gf_passthrough() end, opts = { noremap = false, expr = true, buffer = true }, }, },
要在当前笔记中插入模板,运行命令:ObsidianTemplate。这将用你偏好的选择器打开模板文件夹中可用模板的列表。选择一个模板并按<CR>插入。
要从模板创建新笔记,运行命令:ObsidianNewFromTemplate。这将提示你输入新笔记的可选路径,并用你偏好的选择器打开模板文件夹中可用模板的列表。选择一个模板并按<CR>使用所选模板创建新笔记。
内置支持{{id}}、{{title}}、{{path}}、{{date}}和{{time}}的替换。
例如,使用以下配置
{ -- 其他字段... templates = { folder = "my-templates-folder", date_format = "%Y-%m-%d-%a", time_format = "%H:%M", }, }
和文件~/my-vault/my-templates-folder/note template.md:
# {{title}} 创建日期:{{date}}
创建笔记Configuring Neovim.md并执行:ObsidianTemplate将在光标位置上方插入
# Configuring Neovim 创建日期:2023-03-01-Wed
你还可以使用配置字段templates.substitutions定义自定义模板替换。例如,要在插入模板时自动替换模板变量{{yesterday}},你可以在配置中添加:
{ -- 其他字段... templates = { substitutions = { yesterday = function() return os.date("%Y-%m-%d", os.time() - 86400) end } }
通过配置"动态"工作区,可以使obsidian.nvim在常规工作区/Obsidian保管库之外的单个markdown文件上工作。要做到这一点,你只需要添加一个特殊的工作区,其path字段为函数(而不是字符串),该函数应返回当前缓冲区的父目录。这告诉obsidian.nvim当缓冲区不在另一个固定工作区内时,将该目录用作工作区的path和root(保管库根目录)。
例如,要以这种方式扩展上面的配置:
{ workspaces = { { name = "personal", path = "~/vaults/personal", }, ... + { + name = "no-vault", + path = function() + -- 或者使用当前工作目录: + -- return assert(vim.fn.getcwd()) + return assert(vim.fs.dirname(vim.api.nvim_buf_get_name(0))) + end, + overrides = { + notes_subdir = vim.NIL, -- 必须使用'vim.NIL'而不是'nil' + new_notes_location = "current_dir", + templates = { + folder = vim.NIL, + }, + disable_frontmatter = true, + }, + }, + }, ... }
使用此配置,每当你进入"~/vaults/personal"(或你配置的任何固定保管库)之外的markdown缓冲区时,obsidian.nvim将切换到动态工作区,其路径/根目录设置为缓冲区的父目录。
请注意,为了避免意外行为(比如为notes_subdir创建新目录),仔细设置工作区的overrides选项很重要。
并且记住,要将配置选项重置为nil,你必须在那里使用vim.NIL而不是内置的Lua nil,这是由于Lua表的工作方式。
在提交拉取请求之前,请阅读CONTRIBUTING指南。
如果你感觉特别慷慨,我总是很感谢一些咖啡基金!❤️


多风格AI绘画神器
堆友平台由阿里巴巴设计团队创建,作为一款AI驱动的设计工具,专为设计师提供一站式增长服务。功能覆盖海量3D素材、AI绘画、实 时渲染以及专业抠图,显著提升设计品质和效率。平台不仅提供工具,还是一个促进创意交流和个人发展的空间,界面友好,适合所有级别的设计师和创意工作者。


零代码AI应用开发平台
零代码AI应用开发平台,用户只需一句话简单描述需求,AI能自动生成小程序、APP或H5网页应用,无需编写代码。


免费创建高清无水印Sora视频
Vora是一个免费创建高清无水印Sora视频的AI工具


最适合小白的AI自动化工作流平台
无需编码,轻松生成可复用、可变现的AI自动化工作流

大模型驱动的Excel数据处理工具
基于大模型交互的表格处理系统,允许用户通过对话方式完成数据整理和可视化分析。系统采用机器学习算法解析用户指令,自动执行排序、公式计算和数据透视等操作,支持多种文件格式导入导出。数据处理响应速度保持在0.8秒以内,支持超过100万行数据的即时分析。


AI辅助编程,代码自动修复
Trae是一种自适应的集成开发环境(IDE),通过自动化和多元协作改变开发流程。利用Trae,团队能够更快速、精确地编写和部署代码,从而提高编程效率和项目交付速度。Trae具备上下文感知和代码自动完成功能,是提升开发效率的理想工具。


AI论文写作指导平台
AIWritePaper论文写作是一站式AI论文写作辅助工具,简化了选题、文献检索至论文撰写的整个过程。通过简单设定,平台可快速生成高质量论文大纲和全文,配合图表、参考文献等一应俱全,同时提供开题报告和答辩PPT等增值服务,保障数据安全,有效提升写作效率和论文质量。


AI一键生成PPT,就用博思AIPPT!
博思AIPPT,新一代的AI生成PPT平台,支持智能生成PPT、AI美化PPT、文本&链接生成PPT、导入Word/PDF/Markdown文档生成PPT等,内置海量精美PPT模板,涵盖商务、教育、科技等不同风格,同时针对每个页面提供多种版式,一键自适应切换,完美适配各种办公场景。


AI赋能电商视觉革命,一站式智能商拍平台
潮际好麦深耕服装行业,是国内AI试衣效果最好的软件。使用先进AIGC能力为电商卖家批量提供优质的、低成本的商拍图。合作品牌有Shein、Lazada、安踏、百丽等65个国内外头部品牌,以及国内10万+淘宝、天猫、京东等主流平台的品牌商家,为卖家节省将近85%的出图成本,提升约3倍出图效率,让品牌能够快速上架。


企业专属的AI法律顾问
iTerms是法大大集团旗下法律子品牌,基于最先进的大语言模型(LLM)、专业的法律知识库和强大的智能体架构,帮助企业扫清合规障碍,筑牢风控防线,成为您企业专属的AI法律顾问。
最新AI工具、AI资讯
独家AI资源、AI项目落地

微信扫一扫关注公众号