How do I replace text using a custom Vimscript function in a substitution?
Answer
:%s/pattern/\=MyFunc(submatch(0))/g
Explanation
The \= prefix in Vim's substitute replacement invokes the expression register, which can call any Vimscript function. By defining a custom function, you can perform arbitrarily complex transformations during search-and-replace.
Define a function
function! CamelToSnake(word)
return substitute(a:word, '[A-Z]', '_\l\0', 'g')
endfunction
Use it in a substitution
" Convert camelCase to snake_case across the file
:%s/\<[a-z]\w*[A-Z]\w*\>/\=CamelToSnake(submatch(0))/g
Built-in functions you can use
" Convert to uppercase
:%s/\<\w\+\>/\=toupper(submatch(0))/g
" Convert to lowercase
:%s/\<\w\+\>/\=tolower(submatch(0))/g
" Get string length
:%s/\w\+/\=strlen(submatch(0))/g
" Use printf for formatting
:%s/\d\+/\=printf('%04d', submatch(0))/g
" Use a counter (increment for each match)
:let c=0 | :%s/ITEM/\='item_' . (c+1)/g
Practical example: URL encode spaces
:%s/ /\=printf('%%%02X', char2nr(submatch(0)))/g
This replaces every space with %20.
Tips
submatch(0)is the full match,submatch(1)is the first capture group, etc.- You can call any Vim function, even user-defined ones
- The function must return a string
- For complex multi-step replacements, define a function first — it's cleaner than an inline expression
- Documented under
:help sub-replace-expression