# How to force macro keep running even pattern is not found?

I have a macro to swap text.

For single line, it's running without problem.
But if I run this macro many times and one line is empty or different pattern, it will print below error and stop.

Is there a way to force it keep running even the pattern is not found.

• Could you show a sample code and the end result you want? – SergioAraujo Oct 25 '18 at 13:20

You can use :try to do that (:h :try).

Here is an example (I didn't use your macro because you posted it as an image and it's not easy to copy :) )

let @z=':try|s/foo/bar/|catch||endtry^M'


(Note that ^M should be entered with ctrl+venter)

This way @z will try to make the substitution and if it fails nothing will happen. For example on this buffer:

foo
faa
fii
foo
faa


Using 5@z will substitute all of the foo.

• The command let @z=':try|s/foo/bar/|catch||endtry' is not working. – Fisher Feb 9 '18 at 14:16
• @Fisher that's weird because it works on my system. How is it not working? Do you have an error message? – statox Feb 9 '18 at 14:55
• Tried the command, it reports "Error detected while processing : E488: Trailing characters. (Not sure how to add picture to the comment.) – Fisher Feb 9 '18 at 15:13
• I've added ^M, but still only first line is changed. Only working if I add j after the ^M. And found another way :silent!. – Fisher Feb 9 '18 at 15:34
• Found another way to avoid the error. Add function in .vimrc and check if condition is satisfied, otherwise don't run the command. Like: let current_line=getline('.') if current_line =~ ":" – Fisher Feb 9 '18 at 16:07

Since you're using the s command, you could simply use the e flag. From :help :s_flags:

When the search pattern fails, do not issue an error message and, in particular, continue in maps as if no error occurred.

So, each of the s commands in your macro would look something like:

:s/bar/food/e

• Combining this with the answer from above makes creating general purpose search and replace macros much easier! – daviewales Dec 6 '18 at 23:18

You can use a global command with optional regex, for example:

:g/a\|b/norm! @z


The command above will run the macro "z" only on the lines that have 'a' or 'b'

TIP: when setting your macro you can use double quotes to be able to use special keys like this:

:let @a="iHello World\<CR>bye!\<Esc>"