One solution is to adopt a more functional (as opposed to imperative) approach e.g. this particular task (and many others) can be done with a substitution:
G:s/\v([aeiou])|./\=strlen(submatch(1)) ? 1 : 0/g<CR>gggJ
i.e.:
G " go to the first non-blank character on the last line
" replace each vowel with 1 and everything else with 0
:s/\v([aeiou])|./\=strlen(submatch(1)) ? 1 : 0/g<CR>
gg " go to the first line
gJ " and append the line below
Depending on the task, you might find that plugins (such as abolish.vim) package the logic in a more convenient way than dropping to vimscript.
Another approach is to use :global
as described here, again moving any additional logic into the command(s) where convenient/necessary. If the text to process isn't already in the right format for :g
(which is line-based), it can be split into lines, operated on with :g
, and then reassembled/restored.
You can also bundle together a sequence of non-overlapping commands with |
(:help :bar
) to approximate an if/else
chain e.g. to convert:
DMY: 09/10/2011 to 10/11/2012
DMY: 13/12/2011
MDY: 10/09/2011 to 11/10/2012
MDY: 12/13/2011
to:
DMY: 2011-10-09 to 2012-11-10
DMY: 2011-12-13
MDY: 2011-10-09 to 2012-11-10
MDY: 2011-12-13
formatted for clarity (for the :execute
usage see here):
:exe 'g/^DMY:/s/\v(\d\d)\D(\d\d)\D(\d{4})/\3-\2-\1/g' |
g/^MDY:/s/\v(\d\d)\D(\d\d)\D(\d{4})/\3-\1-\2/g