9

I have a macro to swap text.
enter image description here

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.
enter image description here
Is there a way to force it keep running even the pattern is not found.

Fisher
  • 1,086
  • 2
  • 13
  • 28

3 Answers3

10

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.

statox
  • 49,782
  • 19
  • 148
  • 225
  • The command let @z=':try|s/foo/bar/|catch||endtry' is not working. – Fisher Feb 09 '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 09 '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 09 '18 at 15:13
  • @Fisher I can't reproduce the error, but I noticed that my copy paste failed and that the ^M character was missing. However I'm not sure how this could lead to a trailing characters error. – statox Feb 09 '18 at 15:28
  • 1
    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 09 '18 at 15:34
  • 2
    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 09 '18 at 16:07
9

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
Owen
  • 213
  • 2
  • 5
0

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>"
SergioAraujo
  • 1,165
  • 11
  • 12