obsidian.nvim

obsidian.nvim

Neovim插件实现Obsidian笔记管理与编辑

obsidian.nvim是一款Neovim插件,用于管理Obsidian笔记库。它提供自动完成、导航、图片粘贴和语法高亮等功能,以及创建笔记、搜索和链接等实用命令。该插件支持多工作区配置,可与Obsidian应用协同使用,为用户提供在Neovim环境中处理Markdown笔记的解决方案。

obsidian.nvimNeovim插件ObsidianMarkdown笔记应用Github开源项目
<h1 align="center">obsidian.nvim</h1> <div><h4 align="center"><a href="#setup">设置</a> · <a href="#configuration-options">配置</a> · <a href="#contributing">贡献</a> · <a href="https://github.com/epwalsh/obsidian.nvim/discussions">讨论</a></h4></div> <div align="center"><a href="https://github.com/epwalsh/obsidian.nvim/releases/latest"><img alt="最新版本" src="https://img.shields.io/github/v/release/epwalsh/obsidian.nvim?style=for-the-badge&logo=starship&logoColor=D9E0EE&labelColor=302D41&&color=d9b3ff&include_prerelease&sort=semver" /></a> <a href="https://github.com/epwalsh/obsidian.nvim/pulse"><img alt="最后提交" src="https://img.shields.io/github/last-commit/epwalsh/obsidian.nvim?style=for-the-badge&logo=github&logoColor=D9E0EE&labelColor=302D41&color=9fdf9f"/></a> <a href="https://github.com/neovim/neovim/releases/latest"><img alt="最新Neovim" src="https://img.shields.io/github/v/release/neovim/neovim?style=for-the-badge&logo=neovim&logoColor=D9E0EE&label=Neovim&labelColor=302D41&color=99d6ff&sort=semver" /></a> <a href="http://www.lua.org/"><img alt="使用Lua构建" src="https://img.shields.io/badge/Built%20with%20Lua-grey?style=for-the-badge&logo=lua&logoColor=D9E0EE&label=Lua&labelColor=302D41&color=b3b3ff"></a> <a href="https://www.buymeacoffee.com/epwalsh"><img alt="为我买杯咖啡" src="https://img.shields.io/badge/Buy%20me%20a%20coffee-grey?style=for-the-badge&logo=buymeacoffee&logoColor=D9E0EE&label=Sponsor&labelColor=302D41&color=ffff99" /></a></div> <hr>

这是一个用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 用于将当前笔记的目录加载到选择器列表中。

演示

2024-01-31 14 22 52

设置

系统要求

  • NeoVim >= 0.8.0(这个插件使用了vim.fs,该功能仅在0.8版本中添加)。
  • 如果您需要补全和搜索功能(推荐),您需要安装ripgrep并将其添加到$PATH中。 安装选项请参见ripgrep#installation

某些特定操作系统还需要额外的依赖项才能使用obsidian.nvim的全部功能:

  • Windows WSL 用户需要wsl-open来使用:ObsidianOpen命令。
  • MacOS 用户需要pngpastebrew install pngpaste)来使用:ObsidianPasteImg命令。
  • Linux 用户需要xclip(X11)或wl-clipboard(Wayland)来使用: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的体验。

补全:

选择器:

  • [推荐] nvim-telescope/telescope.nvim:用于搜索和快速切换功能。
  • Mini.Pick(来自mini.nvim库):telescope的替代方案,用于搜索和快速切换功能。
  • ibhagwan/fzf-lua:另一个telescope的替代方案,用于搜索和快速切换功能。

语法高亮:

其他:

如果您选择使用这些插件中的任何一个,应该将它们包含在插件管理器的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("%s", 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_subdirnote_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当缓冲区不在另一个固定工作区内时,将该目录用作工作区的pathroot(保管库根目录)。

例如,要以这种方式扩展上面的配置:

{ 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指南。

如果你感觉特别慷慨,我总是很感谢一些咖啡基金!❤️

BuyMeACoffee

编辑推荐精选

Qwen2.5-VL

Qwen2.5-VL

一款强大的视觉语言模型,支持图像和视频输入

Qwen2.5-VL 是一款强大的视觉语言模型,支持图像和视频输入,可用于多种场景,如商品特点总结、图像文字识别等。项目提供了 OpenAI API 服务、Web UI 示例等部署方式,还包含了视觉处理工具,有助于开发者快速集成和使用,提升工作效率。

HunyuanVideo

HunyuanVideo

HunyuanVideo 是一个可基于文本生成高质量图像和视频的项目。

HunyuanVideo 是一个专注于文本到图像及视频生成的项目。它具备强大的视频生成能力,支持多种分辨率和视频长度选择,能根据用户输入的文本生成逼真的图像和视频。使用先进的技术架构和算法,可灵活调整生成参数,满足不同场景的需求,是文本生成图像视频领域的优质工具。

WebUI for Browser Use

WebUI for Browser Use

一个基于 Gradio 构建的 WebUI,支持与浏览器智能体进行便捷交互。

WebUI for Browser Use 是一个强大的项目,它集成了多种大型语言模型,支持自定义浏览器使用,具备持久化浏览器会话等功能。用户可以通过简洁友好的界面轻松控制浏览器智能体完成各类任务,无论是数据提取、网页导航还是表单填写等操作都能高效实现,有利于提高工作效率和获取信息的便捷性。该项目适合开发者、研究人员以及需要自动化浏览器操作的人群使用,在 SEO 优化方面,其关键词涵盖浏览器使用、WebUI、大型语言模型集成等,有助于提高网页在搜索引擎中的曝光度。

xiaozhi-esp32

xiaozhi-esp32

基于 ESP32 的小智 AI 开发项目,支持多种网络连接与协议,实现语音交互等功能。

xiaozhi-esp32 是一个极具创新性的基于 ESP32 的开发项目,专注于人工智能语音交互领域。项目涵盖了丰富的功能,如网络连接、OTA 升级、设备激活等,同时支持多种语言。无论是开发爱好者还是专业开发者,都能借助该项目快速搭建起高效的 AI 语音交互系统,为智能设备开发提供强大助力。

olmocr

olmocr

一个用于 OCR 的项目,支持多种模型和服务器进行 PDF 到 Markdown 的转换,并提供测试和报告功能。

olmocr 是一个专注于光学字符识别(OCR)的 Python 项目,由 Allen Institute for Artificial Intelligence 开发。它支持多种模型和服务器,如 vllm、sglang、OpenAI 等,可将 PDF 文件的页面转换为 Markdown 格式。项目还提供了测试框架和 HTML 报告生成功能,方便用户对 OCR 结果进行评估和分析。适用于科研、文档处理等领域,有助于提高工作效率和准确性。

飞书多维表格

飞书多维表格

飞书多维表格 ×DeepSeek R1 满血版

飞书多维表格联合 DeepSeek R1 模型,提供 AI 自动化解决方案,支持批量写作、数据分析、跨模态处理等功能,适用于电商、短视频、影视创作等场景,提升企业生产力与创作效率。关键词:飞书多维表格、DeepSeek R1、AI 自动化、批量处理、企业协同工具。

CSM

CSM

高质量语音生成模型

CSM 是一个开源的语音生成项目,它提供了一个基于 Llama-3.2-1B 和 CSM-1B 的语音生成模型。该项目支持多语言,可生成多种声音,适用于研究和教育场景。通过使用 CSM,用户可以方便地进行语音合成,同时项目还提供了水印功能,确保生成音频的可追溯性和透明度。

agents-course

agents-course

Hugging Face 的 AI 智能体课程,涵盖多种智能体框架及相关知识

本项目是 Hugging Face 推出的 AI 智能体课程,深入介绍了 AI 智能体的相关概念,如大语言模型、工具使用等。课程包含多个单元,详细讲解了不同的智能体框架,如 smolagents 和 LlamaIndex,提供了丰富的学习资源和实践案例。适合对 AI 智能体感兴趣的开发者和学习者,有助于提升他们在该领域的知识和技能。

RagaAI-Catalyst

RagaAI-Catalyst

用于 AI 项目管理和 API 交互的工具集,助力 AI 项目高效开发与管理。

RagaAI-Catalyst 是一款专注于 AI 领域的强大工具集,为开发者提供了便捷的项目管理、API 交互、令牌管理等功能。支持多 API 密钥上传,能快速创建、列出和管理 AI 项目,还可获取项目用例和指标信息。适用于各类 AI 开发场景,提升开发效率,推动 AI 项目顺利开展。

smolagents

smolagents

一个包含多种工具和文档处理功能,适用于 LLM 使用的项目。

smolagents 是一个功能丰富的项目,提供了如文件格式转换、网页内容读取、语义搜索等多种工具,支持将常见文件类型或网页转换为 Markdown,方便进行文档处理和信息提取,能满足不同场景下的需求,提升工作效率和数据处理能力。

下拉加载更多