首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >将多行If-语句转换为单行If-语句

将多行If-语句转换为单行If-语句
EN

Stack Overflow用户
提问于 2017-05-06 05:51:07
回答 1查看 1.1K关注 0票数 1

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

把这个打开

代码语言:javascript
运行
复制
if () {
    statement_1;
    statement_2;
} else if () {
    statement_3; statement_4;
} else if () {
    statement_5;
} else {

}

进入到这个

代码语言:javascript
运行
复制
if ()      { statement_1; statement_2 }
else if () { statement_3; statement_4; }
else if () { statement_5; }
else       { }

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

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-05-06 14:28:47

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

代码语言:javascript
运行
复制
if () { statement_1; statement_2; } 
else if () { statement_3; statement_4; }
else if () { statement_5; } 
else { }

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

下一步是将所有的开始大括号放在同一列中。为此,我将使用表式插件,这使得这非常容易:

代码语言:javascript
运行
复制
:%Tabularize /{/

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

现在应该有所需的输出。

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

代码语言:javascript
运行
复制
:%!column -ts{ -o{

如果您想要一个“唯Vim”的解决方案,那么它就更复杂了:

代码语言:javascript
运行
复制
: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)要快得多。

请注意,我没有做一些“魔术”命令,它用一个键的笔划重新排列所有的文本。我不认为这样的命令是个好主意。实际上,会有许多这样的命令无法处理的边缘情况。使用临时编辑命令和/或regexp完全“解析”一种编程语言并不是很好。

Vim真正出色的地方是为用户提供强大的文本编辑命令,这些命令可以被应用并以最小的努力组合在一起,这正是我上面所做的。有几种其他的方法可以用来达到同样的效果。

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

代码语言:javascript
运行
复制
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>)
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43817201

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档