如何在 vim 中交换两行?

How do I swap two lines in vim?

我有这个:

pick 887b66f add 222 Dziewiecsil to flowers new title
pick dc331cb new name of beginning commit

我想得到这个:

pick dc331cb new name of beginning commit
pick 887b66f add 222 Dziewiecsil to flowers new title

有没有办法使用键盘快捷键快速完成此操作?

要将当前行与下一行交换,请在命令模式下键入 ddp

  • dd - 删除行(实际上在其他编辑器中称为剪切)并将其保存在寄存器中
  • p - 从寄存器粘贴行

dd 删除当前行,然后您可以使用 p 粘贴删除的行。还有另一种方法,尽管使用 m。使用 m 你可以移动行,即

:m 1 会将当前行移动到第 1 行之后

:m 0 会将当前行移动到顶部

:m $ 会将当前行移动到底部

在您的示例中,将光标放在第一行并键入 :m $

更多信息:http://vim.wikia.com/wiki/Moving_lines_up_or_down

尽管这个问题很老并且被标记为已回答,但我想通过说您可以使用正常模式命令来扩展答案,这些命令由 nnoremap 像这样:

:nnoremap <C-Up> <Up>ddp<Up>
:nnoremap <C-Down> ddp

这将允许您使用 Ctrl + UpCtrl + [ 移动行=34=]向下 在你的文件中。但是,这将覆盖 @" 寄存器,该寄存器存储您最后复制的 string/word/letter/etc。因此,通过在 ddp 命令之前添加 "(reg),我们可以解决这个问题:

:nnoremap <C-Up> <Up>"add"ap<Up>
:nnoremap <C-Down> "add"ap

这里我们在删除和粘贴命令之前添加"a,以将我们的行存储在@a寄存器中,因此您的默认复制寄存器不会被覆盖。然而,它可能会覆盖 @a 寄存器的内容(谁知道呢,但你可能会在你的用例中将它用于一些重要的事情,但是这一步有点偏执,如果你愿意,你可以跳过它),让我们也解决这个问题:

:nnoremap <silent><C-Up> :let save_a=@a<Cr><Up>"add"ap<Up>:let @a=save_a<Cr>
:nnoremap <silent><C-Down> :let save_a=@a<Cr>"add"ap:let @a=save_a<Cr>

<silent> 需要防止将我们的命令回显到底部的消息行。)

现在我们有两个映射,它们允许我们使用键盘快捷键在文件中移动行。您可以重新定义按钮,我使用 Alt + j/k,即 <A-j><A-k> 用于这些命令。然而,并非所有终端仿真器都支持 Alt 键映射 AFAIK。

示例:

  1. one
> 2. two

:m-2,切换(当前行 - 2)

> 2. two
  1. one

使用 :m+1 开关(当前行 + 1)

  1. one
> 2. two

如果你愿意,你可以映射这个。

Vim wikia 页面中提出的映射实际上是映射键组合的最佳方式,它们模仿 Sublime 和其他编辑器实现此功能的方式。

这包括移动后的缩进动作,这也很棒(这是双等号 == 符号,以防您不想要它)。

它还支持 visualinsert 模式,以便您可以在编辑或使用 fulblocks 时移动行。

nnoremap <A-j> :m .+1<CR>==
nnoremap <A-k> :m .-2<CR>==
inoremap <A-j> <Esc>:m .+1<CR>==gi
inoremap <A-k> <Esc>:m .-2<CR>==gi
vnoremap <A-j> :m '>+1<CR>gv=gv
vnoremap <A-k> :m '<-2<CR>gv=gv

我个人将它们映射到 Mac 上的 <D-J><D-K>,而不是映射到 Alt<A- ] 钥匙。这样我使用 Cmd + Shift + j/k,我的指尖感觉更自然。