Integrate with Vim Wiki

Here’s a quick tip for my fellow vim users. vim wiki is a powerful plugin that can link in between documents.

I was able to get it working by installing the plugin and changing the settings to point to my obsidian vault and using the markdown syntax.

Add this line to your vimrc file:

let g:vimwiki_list = [{'path': '~/repos/obsidian/',
                      \ 'syntax': 'markdown', 'ext': '.md'}]

*Change ~/repos/obsidian/ to the path of your obsidian vault.

Hope this helps someone like it helped me!

12 Likes

Hey, as a vim user you might be interested in this topic I made a while ago:

2 Likes

Awesome. Thanks!

Hi! I am curious how your experience using the two has faired after a year.

I also wanted to use vimwiki and obsidian interchangeable. Did you have to resort to using absolute paths?

For example:

  • Obsidian search for “Hello.md” in all the directories when you use [[Hello.md]]
  • However, vimwiki, takes that as a relative link, so it only looks for in in the current directory
1 Like

I’m also a vimwiki user who also uses Task Warrior and the tasklib/taskwiki subsystem to manage work tasks alongside notes and documentation. I have the same system set up at home for personal stuff and…don’t use it.

I’ve recently tried Obsidian again and between the .obsidian.vimrc plugin and some keymapping in the settings, I’ve approximated the behavior of vim + tmux + vim-tmux-navigator, at least insofar as navigating panes. It would be awesome to be able to minimally change this setup to allow working with notes in a terminal or in Obsidian.

If it’s too brittle to cobble together, I’ll just jump into Obsidian whole hog. But it would be great to hear others’ experiences.

I’ve added the code, but I’m not sure how it works.
What kind of command should I use to use the wiki?

I finally managed to get the “look for the note in all (sub)directories of the vault” working. :partying_face: This solution works for the wiki.vim plugin - I don’t know if the same is possible with vimwiki.

How it works:

wiki.vim lets you specify a custom URL resolver function. I implemented it by calling the rg (ripgrep) command line utility to recursively search the entire vault for the file. Add a bit of polishing like inferring the .md file extension and it works like a charm! (rg can be replaced by something like find, which comes preinstalled on many systems)

The following Lua implementation (I use NeoVim) works on my machine (macOS) and it should also work on Linux (haven’t tested though):

vim.g.wiki_root = "/path/to/obsidian/vault"

local function find_wiki_path_for_file(filename)
    -- recursively search for the file name in the wiki_root using ripgrep
    local rg_result_pipe = assert(io.popen(string.format(
        "rg -g '%s' --files \"%s\"",
        filename,
        vim.g.wiki_root
    )))
    local rg_result = rg_result_pipe:read("*line")
    rg_result_pipe:close()

    -- if ripgrep found a result, return that
    if rg_result then return rg_result end

    -- if it didn't find a result, the file does not exist;
    -- in that case, the link will point to the (not yet existing)
    -- corresponding file in the wiki_root
    if vim.g.wiki_root:sub(-1) == "/" then
        return vim.g.wiki_root .. filename
    else
        return vim.g.wiki_root .. "/" .. filename
    end
end

local function resolve_wiki_link(url)
    local components = {}
    for element in (url.stripped .. "#"):gmatch("([^#]*)#") do
        table.insert(components, element)
    end

    local filename = components[1]
    url.anchor = components[2] or ""

    -- infer the .md file extension
    if filename:sub(-3) ~= ".md" then filename = filename .. ".md" end

    if url.origin:sub(1, #vim.g.wiki_root) == vim.g.wiki_root then
        -- if the "origin" (the file that contains the link) is in the wiki_root,
        -- the wiki_root directory is recursively searched for the file name;
        url.path = find_wiki_path_for_file(filename)
    else
        -- if the origin is not in the wiki_root,
        -- fall back to only looking in the same directory as the origin
        url.path = url.origin:match(".*/") .. filename
    end

    return url
end

vim.g.wiki_link_schemes = {
    wiki = { resolver = resolve_wiki_link, },
}

No idea how to do this in VimScript, but I assume the implementation could be ported with enough VimScript knowledge. :slight_smile:

1 Like