2013-03-16 63 views
6

有没有人在Vim中有一个插件或宏来替换匹配的{大括号}doend?最好把一个单行的语句是这样的:在Vim(Ruby)中用do/end替换{大括号}

foo.each { |f| f.whatever } 

到:

foo.each do |f| 
    f.whatever 
end 

我可以做一个宏自己的那一个情况,但我想的东西,也可以处理转换现有的多-line,潜在地复杂块,如:

foo.each { |f| 
    f.bars.each { |b| b.whatever } 
    hash = { a: 123, b: 456 } 
} 

成:

foo.each do |f| 
    f.bars.each { |b| b.whatever } 
    hash = { a: 123, b: 456 } 
end 

我看过vim-surroundrails.vim,并没有找到任何一种方法。

+0

对ruby不太了解。但为什么你的多行示例(输出)只有外部'{,}'被替换,内部'f.bars.each {...'不是? – Kent 2013-03-16 02:46:40

+0

支持两者都很好,但通常我不想要任何东西,只能一次扩展一个级别。我的方案是我更喜欢单行语句的内嵌块,但经常发现自己想要添加另外一个或两个语句,并且我想扩展该块。是的,我知道我应该将其全部重构为一种方法。 – 2013-03-16 03:26:54

回答

7

有一个名为Vim Blockle的Vim插件执行此功能。

一旦你安装了插件,你穿上{}doend光标,按<Leader>b交换块样式。

+0

谢谢!有点古怪,但这几乎是我所期待的。 – 2013-03-16 04:43:29

+1

所以我研究了安装Blockle,并偶然发现Blockle作者推荐安装'splitjoin':https://github.com/jgdavey/vim-blockle/issues/5 – 2016-01-13 10:39:18

0

我认为你多行例如,输出将是:

foo.each do |f| 
    f.bars.each do |b| b.whatever end 
    hash = { a: 123, b: 456 } 
end 

也就是说,f.bars.each{...}也应该被更换。

,如果它是我们的目标,试试这个:

gg/each\s*{<enter>qqf{%send<esc><c-o>sdo<esc>[email protected] 

简短说明:

gg    " move cursor to top 
/each\s*{<enter> " search pattern we want 
qq    " start recording macro to register q 
f{    " move to { 
%send<esc>  " move to closing {, and change it to "end", back to normal 
<c-o>sdo   " back to beginning { and change it into "do" 
<esc>nq   " back to normal, and go to next match, stop recording 

,那么你可以例如[email protected]做和检查结果。

+0

这并不完全是我所追求的。看到我对这个问题的评论。我只想为当前行的范围做这件事。不过,我会检查一下,看看我是否可以使用它。 – 2013-03-16 03:27:59