I want to do some edits on each match during a global substitution operation.

I found this answer

:% s/re\(ge\)xp/\= myfunction(submatch(1))/gc. 

But I don't have a function, just some keystrokes.

So how can I wrap a macro into myfunction to call during substitute?

Sample use: rot13(vselection) is g?, but rot13 is not a function in vim:


I found a workaround by using the bash utils without using macros this answer.

%s/m\(atm\)ul/\=substitute(':' . system('echo '.submatch(1).'|tr A-Za-z N-ZA-Mn-za-m'),'\n','','g')/gc

interactively changes 'matmul' to ':ngz:'

  • 1
    Make a function and in the function call the macro? Commented Dec 6, 2016 at 14:49

2 Answers 2


I would suggest the following:

Record your keystrokes as a macro (here in the register q) and call:

:g/regex/normal @q

This will apply the macro on each found regex in your document.

Example of use:

Content of your file

function A(){}
function B(){}
function C(){}


/function<CR>           " search for function
qqg?gnq                 " in a macro, rot13 the matched `function`
:%g//normal@q<CR>       " repeat for all `function` in the file


  • :h :g
  • :h :normal
  • :h g?
  • :h gn
  • How to access the current-match in the macro? For example, I want to run rot13 on the matches, thanks.
    – mosh
    Commented Dec 6, 2016 at 14:48
  • You can do a rot13 with the g? command. Let me expand my answer.
    – nobe4
    Commented Dec 6, 2016 at 17:07

With :substitute (especially the replace with expression), you get the exact match (or any submatches), and you can transform / reorder / invoke functions on that easily.

Normal mode commands (like g?) can directly edit text, but they usually work on lines or text covered by {motion}.

What you're asking for is a cross between the two. Since there is not rot13() built-in function, you either have to provide that yourself (and then use :s//\=rot13(submatch(0))), or relinquish the regexp matching of :s and use :global (and / or :call search()) in combination with :normal! g?.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.