Search code examples
vimglobalex

How to execute multiple global commands in Vim sequentially? (Error: "Cannot do :global recursive")


I want to sort the paragraphs in my text according to their initials with the following global command:

g/_p/,/^$/mo$

This works alone. But when I use several global commands at once, then an error occurs:

g/_p/,/^$/mo$|g/_w/,/^$/mo$

This gives the following error:

Cannot do :global recursive

How can I run these commands sequentially at once?


Solution

  • :exe 'g/_p/,/^$/mo$' | g/_w/,/^$/mo$
    

    To append more global commands, just keep wrapping them in execute:

    :execute 'g/aaa/s//bbb/g ' | execute 'g/ccc/s/ddd//g' | execute 'g/eee/s/fff/ggg/g' | g/^cake/s/$/ is a lie/g
    

    The reason for the error is in :help:bar:

    *:bar* *:\bar* | can be used to separate commands, so you can give multiple commands in one line. If you want to use | in an argument, precede it with \.

    These commands see the | as their argument, and can therefore not be followed by another Vim command:

    • (.. list of commands ..)
    • :global
    • (.. list of commands ..)

    Note that this is confusing (inherited from Vi): With :g the | is included in the command, with :s it is not.

    To be able to use another command anyway, use the :execute command.

    This also answers why the below chain would work without any issues:

    %s/htm/html/c | %s/JPEG/jpg/c | %s/GIF/gif/c