如何在Vim中将Ruby的“if”语句重构为单行简写形式?

4

I have the following Ruby code:

if some_cond && another
  foo_bar
end

我想要把它改成:

foo_bar if some_cond && another

什么是在Vim中最常用的方法?
4个回答

5
假设光标位于重构之前的if行(不一定在该行的开头),我将使用以下正常模式命令序列:
ddjVpkJ<<

或者使用以下 Ex 命令链:

:m+|-j|<|+d

这里使用:move +命令将if行向下移动一行。 :move命令会剪切给定范围的行(如果未指定,则为当前行)并将其粘贴到由参数指定的行下面。 +地址是对下一行的.+1的简写(详情请参见:help {address})。

其次,包含条件语句主体的行与刚刚移动的if行连接在了一起。 :join命令将给定范围的行连接成一行。 -范围是.-1的缩写地址,引用光标上方的行(详情请参见:help {address})。

第三,使用:<命令减少一次shiftwidth缩进。

最后,剩余的end行现在可以用+来访问,并使用:delete命令删除。


@ib 很好的ex命令。我之前想过使用 :s//,但这个更好,我可能会自己映射它。 - Peter Rincker
您提供的 Ex 命令非常棒,但是您能解释一下它们以及如何获取帮助吗? - Sławosz
@Peter: 谢谢!类似 :s/^\s*\(if .*\)\n\(\_.*\)\n\s*end\>/\2 \1/|< 这样的也足够好用。 - ib.
@Sławosz:好的。我已经添加了一份简要说明,解释了这四个Ex命令背后的操作。如需更多细节,请参阅:h :m:h :j:h :<:h :d:h {ad - ib.

2

另一种方式:

ddpkJjdd
  • ddp 交换两行的位置
  • kJ 向上移动并连接两行
  • == 重新缩进该行
  • jdd 向下移动并删除最后一行

2
我看到了几种(可能不是最优的)解决方案:
  1. 光标位于第一行的第一个字符:

    • D - 删除 if 条件,但保持光标在原位(不删除该行)
    • J - 将下一行加入当前行
    • A <Space> <ESC> - 添加空格并退出 Normal 模式
    • p - 粘贴 if 条件
    • 然后使用 jdd 删除剩余部分
  2. 光标位于第一行的第一个字符,如前所述:

    • j - 移动到下一行
    • dd - 删除此行
    • k - 移回到 if 条件
    • P - 在当前行之前粘贴已删除的行,光标应置于粘贴的行
    • J - 将下一行加入当前行
    • ==<< - 减少当前行的缩进
    • 然后使用 jdd 删除剩余部分
  3. 另一种解决方案:

    • j - 移动到第二行
    • JD - 将下一行与当前行合并,删除已合并的部分
    • dd - 删除当前行
    • k - 移回到上一行
    • PJ<< - 粘贴、合并和减少缩进

这可能不是最优的,但我可以不加思考地执行它,因为这些命令中的大多数都在我的肌肉记忆中(大多数时间你不会想如何移动,如何复制/删除和粘贴,而且记住合并行也很有帮助)。

如果您在配置文件中启用了 virtualedit,则可以使用 $ <Space> 代替 A <Space> <Esc>,但我发现相对于 A 后跟 Ctrl-[(类似于 ESC),$ 更难使用。

作为建议:如果您使用一些大写字母命令,请尽可能地将它们链接在一起,这样您只需要按住Shift键并执行一些命令,而不是混合使用大小写字母命令并同时按下两个键(大写字母需要按2次键,其中一个是Shift)。有一次我在控制台中找到了一个有用的组合,用于重新启动服务器Ctrl+cpj,它可以通过单个Ctrl按键发送Ctrl+c、Ctrl+p(上一个命令)和Ctrl+j(Enter键)。从那时起,我也在Vim中尝试寻找类似的节省时间的组合,主要使用Shift,因为在Vim中Ctrl用得不多。

1

有大概30种方法可以做到这一点。

这里是其中一种,假设您从单词end的末尾开始:

dd(删除最后一行)
"aD(删除并将foo_bar复制到缓冲区a
dd(删除现在为空的第二行)
"aP(从缓冲区a粘贴到插入符前)
aSpaceEsc(插入空格并返回正常模式)

同样,在Vim中,“正确地”做某事很少适用,因为有很多方法可以完成某件事。这是如此微小的变化,以至于重新输入foo_bar也是可以接受的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接