宏中的条件操作



在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

相关内容

  • 没有找到相关文章

最新更新