这是一个用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.nvim
return { "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.nvim
use({ "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指南。
如果你感觉特别慷慨,我总是很感谢一些咖啡基金!❤️
一键生成PPT和Word,让学习生活更轻松
讯飞智文是一个利用 AI 技术的项目,能够帮助用户生成 PPT 以及各类文档。无论是商业领域的市场分析报告、年度目标制定,还是学生群体的 职业生涯规划、实习避坑指南,亦或是活动策划、旅游攻略等内容,它都能提供支持,帮助用户精准表达,轻松呈现各种信息。
深度推理能力全新升级,全面对标OpenAI o1
科大讯飞的星火大模型,支持语言理解、知识问答和文本创作等多功能,适用于多种文件和业务场景,提升办公和日常生活的效率。讯飞星火是一个提供丰富智能服务的平台,涵盖科技资讯、图像创作、写作辅助、编程解答、科研文献解读等功能,能为不同需求的用户提供便捷高效的帮助,助力用户轻松获取信息、解决问题,满足多样化使用场景。
一种基于大语言模型的高效单流解耦语音令牌文本到语音合成模型
Spark-TTS 是一个基于 PyTorch 的开源文本到语音合成项目,由多个知名机构联合参与。该项目提供了高效的 LLM(大语言模型)驱动的语音合成方案,支持语音克隆和语音创建功能,可通过命令行界面(CLI)和 Web UI 两种方式使用。用户可以根据需求调整语音的性别、音高、速度等参数,生成高质量的语音。该项目适用于多种场景,如有声读物制作、智能语音助手开发等。
字节跳动发布的AI编程神器IDE
Trae是一种自适应的集成开发环境(IDE),通过自动化和多元协作改变开发流程。利用Trae,团队能够更快速、精确地编写和部署代码,从而提高编程效率和项目交付速度。Trae具备上下文感知和代码自动完成功能,是提升开发效率的理想工具。
AI助力,做PPT更简单!
咔片是一款轻量化在线演示设计工具,借助 AI 技术,实现从内容生成到智能设计的一站式 PPT 制作服务。支持多种文档格式导入生成 PPT,提供海量模板、智能美化、素材替换等功能,适用于销售、教师、学生等各类人群,能高效制作出高品质 PPT,满足不同场景演示需求。
选题、配图、成文,一站式创作,让内容运营更高效
讯飞绘文,一个AI集成平台,支持写作、选题、配图、排版和发布。高效生成适用于各类媒体的定制内容,加速品牌传播,提升内容营销效果。
专业的AI公文写作平台,公文写作神器
AI 材料星,专业的 AI 公文写作辅助平台,为体制内工作人员提供高效的公文写作解决方案。拥有海量公文文库、9 大核心 AI 功能,支持 30 + 文稿类型生成,助力快速完成领导讲话、工作总结、述职报告等材料,提升办公效率,是体制打工人的得力写作神器。
OpenAI Agents SDK,助力开发者便捷使用 OpenAI 相关功能。
openai-agents-python 是 OpenAI 推出的一款强大 Python SDK,它为开发者提供了与 OpenAI 模型交互的高效工具,支持工具调用、结果处理、追踪等功能,涵盖多种应用场景,如研究助手、财务研究等,能显著提升开发效率,让开发者更轻松地利用 OpenAI 的技术优势。
高分辨率纹理 3D 资产生成
Hunyuan3D-2 是腾讯开发的用于 3D 资产生成的强大工具,支持从文本描述、单张图片或多视角图片生成 3D 模型,具备快速形状生成能力,可生成带纹理的高质量 3D 模型,适用于多个领域,为 3D 创作提供了高效解决方案。
一个具备存储、管理和客户端操作等多种功能的分布式文件系统相关项目。
3FS 是一个功能强大的分布式文件系统项目,涵盖了存储引擎、元数据管理、客户端工具等多个模块。它支持多种文件操作,如创建文件和目录、设置布局等,同时具备高效的事件循环、节点选择和协程池管理等特性。适用于需要大规模数据存储和管理的场景,能够提高系统的性能和可靠性,是分布式存储领域的优质解决方案。
最新AI工具、AI资讯
独家AI资源、AI项目落地
微信扫一扫关注公众号