Fixing Vimwiki Link Format With AI
Hey 👋
I’ve been using vimwiki for years and there’s one thing that’s been bugging me the entire time.
You know when you select text in visual mode, hit Enter, and it becomes a markdown link? Well, mine weren’t that pretty.
When I’d select “Article: How to Buy a House” and press Enter, vimwiki would create:
[Article: How to Buy a House](Article:-How-to-Buy-a-House.md)
Ugh. Look at that URL. Article:-How-to-Buy-a-House.md. I hate it.
What I really wanted was:
[Article: How to Buy a House](article-how-to-buy-a-house.md)
Clean. Lowercase. URL-friendly.
Failed attempts
I’ve tried figuring this out multiple times over the years. I’d dig into the vimwiki source code, get lost in the autoload functions, give up. The plugin works great for everything else, so I’d just live with the ugly URLs.
But this time I decided to ask Claude for help.
And honestly? It worked surprisingly well. Within minutes it had mapped out the codebase, found the exact functions responsible for link generation, and identified the limitation: the links_space_char option only replaces spaces — no lowercase, no special character handling.
What would have taken me hours (or let’s be honest, I would have given up again), Claude figured out in minutes.
The solution
Rather than hacking vimwiki directly, we created a custom override in my init.vim:
" Custom vimwiki link transformation
function! CustomVimwikiLinkTransform(text)
" Convert to lowercase
let result = tolower(a:text)
" Replace any non-alphanumeric characters with hyphens
let result = substitute(result, '[^a-z0-9]', '-', 'g')
" Remove multiple consecutive hyphens
let result = substitute(result, '-\+', '-', 'g')
" Remove leading/trailing hyphens
let result = substitute(result, '^-\|-$', '', 'g')
return result
endfunction
" Override vimwiki's visual mode link creation
function! CustomNormalizeLinkSyntaxV()
" Get the visual selection
let visual_selection = vimwiki#u#get_selection()
" Transform the URL part using our custom function
let transformed_url = CustomVimwikiLinkTransform(visual_selection)
" Create the markdown link: [original text](transformed-url.md)
let file_extension = vimwiki#vars#get_wikilocal('ext', vimwiki#vars#get_bufferlocal('wiki_nr'))
let link = '[' . visual_selection . '](' . transformed_url . file_extension . ')'
" Replace the selection with our custom link
call vimwiki#u#get_selection(link)
endfunction
" Hook into vimwiki after it loads
augroup VimwikiCustom
autocmd!
autocmd FileType vimwiki call SetupCustomVimwikiMappings()
augroup END
function! SetupCustomVimwikiMappings()
" Only for markdown syntax wikis
if vimwiki#vars#get_wikilocal('syntax') == 'markdown'
" Override the visual mode Enter mapping
vnoremap <buffer> <CR> :<C-u>call CustomNormalizeLinkSyntaxV()<CR>
endif
endfunction
Now when I select “Article: How to Buy a House” and press Enter:
[Article: How to Buy a House](article-how-to-buy-a-house.md)
Perfect.
What I learned
This was a good example of when AI actually helps. Not because I couldn’t have done it myself — but because exploring unfamiliar codebases is tedious and I kept giving up.
Claude didn’t write magic code. It just helped me navigate faster. Found the right functions, proposed a non-invasive approach, explained it well enough that I can modify it later.
I’m not hiding the fact that AI helped me here. I think that’s part of what makes it interesting. Sometimes the best way to solve a problem is to ask for help.
After years of wanting this feature, I finally have clean URLs in my vimwiki. 🎉
If you’re into vimwiki customization, you might also like Make Vimwiki Open Links in Vertical Splits.
Send a comment