如何在 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

有没有一种方法可以快速地使用键盘快捷键做到这一点?

46802 次浏览

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

  • Dd-delete 行(实际上在其他编辑器中称为 cut)并将其保存到 register 中
  • 从寄存器粘贴线

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 + Down的行。然而,这将覆盖 @"寄存器,它存储您最后复制的字符串/单词/字母/等。因此,通过在 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 维基亚页面中提出的映射实际上是映射密钥组合的最佳方式,这种方式模拟了 Sublime 和其他编辑器实现此特性的方式。

这包括移动后的缩进动作,这也很棒(这是双等号 ==符号,如果你不想要的话)。

它还支持 视觉效果插入模式,因此您可以在编辑或使用 fulblock 时移动行。

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,这让我的指尖感觉更自然。