1

是否有可能有一个 vim 绑定将多行 if 语句转换为单行 if 语句,反之亦然?

转这个

if () {
    statement_1;
    statement_2;
} else if () {
    statement_3; statement_4;
} else if () {
    statement_5;
} else {

}

进入这个

if ()      { statement_1; statement_2 }
else if () { statement_3; statement_4; }
else if () { statement_5; }
else       { }

或任何接近上述行为的东西?我正在考虑在视觉选择要转换的块时执行命令,然后使用搜索和输入新行等。但我的问题是确定代码中有else if多少else if

4

1 回答 1

2

V通过在可视模式下选择所有行并按;将所有行合并为一行J;然后在每个elsewith之前添加一个换行符:s/else/\relse/。你最终会得到:

if () { statement_1; statement_2; } 
else if () { statement_3; statement_4; }
else if () { statement_5; } 
else { }

替换模式中的\r是换行符(您需要使用\n和搜索并\r替换;不要问我为什么)。

下一步是将所有起始大括号放在同一列中。我会为此使用表格插件,这很容易:

:%Tabularize /{/

随着%我们对整个缓冲区进行操作,在“真实”文件中,您可能希望使用更严格的范围或可视模式。还有一些其他插件也可以做类似的事情。

你现在应该有你想要的输出了。


如果不想使用插件,可以使用column命令:

:%!column -ts{ -o{

如果你想要一个“仅 Vim”的解决方案,那么它有点复杂:

:let b:column = 10
:%s/^\(.\{-}\) {/\=submatch(1) . repeat(' ', b:column - len(submatch(1))) . ' {'/

打破它:

  • 我使用b:column变量来指定要对齐的列。您不需要这个,但它使以后编辑这个号码更容易一些。

  • ^\(.\{-}\) {将之前的所有内容{放在一个子组中。

  • 在替换中,我们使用了一个表达式(如 所示\=)。见:help sub-replace-\=
  • 首先我们把if ...后面的submatch(1)
  • 然后我们根据需要插入尽可能多的空格repeat(' ', b:column - len(submatch(1)))
  • 最后我们将文字插入{回来。

我告诉过你它有点复杂;-)如果你不想要表格。就个人而言,我只是启动插入模式来插入空格,这比编写和调试这个(相关的 xkcd)要快得多。


请注意,我没有做出一些“魔术”命令,只需按一下键即可重新排列所有文本。我认为这样的命令不是一个好主意。在实践中,会有很多这样的命令无法处理的边缘情况。使用临时编辑命令和/或正则表达式完全“解析”一种编程语言并没有那么好用。

Vim 真正的亮点在于为用户提供了强大的文本编辑命令,可以轻松地应用和组合这些命令,这正是我在上面所做的。可以使用其他几种方法来获得相同的效果。

但是,如果您真的想这样做,当然可以将以上所有内容组合到一个命令中:

fun! s:reformat(line1, line2)
    " Remember number of lines for later
    let l:before = line('$')

    " Join the lines
    execute 'normal! ' . (a:line2 - a:line1 + 1) . 'J'

    " Put newline before else
    :s/else/\relse/

    " Run tabular; since the number of lines change we need to calculate the range.
    " You could also use one of the other methods here, if you want.
    let l:line2 = a:line2 - (l:before - line('$'))
    execute a:line1 . ',' . l:line2 . 'Tabularize /{/'
endfun

command! -range Reformat :call s:reformat(<line1>, <line2>)
于 2017-05-06T14:28:47.307 回答