home / skills / julianobarbosa / claude-code-skills / obsidian-nvim-skill

obsidian-nvim-skill skill

/skills/obsidian-nvim-skill

This skill helps you configure and troubleshoot obsidian.nvim for Obsidian vault management, including workspaces, templates, daily notes, and UI customization.

npx playbooks add skill julianobarbosa/claude-code-skills --skill obsidian-nvim-skill

Review the files below or copy the command above to add this skill to your agents.

Files (5)
SKILL.md
6.1 KB
---
name: obsidian-nvim
description: Guide for implementing obsidian.nvim - a Neovim plugin for Obsidian vault management. Use when configuring, troubleshooting, or extending obsidian.nvim features including workspace setup, daily notes, templates, completion, pickers, and UI customization.
---

# obsidian.nvim Skill

A comprehensive guide for implementing and configuring obsidian.nvim - the Neovim plugin for managing Obsidian vaults.

## Quick Start

### Minimal Installation (lazy.nvim)

```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

## Configuration

See [references/configuration.md](references/configuration.md) for complete configuration options.

### 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" },
    },
  },
})
```

## Commands

See [references/commands.md](references/commands.md) for complete command reference.

### Primary Commands

| Command | Description |
|---------|-------------|
| `: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 |

### Visual Mode Commands

| Command | Description |
|---------|-------------|
| `: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 |

## Keymaps

### Smart Action (Recommended: `<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 })
```

### 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" })
```

## 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>",
  },
},
```

## Completion Integration

### With blink.cmp

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

### With nvim-cmp

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

**Triggers:**
- `[[` - Wiki link completion
- `[` - Markdown link completion
- `#` - Tag completion

## Templates

### Template Variables

| Variable | Description |
|----------|-------------|
| `{{title}}` | Note title |
| `{{date}}` | Current date |
| `{{time}}` | Current time |
| `{{id}}` | Note 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,
  },
},
```

## 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" },
},
```

## Troubleshooting

See [references/troubleshooting.md](references/troubleshooting.md) for comprehensive troubleshooting.

### Health Check

```vim
:checkhealth obsidian
```

### Quick Fixes

| Issue | Solution |
|-------|----------|
| Completion not working | Install ripgrep: `brew install ripgrep` |
| Picker not opening | Verify picker name matches installed plugin |
| Images not pasting | macOS: `brew install pngpaste` |
| Links not following | Ensure cursor is on `[[link]]` or `[text](link)` |
| Checkboxes not rendering | Set `:set conceallevel=2` |
| Workspace not found | Verify path exists and file is inside vault |

### Debug Mode

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

## Examples

See [references/examples.md](references/examples.md) for practical configuration examples.

## Resources

- [GitHub Repository](https://github.com/obsidian-nvim/obsidian.nvim)
- [Wiki Documentation](https://github.com/obsidian-nvim/obsidian.nvim/wiki)
- [Breaking Changes](https://github.com/obsidian-nvim/obsidian.nvim/wiki/Breaking-Changes)

Overview

This skill is a focused guide for implementing and configuring obsidian.nvim, the Neovim plugin that manages Obsidian-style vaults inside Neovim. It helps you set up workspaces, daily notes, templates, completion, pickers, and UI behavior so you can use your vaults efficiently within Neovim. The content is practical and oriented to configuration, troubleshooting, and extension.

How this skill works

The guide explains required system tools, minimal and full configuration options, and the plugin API surface for workspace and note management. It covers key features like daily notes, template variables and substitutions, note ID generation, completion triggers, picker mappings, frontmatter generation, and UI customization. It also lists commands, recommended keymaps, troubleshooting steps, and quick fixes for common issues.

When to use it

  • When installing or configuring obsidian.nvim for the first time.
  • When you need to wire up completion, pickers, or template behavior.
  • When troubleshooting completion, picker, or image-paste problems.
  • When customizing note IDs, frontmatter, or UI rendering like checkboxes.
  • When integrating obsidian.nvim with your preferred picker or completion engine.

Best practices

  • Define one or more workspaces with explicit names and absolute paths to avoid path issues.
  • Install ripgrep and the appropriate image-paste tool (pngpaste on macOS or xclip/wl-clipboard on Linux) before enabling completion and image features.
  • Use the provided note_id_func pattern or adapt it for reproducible Zettelkasten-style IDs.
  • Enable and test completion triggers ([[, [, #]) with your chosen completion engine (nvim-cmp or blink.cmp).
  • Map a smart Enter key to follow links only when the cursor is on a markdown link to preserve normal Enter behavior.

Example use cases

  • Create a minimal lazy.nvim install that only loads for markdown files and registers a personal workspace.
  • Configure daily notes to live in a dedicated folder with a custom date and alias format.
  • Use template substitutions to insert yesterday/tomorrow dates or custom computed fields into new notes.
  • Wire obsidian.nvim to telescope or fzf-lua with custom note and tag mappings for faster navigation.
  • Enable frontmatter generation to include id, aliases, tags, and additional metadata in a consistent order.

FAQ

Completion isn't showing wiki links. What do I check first?

Verify ripgrep is installed and that completion.min_chars is set appropriately. Confirm your chosen completion backend (nvim_cmp or blink) matches your config.

Picker doesn't open when I run the command.

Ensure the picker name matches an installed picker plugin (telescope, fzf-lua, etc.) and that your picker configuration maps note operations correctly.