在VIM宏中,如何处理条件操作?
if condition is true
do this
else
do something else
基本示例
文件内容:_
abcdefg
宏将做:
G^
if letter is one of the following letters: a e i o u
gg$i0<ESC>
else
gg$i1<ESC>
Gx
重复7次缓冲区将为:
_0111011
那么,我如何验证一个条件是否为真,然后运行一个操作?
由于Vim中没有"条件"命令,因此不能严格地通过宏来完成。您只能使用这样一个事实:当宏中的命令发出蜂鸣声时,宏重播将被中止。递归宏使用这个事实来停止迭代(例如,当j
命令不能移动到缓冲区末尾的下一行时)。
另一方面,Vimscript中的条件逻辑非常简单,一个宏可以轻松地:call
任何Vimscript函数。
你的例子可以这样表述:
function! Macro()
" Get current letter.
normal! yl
if @" =~# '[aeiou]'
execute "normal! gg$i0<ESC>"
else
execute "normal! gg$i1<ESC>"
endif
endfunction
一种解决方案是采用一种更实用(而不是命令式)的方法,例如,这个特定的任务(以及许多其他任务)可以通过替换来完成:
G:s/v([aeiou])|./=strlen(submatch(1)) ? 1 : 0/g<CR>gggJ
即:
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
根据任务的不同,您可能会发现插件(如abolish.vim)以一种比添加到vimscript更方便的方式封装逻辑。
另一种方法是使用这里描述的:global
,再次将任何额外的逻辑移动到方便/必要的命令中。如果要处理的文本已经不是:g
(基于行)的正确格式,则可以将其分成几行,用:g
操作,然后重新组装/恢复。
您还可以将一系列不重叠的命令与|
(:help :bar
)捆绑在一起,以近似if/else
链,例如转换:
DMY: 09/10/2011 to 10/11/2012
DMY: 13/12/2011
MDY: 10/09/2011 to 11/10/2012
MDY: 12/13/2011
:
DMY: 2011-10-09 to 2012-11-10
DMY: 2011-12-13
MDY: 2011-10-09 to 2012-11-10
MDY: 2011-12-13
格式为清晰(:execute
用法见这里):
:exe 'g/^DMY:/s/v(dd)D(dd)D(d{4})/3-2-1/g' |
g/^MDY:/s/v(dd)D(dd)D(d{4})/3-1-2/g