obsidian-nvim

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

obsidian.nvim Skill

obsidian.nvim 使用指南

A comprehensive guide for implementing and configuring obsidian.nvim - the Neovim plugin for managing Obsidian vaults.
这是一份关于 obsidian.nvim 的全面实施与配置指南——obsidian.nvim 是一款用于管理 Obsidian vault 的 Neovim 插件。

Quick Start

快速开始

Minimal Installation (lazy.nvim)

最小化安装(基于 lazy.nvim)

lua
return {
  "obsidian-nvim/obsidian.nvim",
  version = "*",
  ft = "markdown",
  opts = {
    workspaces = {
      { name = "personal", path = "~/vaults/personal" },
    },
  },
}
lua
return {
  "obsidian-nvim/obsidian.nvim",
  version = "*",
  ft = "markdown",
  opts = {
    workspaces = {
      { name = "personal", path = "~/vaults/personal" },
    },
  },
}

System Requirements

系统要求

  • Neovim: >= 0.10.0
  • ripgrep: Required for completion and search (
    brew install ripgrep
    )
  • pngpaste (macOS): For image pasting (
    brew install pngpaste
    )
  • xclip/wl-clipboard (Linux): For image pasting
  • Neovim:版本 >= 0.10.0
  • ripgrep:自动补全和搜索功能必需(执行
    brew install ripgrep
    安装)
  • pngpaste(macOS):用于图片粘贴(执行
    brew install pngpaste
    安装)
  • xclip/wl-clipboard(Linux):用于图片粘贴

Configuration

配置

See references/configuration.md for complete configuration options.
完整配置选项请查看 references/configuration.md

Essential Configuration Options

核心配置选项

lua
require("obsidian").setup({
  -- Workspace configuration (required)
  workspaces = {
    { name = "personal", path = "~/vaults/personal" },
    { name = "work", path = "~/vaults/work" },
  },

  -- Daily notes
  daily_notes = {
    folder = "daily",
    date_format = "%Y-%m-%d",
    alias_format = "%B %-d, %Y",
    default_tags = { "daily-notes" },
  },

  -- Templates
  templates = {
    folder = "templates",
    date_format = "%Y-%m-%d",
    time_format = "%H:%M",
  },

  -- Note ID generation (Zettelkasten-style by default)
  note_id_func = function(title)
    local suffix = ""
    if title ~= nil then
      suffix = title:gsub(" ", "-"):gsub("[^A-Za-z0-9-]", ""):lower()
    else
      for _ = 1, 4 do
        suffix = suffix .. string.char(math.random(65, 90))
      end
    end
    return tostring(os.time()) .. "-" .. suffix
  end,

  -- Completion settings
  completion = {
    nvim_cmp = true,  -- or blink = true for blink.cmp
    min_chars = 2,
  },

  -- UI customization
  ui = {
    enable = true,
    checkboxes = {
      [" "] = { char = "󰄱", hl_group = "ObsidianTodo" },
      ["x"] = { char = "", hl_group = "ObsidianDone" },
    },
  },
})
lua
require("obsidian").setup({
  -- 工作区配置(必填)
  workspaces = {
    { name = "personal", path = "~/vaults/personal" },
    { name = "work", path = "~/vaults/work" },
  },

  -- 日常笔记设置
  daily_notes = {
    folder = "daily",
    date_format = "%Y-%m-%d",
    alias_format = "%B %-d, %Y",
    default_tags = { "daily-notes" },
  },

  -- 模板设置
  templates = {
    folder = "templates",
    date_format = "%Y-%m-%d",
    time_format = "%H:%M",
  },

  -- 笔记ID生成(默认采用 Zettelkasten 风格)
  note_id_func = function(title)
    local suffix = ""
    if title ~= nil then
      suffix = title:gsub(" ", "-"):gsub("[^A-Za-z0-9-]", ""):lower()
    else
      for _ = 1, 4 do
        suffix = suffix .. string.char(math.random(65, 90))
      end
    end
    return tostring(os.time()) .. "-" .. suffix
  end,

  -- 自动补全设置
  completion = {
    nvim_cmp = true,  -- 或设置为 blink = true 以使用 blink.cmp
    min_chars = 2,
  },

  -- UI自定义设置
  ui = {
    enable = true,
    checkboxes = {
      [" "] = { char = "󰄱", hl_group = "ObsidianTodo" },
      ["x"] = { char = "", hl_group = "ObsidianDone" },
    },
  },
})

Commands

命令

See references/commands.md for complete command reference.
完整命令参考请查看 references/commands.md

Primary Commands

主要命令

CommandDescription
:Obsidian
Open command picker
:Obsidian today [OFFSET]
Open/create daily note
:Obsidian new [TITLE]
Create new note
:Obsidian search [QUERY]
Search vault with ripgrep
:Obsidian quick_switch
Fuzzy find notes
:Obsidian backlinks
Show references to current note
:Obsidian template [NAME]
Insert template
:Obsidian workspace [NAME]
Switch workspace
命令说明
:Obsidian
打开命令选择器
:Obsidian today [OFFSET]
打开/创建今日笔记(支持偏移量)
:Obsidian new [TITLE]
创建新笔记
:Obsidian search [QUERY]
使用 ripgrep 搜索 vault
:Obsidian quick_switch
模糊查找笔记
:Obsidian backlinks
显示当前笔记的引用链接
:Obsidian template [NAME]
插入模板
:Obsidian workspace [NAME]
切换工作区

Visual Mode Commands

可视模式命令

CommandDescription
:Obsidian link [QUERY]
Link selection to existing note
:Obsidian link_new [TITLE]
Create note and link selection
:Obsidian extract_note [TITLE]
Extract selection to new note
命令说明
:Obsidian link [QUERY]
将选中内容链接到已有笔记
:Obsidian link_new [TITLE]
创建新笔记并链接选中内容
:Obsidian extract_note [TITLE]
将选中内容提取为新笔记

Keymaps

按键映射

Smart Action (Recommended:
<CR>
)

智能操作(推荐映射:
<CR>

lua
vim.keymap.set("n", "<CR>", function()
  if require("obsidian").util.cursor_on_markdown_link() then
    return "<cmd>Obsidian follow_link<CR>"
  else
    return "<CR>"
  end
end, { expr = true })
lua
vim.keymap.set("n", "<CR>", function()
  if require("obsidian").util.cursor_on_markdown_link() then
    return "<cmd>Obsidian follow_link<CR>"
  else
    return "<CR>"
  end
end, { expr = true })

Navigation Links

导航链接

lua
vim.keymap.set("n", "[o", function()
  require("obsidian").util.nav_link("prev")
end, { buffer = true, desc = "Previous link" })

vim.keymap.set("n", "]o", function()
  require("obsidian").util.nav_link("next")
end, { buffer = true, desc = "Next link" })
lua
vim.keymap.set("n", "[o", function()
  require("obsidian").util.nav_link("prev")
end, { buffer = true, desc = "上一个链接" })

vim.keymap.set("n", "]o", function()
  require("obsidian").util.nav_link("next")
end, { buffer = true, desc = "下一个链接" })

Picker Integration

选择器集成

Configure your preferred picker:
lua
picker = {
  name = "telescope",  -- or "fzf-lua", "mini.pick", "snacks.picker"
  note_mappings = {
    new = "<C-x>",
    insert_link = "<C-l>",
  },
  tag_mappings = {
    tag_note = "<C-x>",
    insert_tag = "<C-l>",
  },
},
配置你偏好的选择器:
lua
picker = {
  name = "telescope",  -- 可选 "fzf-lua", "mini.pick", "snacks.picker"
  note_mappings = {
    new = "<C-x>",
    insert_link = "<C-l>",
  },
  tag_mappings = {
    tag_note = "<C-x>",
    insert_tag = "<C-l>",
  },
},

Completion Integration

自动补全集成

With blink.cmp

基于 blink.cmp

lua
completion = {
  blink = true,
  nvim_cmp = false,
  min_chars = 2,
},
lua
completion = {
  blink = true,
  nvim_cmp = false,
  min_chars = 2,
},

With nvim-cmp

基于 nvim-cmp

lua
completion = {
  nvim_cmp = true,
  blink = false,
  min_chars = 2,
},
Triggers:
  • [[
    - Wiki link completion
  • [
    - Markdown link completion
  • #
    - Tag completion
lua
completion = {
  nvim_cmp = true,
  blink = false,
  min_chars = 2,
},
触发方式:
  • [[
    - Wiki 链接补全
  • [
    - Markdown 链接补全
  • #
    - 标签补全

Templates

模板

Template Variables

模板变量

VariableDescription
{{title}}
Note title
{{date}}
Current date
{{time}}
Current time
{{id}}
Note ID
变量说明
{{title}}
笔记标题
{{date}}
当前日期
{{time}}
当前时间
{{id}}
笔记ID

Custom Substitutions

自定义替换规则

lua
templates = {
  folder = "templates",
  substitutions = {
    yesterday = function()
      return os.date("%Y-%m-%d", os.time() - 86400)
    end,
    tomorrow = function()
      return os.date("%Y-%m-%d", os.time() + 86400)
    end,
  },
},
lua
templates = {
  folder = "templates",
  substitutions = {
    yesterday = function()
      return os.date("%Y-%m-%d", os.time() - 86400)
    end,
    tomorrow = function()
      return os.date("%Y-%m-%d", os.time() + 86400)
    end,
  },
},

Frontmatter Management

前置元数据管理

lua
frontmatter = {
  enabled = true,
  func = function(note)
    local out = { id = note.id, aliases = note.aliases, tags = note.tags }
    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,
  sort = { "id", "aliases", "tags" },
},
lua
frontmatter = {
  enabled = true,
  func = function(note)
    local out = { id = note.id, aliases = note.aliases, tags = note.tags }
    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,
  sort = { "id", "aliases", "tags" },
},

Troubleshooting

故障排查

See references/troubleshooting.md for comprehensive troubleshooting.
全面故障排查指南请查看 references/troubleshooting.md

Health Check

健康检查

vim
:checkhealth obsidian
vim
:checkhealth obsidian

Quick Fixes

快速修复方案

IssueSolution
Completion not workingInstall ripgrep:
brew install ripgrep
Picker not openingVerify picker name matches installed plugin
Images not pastingmacOS:
brew install pngpaste
Links not followingEnsure cursor is on
[[link]]
or
[text](link)
Checkboxes not renderingSet
:set conceallevel=2
Workspace not foundVerify path exists and file is inside vault
问题解决方法
自动补全无法工作安装 ripgrep:执行
brew install ripgrep
选择器无法打开确认选择器名称与已安装的插件匹配
图片无法粘贴macOS:执行
brew install pngpaste
安装 pngpaste
链接无法跳转确保光标位于
[[link]]
[text](link)
链接上
复选框无法正常渲染设置
:set conceallevel=2
工作区无法找到确认路径存在且文件位于 vault 内

Debug Mode

调试模式

lua
log_level = vim.log.levels.DEBUG,
lua
log_level = vim.log.levels.DEBUG,

Examples

示例

See references/examples.md for practical configuration examples.
实用配置示例请查看 references/examples.md

Resources

相关资源