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 finally managed to get the “look for the note in all (sub)directories of the vault” working. 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.