obsidian.nvim

repository·main·Indexed 27 days ago

https://github.com/epwalsh/obsidian.nvim

A Neovim plugin written in Lua for writing and navigating Obsidian vaults. It provides Neovim-native workflows for note-taking, linking, and vault management, featuring asynchronous autocompletion for references and tags, image pasting support, and enhanced markdown syntax highlighting. The plugin includes a Lua client API for programmatically managing workspaces, daily notes, templates, and backlinks.

Tokens
7.5K
Snippets
15
Records
52
Agent score
91%

What's inside obsidian.nvim

  1. Overview of obsidian.nvim features

    main

    obsidian.nvim is a Neovim plugin for writing and navigating Obsidian vaults using Lua. Key features include:

    • Completion: Asynchronous autocompletion for note references ([[) and tags (#) via nvim-cmp and ripgrep.
    • Navigation: Use gf on any link to navigate to the referenced note.
    • Images: Support for pasting images from the clipboard into notes.
    • Syntax: Enhanced markdown syntax highlighting, concealing, and extmarks for references, tags, and checkboxes.
  2. Install and configure obsidian.nvim

    main

    To install obsidian.nvim, use your preferred plugin manager. It is recommended to use the latest release (version = "*" or tag = "*") rather than the main branch for stability.

    Required Dependency:

    • nvim-lua/plenary.nvim

    Setup: Call require("obsidian").setup({ ... }) with your desired configuration. You can define multiple workspaces to manage different Obsidian vaults.

    -- Example using lazy.nvim
    return {
      "epwalsh/obsidian.nvim",
      version = "*",
      lazy = true,
      ft = "markdown",
      dependencies = {
        "nvim-lua/plenary.nvim",
      },
      opts = {
        workspaces = {
          {
            name = "personal",
            path = "~/vaults/personal",
          },
        },
      },
    }
  3. System requirements and OS dependencies

    main

    Core Requirements

    • NeoVim: >= 0.8.0
    • ripgrep: Required for completion and search features.

    OS-Specific Dependencies

    Certain commands require external tools:

    • Windows WSL: wsl-open (for :ObsidianOpen)
    • MacOS: pngpaste (for :ObsidianPasteImg)
    • Linux: xclip (X11) or wl-clipboard (Wayland) (for :ObsidianPasteImg)
  4. Configure templates and substitutions

    main

    Use :ObsidianTemplate to insert a template or :ObsidianNewFromTemplate to create a new note from one.

    Built-in substitutions: {{id}}, {{title}}, {{path}}, {{date}}, and {{time}}.

    Custom substitutions: Define functions in templates.substitutions to add custom variables.

    templates = {
      folder = "my-templates-folder",
      substitutions = {
        yesterday = function() 
          return os.date("%Y-%m-%d", os.time() - 86400) 
        end
      }
    }
  5. Configure attachments and image pasting

    main

    Manage how images and other attachments are handled when using :ObsidianPasteImg.

    • attachments.img_folder: The directory where images are stored (relative to vault root).
    • attachments.img_name_func: Function to generate the filename (e.g., adding a timestamp).
    • attachments.img_text_func: Function to define the markdown syntax used to insert the image.
    attachments = {
      img_folder = "assets/imgs",
      img_name_func = function() 
        return string.format("%s-", os.time()) 
      end,
    }
  6. Configure daily notes

    main

    Customize how daily notes are handled via the daily_notes table in your setup:

    • folder: Subdirectory for daily notes.
    • date_format: Date format for the note ID.
    • alias_format: Date format for the default alias.
    • default_tags: Tags to add to new daily notes.
    • template: Path to a template file to insert upon creation.
    daily_notes = {
      folder = "notes/dailies",
      date_format = "%Y-%m-%d",
      alias_format = "%B %-d, %Y",
      default_tags = { "daily-notes" },
      template = "daily.md"
    }
  7. Configure UI and syntax highlighting

    main

    To enable advanced UI features (like checkbox icons and link concealment), set conceallevel to 1 or 2 in Neovim.

    Key UI settings:

    • ui.enable: Enable/disable UI features.
    • ui.checkboxes: Map characters (e.g., " ", "x") to specific highlight groups.
    • ui.hl_groups: Define custom highlight groups using vim.api.nvim_set_hl().
    -- Required for UI features
    -- set conceallevel=1
    
    ui = {
      enable = true,
      checkboxes = {
        [" "] = { char = "󰄱", hl_group = "ObsidianTodo" },
        ["x"] = { char = "", hl_group = "ObsidianDone" },
      },
    }
  8. Configure obsidian.nvim workspaces

    main

    Workspaces define your Obsidian vaults. You can configure multiple workspaces, and obsidian.nvim will automatically select the one whose path is a parent of the current file.

    • Fixed Workspaces: Provide a name and a path (string).
    • Strict Mode: Setting strict = true forces the path to be treated as the workspace root, even if the actual Obsidian vault root is higher up.
    • Dynamic Workspaces: Provide a Lua function for the path field. This is useful for working with markdown files outside of fixed vaults (e.g., using the current buffer's parent directory).
    workspaces = {
      { 
        name = "personal", 
        path = "~/vaults/personal" 
      },
      { 
        name = "dynamic-vault", 
        path = function() 
          return assert(vim.fs.dirname(vim.api.nvim_buf_get_name(0))) 
        end 
      }
    }
  9. Search for tags using Obsidian commands

    main

    You can interact with tags in your Obsidian vault using the tag-related commands. The behavior depends on the context of your selection or cursor position:

    1. With specific tags provided: If you pass specific tags as arguments, the plugin searches for those tags and opens a picker to select specific occurrences.
    2. With a visual selection: If you visually select a tag (e.g., #work or work), the plugin searches for that specific tag.
    3. With a tag under the cursor: If no arguments or visual selection are present, the plugin identifies the tag currently under your cursor and searches for it.
    4. No selection/arguments: If no tag is identified, the plugin opens a picker containing all tags found in the vault. Selecting tags from this list will then trigger a search for those specific tags.

    When a match is found, a picker displays the note's display name, the line number, and the text content. Selecting an entry opens the note at the exact line and column where the tag was found.

  10. Get the Obsidian client instance

    main

    To programmatically interact with obsidian.nvim features in Lua, obtain the main client instance using require("obsidian").get_client(). The client provides access to workspaces, notes, searching, and link resolution.

    local client = require("obsidian").get_client()
  11. Open notes in the Obsidian application

    main

    The open command allows you to open the current note or a specific note reference directly in the Obsidian desktop application.

    Behavior Logic:

    1. With Arguments: If you provide a search term as an argument, the plugin attempts to resolve that term to a note (using a picker if multiple matches are found) and opens it.
    2. With Cursor Link: If no argument is provided, the plugin checks for a note reference (link) under the cursor. If a valid link is found, it resolves and opens that note.
    3. Current Buffer: If no argument or link is found, the plugin attempts to open the file currently active in the buffer, provided it is within the configured vault.

    Configuration Options affecting this command:

    • use_advanced_uri: If true, the command uses the obsidian://advanced-uri protocol, which allows opening the note at the specific line where the cursor is located. If false, it uses the standard obsidian://open protocol.
    • open_app_foreground: On macOS, if true, Obsidian is opened in the foreground. If false, it uses the --background flag.