是否可以使用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
答案 0 :(得分:2)
通过在视觉模式V
中选择并按J
,将所有行连接到一行;然后在else
:s/else/\relse/
之前添加换行符。你最终会得到:
if () { statement_1; statement_2; }
else if () { statement_3; statement_4; }
else if () { statement_5; }
else { }
替换模式中的\r
是换行符(您需要使用\n
并搜索并替换\r
;不要问我原因。)
下一步是将所有开始大括号放在同一列中。我为此使用了tabular plugin,这非常简单:
:%Tabularize /{/
使用%
我们对整个缓冲区进行操作,在" real"文件你可能想要使用更严格的范围或视觉模式。还有其他一些插件可以做类似的事情。
您现在应该拥有所需的输出。
如果您不想使用插件,可以使用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)))
{
插回。我告诉过你这有点复杂;-)如果你不想要表格。就个人而言,我只是开始插入模式来插入空格,这比编写和写入更快。调试这个(relevant 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>)