5

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.

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

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
  • 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 9 '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 9 '18 at 16:07
3

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
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>"

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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