Vim 多行 If 语句转换为单行 If 语句
Vim Multi-Line If-Statements into Single-Line If-Statements
是否可以使用 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
通过在可视模式下选择它们 V
并按 J
将所有行合并为一行;然后在每个 else
和 :s/else/\relse/
之前添加一个换行符。你最终会得到:
if () { statement_1; statement_2; }
else if () { statement_3; statement_4; }
else if () { statement_5; }
else { }
replacement pattern中的\r
是一个换行符(你需要使用\n
和search,replace中使用\r
;不要问我为什么)。
下一步是将所有开始大括号放在同一列中。为此,我会使用 tabular plugin,这非常简单:
:%Tabularize /{/
使用 %
我们对整个缓冲区进行操作,在 "real" 文件中您可能希望使用限制性更强的范围或可视模式。还有一些其他插件也可以做类似的事情。
你现在应该有你想要的输出。
如果不想使用插件,可以使用column
命令:
:%!column -ts{ -o{
如果你想要一个"Vim-only"的解决方案,那就有点复杂了:
:let b:column = 10
:%s/^\(.\{-}\) {/\=submatch(1) . repeat(' ', b:column - len(submatch(1))) . ' {'/
分解:
我使用了 b:column
变量来指定要对齐的列。您不需要这个,但它可以让以后编辑这个数字更容易一些。
^\(.\{-}\) {
将 {
之前的所有内容放入子组中。
- 在替换中我们使用了一个表达式(如
\=
所示)。参见 :help sub-replace-\=
。
- 首先我们用
submatch(1)
放回 if ...
- 然后我们用
repeat(' ', b:column - len(submatch(1)))
插入我们需要的空格
- 最后我们插入文字
{
。
我告诉过你它有点复杂 ;-) 如果你不想要表格。就个人而言,我只是启动插入模式来插入空格,这比编写和调试这个要快得多(relevant xkcd)。
请注意,我没有使用 "magic" 命令来重新排列所有文本,只需按一下键即可。我不认为这样的命令是个好主意。在实践中,会有很多这样的命令无法处理的边缘情况。完全 "parsing" 一种带有临时编辑命令的编程语言 and/or 正则表达式并不是那么好用。
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>)
是否可以使用 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
通过在可视模式下选择它们 V
并按 J
将所有行合并为一行;然后在每个 else
和 :s/else/\relse/
之前添加一个换行符。你最终会得到:
if () { statement_1; statement_2; }
else if () { statement_3; statement_4; }
else if () { statement_5; }
else { }
replacement pattern中的\r
是一个换行符(你需要使用\n
和search,replace中使用\r
;不要问我为什么)。
下一步是将所有开始大括号放在同一列中。为此,我会使用 tabular plugin,这非常简单:
:%Tabularize /{/
使用 %
我们对整个缓冲区进行操作,在 "real" 文件中您可能希望使用限制性更强的范围或可视模式。还有一些其他插件也可以做类似的事情。
你现在应该有你想要的输出。
如果不想使用插件,可以使用column
命令:
:%!column -ts{ -o{
如果你想要一个"Vim-only"的解决方案,那就有点复杂了:
:let b:column = 10
:%s/^\(.\{-}\) {/\=submatch(1) . repeat(' ', b:column - len(submatch(1))) . ' {'/
分解:
我使用了
b:column
变量来指定要对齐的列。您不需要这个,但它可以让以后编辑这个数字更容易一些。^\(.\{-}\) {
将{
之前的所有内容放入子组中。- 在替换中我们使用了一个表达式(如
\=
所示)。参见:help sub-replace-\=
。 - 首先我们用
submatch(1)
放回 - 然后我们用
repeat(' ', b:column - len(submatch(1)))
插入我们需要的空格
- 最后我们插入文字
{
。
if ...
我告诉过你它有点复杂 ;-) 如果你不想要表格。就个人而言,我只是启动插入模式来插入空格,这比编写和调试这个要快得多(relevant xkcd)。
请注意,我没有使用 "magic" 命令来重新排列所有文本,只需按一下键即可。我不认为这样的命令是个好主意。在实践中,会有很多这样的命令无法处理的边缘情况。完全 "parsing" 一种带有临时编辑命令的编程语言 and/or 正则表达式并不是那么好用。
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>)