在 Vim 中上下移动整行

     2023-02-21     61

关键词:

【中文标题】在 Vim 中上下移动整行【英文标题】:Move entire line up and down in Vim 【发布时间】:2010-10-19 00:20:59 【问题描述】:

在 Notepad++ 中,我可以使用 Ctrl + Shift + Up / Down 将当前行向上移动和下来。 Vim中是否有类似的命令?我翻遍了无穷无尽的指南,但一无所获。

如果没有,我如何将操作绑定到该组合键?

编辑:Mykola 的答案适用于所有行,除了缓冲区开头和结尾的行。将第一行向上或底线向下移动会删除该线,而当将底线向上移动时,它最初会跳过两个空格,就像一个棋子!任何人都可以提供任何改进吗?

【问题讨论】:

我别无选择,只能实施脚本解决方案。我希望它是干净的并且可以满足您的需求。 给未来的孩子们:vim.wikia.com/wiki/Moving_lines_up_or_down 我不确定您为什么需要脚本,Wikia 文章示例有效。我在下面发布了一个简化版本,因为 Wikia 的具有 3 种不同映射模式的示例可能相当令人生畏(并且不是真正必要的。如果您只使用块选择映射,那么您只需记住块选择(Shift V)并使用这些快捷方式(请参阅下面的答案)。 主题截图:vimcasts.org/e/26 也在vi SE 【参考方案1】:

如果我想将一行与上面的行交换,我通常会执行以下操作

ddkP

解释

dd 将删除该行并将其添加到默认寄存器中。 k 将向上移动一行(j 将向下移动一行) P 将粘贴在当前行上方

【讨论】:

而且它也始终可用。 :-) ddp 向下移动一行(删除行并粘贴到当前行下方) 移动一堆行,比如 4,4 dd,然后移动到,比如 2 行,然后是 :2 要粘贴的位置,P @Guru 应该是4dd而不是4 dd dd<number>jp 将当前行 +1 行向下移动。 dd<number>kp 将当前行 行向上移动。【参考方案2】:

假设光标在您要移动的行上。

上下移动: :m 移动

:m +1 - 下移 1 行

:m -2 - 上移 1 行

(请注意,您可以将 +1 替换为任何数字,具体取决于您要向上或向下移动的行数,即 +2 会将其向下移动 2 行,-3 会将其向上移动 2 行)

移动到特定行

:set number - 显示数字行(更容易看到您将其移动到的位置)

:m 3 - 在第 3 行之后移动该行(将 3 替换为您想要的任何行)

移动多行:

V(即Shift-V)并上下移动 courser 以在 VIM 中选择多行

一旦选择点击 : 并运行上面的命令,m +1

【讨论】:

对我来说:m -2 只向上移动一行。 我把这个方法放在我的 vimrc 中,但是我不能用 '.' 重复这个命令。有人知道这是为什么吗? 非常好!不像 Notepad++ 中的解决方案那样舒适,但仍然 - 真实且有效。 Hermann,对不起,我的错字/错误,你是对的, :m -2 会将它上移一行。我改变了它。也很抱歉很晚才回复(不确定 .vimrc 部分)干杯 使用该命令移动有效,如果您想按照 OP 的要求在 Notepad++ 等绑定中使用它,您需要在 .vimrc 中输入以下内容:noremap <c-s-up> :m -2<CR> noremap <c-s-down> :m +1<CR> 【参考方案3】:

将以下内容放入您的 .vimrc 以完成这项工作

noremap <c-s-up> :call feedkeys( line('.')==1 ? '' : 'ddkP' )<CR>
noremap <c-s-down> ddp

行的消失看起来像一个 Vim 错误。我放了一个技巧来避免它。可能有一些更准确的解决方案。

更新

仅使用 Vim 组合有很多无法解释的困难。这些是缺线和额外的跳线。

这里是脚本解决方案,可以放在 .vimrc 或 ~/.vim/plugin/swap_lines.vim 中

function! s:swap_lines(n1, n2)
    let line1 = getline(a:n1)
    let line2 = getline(a:n2)
    call setline(a:n1, line2)
    call setline(a:n2, line1)
endfunction

function! s:swap_up()
    let n = line('.')
    if n == 1
        return
    endif

    call s:swap_lines(n, n - 1)
    exec n - 1
endfunction

function! s:swap_down()
    let n = line('.')
    if n == line('$')
        return
    endif

    call s:swap_lines(n, n + 1)
    exec n + 1
endfunction

noremap <silent> <c-s-up> :call <SID>swap_up()<CR>
noremap <silent> <c-s-down> :call <SID>swap_down()<CR>

【讨论】:

不得不更改为 因为我的设置似乎有冲突,但答案很棒!非常感谢 谢谢,非常适合 git rebase --interactive 。必须绑定到 。 c-s-up/down 不起作用。 如果有人想要不同的快捷方式:c 用于控制,A 用于 alt,我使用 &lt;A-up&gt; 就像在 eclipse 中使用的一样。 消失的线不是 Vim 的错误!而是由于在文档的最后一行执行了ddkP。在 3 行文件上自己尝试一下。为避免此类问题,请使用更简单的:m mappings as given on the Vim wiki。 我将最后几行更改为&lt;A-up&gt;&lt;A-down&gt;,但是当我在tmux 的可视化运行中尝试vim 中的这些键时,选择消失并且光标向上移动;不移动选定的行。【参考方案4】:

向上移动一个队列:ddkP

下移一行:ddp

【讨论】:

在 vimrc 中有这个不允许使用 '.' 重复命令 @HermannIngjaldsson,如果您希望能够使用. 重复,我想您可以将命令包装在一个函数中。 是的,.. 如果你需要移动更多的行,你可以用 V 代替 dd。 如果您在文件的开头或结尾按住此组合,它将开始删除这些行。【参考方案5】:

将以下内容添加到 ~/.vimrc 文件中(确保您没有 n,m 的映射)

nmap n :m +1<CR>
nmap m :m -2<CR>

现在按n 键将向下移动一行,m 将向上移动一行。

【讨论】:

【参考方案6】:

这对我有用:

http://vim.wikia.com/wiki/Moving_lines_up_or_down_in_a_file

顺便说一句,如果你想使用 ALT+some_key 并且你的终端(urxvt 这样做)拒绝遵守,你应该在你的 .vimrc 中输入这样的内容:

" For moving lines (^] is a special character; use <M-k> and <M-j> if it works)
nnoremap ^]k mz:m-2<CR>`z==
inoremap ^]j <Esc>:m+<CR>==gi
inoremap ^]k <Esc>:m-2<CR>==gi
vnoremap ^]j :m'>+<CR>gv=`<my`>mzgv`yo`z
nnoremap ^]j mz:m+<CR>`z==
vnoremap ^]k :m'<-2<CR>gv=`>my`<mzgv`yo`z

其中 ^] 是单个字符,表示 ALT 键。 要输入该字符,请在 Vim 中使用 C+v, Esc(在 Windows 上为 C+q, Esc)。

【讨论】:

这很好,使用 Vim 的内置命令移动一行。面对撤消或错误时,它更有可能表现得很好。 为什么不输入 Esc 作为 C-vEsc (linux)。 Windows 将 C-v 全部替换为 C-q,但在插入/命令模式下输入任何特殊键的方式相同 @sehe:谢谢,当时我不知道。我已经更新了答案。 @RafaelRinaldi, [niv]noremap 是正常|插入|视觉模式的重映射。 &lt;CR&gt;Carriage ReturnEnter 键)。 @vp_arth 不,没有【参考方案7】:

在命令模式下,将光标放在要下移的行上,然后

ddp

说明: dd 删除当前行到通用缓冲区 p 将其放回光标位置之后,或者如果是整行,则放回下方一行。

许多文档中关于命令 p 和 P 存在一些混淆。 实际上 p 粘贴在光标之后,然后在光标处粘贴。

【讨论】:

【参考方案8】:

只需将此代码添加到 .vimrc(或 .gvimrc)

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

【讨论】:

根据vim.wikia.com/wiki/…,请参阅此处以获得全面的解释。 在 Mac 上 不起作用,我不知道为什么。我已经替换为 ,并且使用 Ctrl 键效果很好。【参考方案9】:

简单的解决方案是在您的.vimrc 中添加以下几行:

nmap <C-UP> :m-2<CR>  
nmap <C-DOWN> :m+1<CR>

【讨论】:

【参考方案10】:

正是您在这些插件中寻找的内容

https://github.com/vim-scripts/upAndDown https://github.com/matze/vim-move

【讨论】:

它也支持多行,这很好。 键代表什么? @UsamaMan 换档修饰符 This 更好 imo @NoahJ.Standerson 当然,但看起来基本相同【参考方案11】:

我将以下内容放在 .vimrc 文件的末尾:

noremap H ddkkp
noremap N ddp

所以现在'H'和'N'分别上下移动当前行。

【讨论】:

H 和 N 实际上是有用的命令(H 将光标移动到屏幕顶部和开头,N 移动到上一个搜索结果),所以我建议使用不同的键 我明白了。我也重新配置了它们。要转到屏幕顶部,我按 a 然后向上。在我的书中,A 总是意味着一路。要搜索以前的结果,我按 f 然后离开。 F 代表查找。但是对于那些没有那样的人,是的..它是有效的。【参考方案12】:

当您在vim 中点击命令:help move 时,结果如下:

:[range]m[ove] address *:m* *:mo* *:move* *E134* Move the lines given by [range] to below the line given by address.

例如: 将当前行下移一行 => :m+1.

例如: 将编号为 100 的行移到编号为 80 的行下方 => :100 m 80

例如: 将编号为 100 的行移到编号为 200 的行下方 => :100 m 200

例如: 将编号在 [100, 120] 内的行移动到编号为 200 的行下方 => :100,120 m 200

【讨论】:

【参考方案13】:

对我来说,ddkkp 做到了(而不是 ddkP 使用大写的 P,这也可以)。

【讨论】:

【参考方案14】:

最简单的方法和 vscode 一样。将以下行添加到 .vimrc

"Ctrl+Shift+up move line above"
nmap <C-S-Up> :m -2<CR>

"Ctrl+Shift+down move line below
nmap <C-S-Down> :m +1<CR>

【讨论】:

【参考方案15】:

这是 MacVim 的简化版本,使用 Wikia 文章示例(参见 gun 评论中的链接)。

" Move selection up/down (add =gv to reindent after move)
:vmap <D-S-Up> :m-2<CR>gv
:vmap <D-S-Down> :m'>+<CR>gv

我只使用块选择变体,因为只需要 Shift-V 来选择当前行,并且可以选择上/下光标来选择更多行。

根据上面的快捷键,按下 Cmd-Shift-Up/Down 将向上/向下移动块选择。 “D”是 MacVim 中的 Command 键,对于 Windows,请尝试“C”(Control)或“A”(Alt)(例如, 将是 Control Alt f)。

Wikia 文章在其中添加了“=gv”,这具有根据周围文本调整移动后块的缩进的效果。这很令人困惑,因此我将其删除,并添加了用于快速缩进选择的快捷方式。

" Indent selection left/right (Cmd Shift Left/Right is used for Tab switching)
:vmap <D-A-Left> <gv
:vmap <D-A-Right> >gv

请注意,> 也可以这样做,但选择会丢失,因此上面的这些快捷方式允许多次缩进并且仍然移动块,因为选择保持不变。

我的 MacVim 配置为使用 Cmd-Shift-Left/Right 切换选项卡,所以我使用了 Cmd-Alt-Left/Right。

这是 MacVim 的 Tab 切换(将 .gvimrc 与上面的其余部分一起放入):

:macm Window.Select\ Previous\ Tab key=<D-S-Left>
:macm Window.Select\ Next\ Tab key=<D-S-Right>

【讨论】:

【参考方案16】:

vim plugin unimpaired.vim [e and ]e

【讨论】:

这看起来有点矫枉过正,我不认为你真的需要一个完整的插件。 vimrc 中的 2 行完全符合 OP 的要求【参考方案17】:

如果您想在匹配特定搜索的多行上执行此操作:

向上::g/Your query/ normal ddp:g/Your query/ m -1 向下:g/Your query/ normal ddp:g/Your query/ m +1

【讨论】:

【参考方案18】:

这是一个适用于我的机器的解决方案 : 运行 VIM 8.1 的 MacBook Pro

这些命令不会删除缓冲区顶部或底部的行。

使用 Alt-J 和 Alt-K 输出的实际符号可以解决它们的键码在我的环境中无法正确映射的问题。

把这个放到旧的 .vimrc 中看看是否适合你。

" Maps Alt-J and Alt-K to macros for moving lines up and down
" Works for modes: Normal, Insert and Visual
nnoremap ∆ :m .+1<CR>==
nnoremap ˚ :m .-2<CR>==
inoremap ∆ <Esc>:m .+1<CR>==gi
inoremap ˚ <Esc>:m .-2<CR>==gi
vnoremap ∆ :m '>+1<CR>gv=gv
vnoremap ˚ :m '<-2<CR>gv=gv

【讨论】:

【参考方案19】:

可以使用命令:

:g/^/move 0

参考:https://vi.stackexchange.com/questions/2105/how-to-reverse-the-order-of-lines

【讨论】:

【参考方案20】:

:m.+1 或 :m.-2 如果您要移动一行,则可以。这是我移动多行的脚本。在视觉模式下,Alt-up/Alt-down 会将包含视觉选择的行向上/向下移动一行。在插入模式或正常模式下,如果没有给出计数前缀,Alt-up/Alt-down 将移动当前行。如果有计数前缀,Alt-up/Alt-down 将从当前行开始的多行向上/向下移动一行。

function! MoveLines(offset) range
    let l:col = virtcol('.')
    let l:offset = str2nr(a:offset)
    exe 'silent! :' . a:firstline . ',' . a:lastline . 'm'
        \ . (l:offset > 0 ? a:lastline + l:offset : a:firstline + l:offset)
    exe 'normal ' . l:col . '|'
endf

imap <silent> <M-up> <C-O>:call MoveLines('-2')<CR>
imap <silent> <M-down> <C-O>:call MoveLines('+1')<CR>
nmap <silent> <M-up> :call MoveLines('-2')<CR>
nmap <silent> <M-down> :call MoveLines('+1')<CR>
vmap <silent> <M-up> :call MoveLines('-2')<CR>gv
vmap <silent> <M-down> :call MoveLines('+1')<CR>gv

【讨论】:

vim简介(代码片段)

...模式了(这是默认的模式)。在这个模式中,你可以使用『上下左右』按键来移动光标,你可以使用『删除字符』或『删除整行』来处理档案内容,也可以使用『复制、贴上』来处理你的文件数据。编辑模式:在一般模式中可以进... 查看详情

如何在 Vim 中复制整行?

】如何在Vim中复制整行?【英文标题】:HowtoduplicateawholelineinVim?【发布时间】:2010-09-0913:18:55【问题描述】:如何在Vim中以类似于IntelliJIDEA/Resharper或中的Ctrl+D的方式复制整行Eclipse中的Ctrl+Alt+↑/↓?【问题讨论】:人们不再运行... 查看详情

vim复制一整行和复制多行

1、复制1)单行复制在命令模式下,将光标移动到将要复制的行处,按“yy”进行复制;2)多行复制在命令模式下,将光标移动到将要复制的首行处,按“nyy”复制n行;其中n为1、2、3……2、粘贴在命令模式... 查看详情

vim

...强版本,可以显示颜色 vim的模式?1.一般模式 移动jk上下hI左右 gg 移动到行首G 移动到行尾 ^shift+6移动到本行行首$shift+4移动到本行行尾 删除复制和粘贴x 向后删除一个字符   X向前删除一个... 查看详情

vi/vim的使用

...模式了(这是默认的模式)。在这个模式中,你可以使用『上下左右』按键来移动光标,你可以使用『删除字符』或『删除整行』来处理档案内容,也可以使用『复制、贴上』来处理你的文件数据。编辑模式:在一般模式中可以进... 查看详情

vim可视模式

...,进入行选择模式,按下V之后就会把整行选取,您可以上下移动光标选更多的行,同样,再按一次Shift+v就可以取消选取。在普通模式下输入Ctrl+v(小写),这是区域选择模式,可以进行矩形区域选择,再按一次Ctrl+v取消 查看详情

vim常用指令(代码片段)

...动光标0光标移动到行首$将光标移动到行尾viPageUp/PageDown上下翻屏HHead将光标移动到屏幕顶端M将光标移动到屏幕的中间L将光标移动到屏幕底端w或W将光标移动到下一个单词G将光标移动到文件尾行gg将光标移动到文章行首2复制粘yy... 查看详情

vi和vim编辑器

...般模式了(这是默认的模式)。在这个模式中,你可以使用[上下左右」按键来移动光标,你可以使用「删除字符」或「删除整行」来处理档案内容,也可以使用「复制、贴上」来处理你的文件数据。1.2插入模式/编辑模式在模式下... 查看详情

my-vim-wiki-doing(代码片段)

...用的几个操作入门指南~vimtutor~1.vim中是区分大小写2.vim中移动光标h 向左移动j  向下移动k 向上移动l  向右移动其实使用方向键也是能移动的,但是熟悉后再一些其他的编辑器或者浏览器中也能使用3.vim中删... 查看详情

vi/vim编辑器

...式了(这是默认的模式)。在这个模式中,你可以使用『上下左右』按键来移动光标,你可以使用『删除字符』或『删除整行』来处理档案内容, 查看详情

vim使用(代码片段)

...候,强制写入数据使用。2、命令模式操作2.1移动光标1)上下左右移动光标上下左右移动光标上、下、左、右方向键,或者H、j、k、l2)把光标移动到文件头或尾gg移动到文件头G移动到文件尾(shift+g)3移动到行首或行尾)0移动到行... 查看详情

linux中vim编辑器常用按键(代码片段)

...是默认的模式)。在这个模式中,你可以使用『上下左右』按键来移动光标,你可以使用『删除字符』或『删除整行』来处理档案内容,也可以使用『复制、粘贴』来处理你的文件数据。命令&#x 查看详情

Vi/Vim 字典获取整行

】Vi/Vim字典获取整行【英文标题】:Vi/VimDictionaryGetWholeLine【发布时间】:2017-02-0123:44:24【问题描述】:我有一个用于在VI中自动完成的字典文件。我知道我需要使用“CTRL+X,CTRL+K”来搜索和自动完成单词或行。示例文件dic.:xi_x1_a1x... 查看详情

vim使用(代码片段)

...模式了(这是默认的模式)。在这个模式中,你可以使用『上下左右』按键来移动光标,你可以使用『删除字符』或『删除整行』来处理档案内容,也可以使用『复制、贴上』来处理你的文件数据。编辑模式:在一般模式中可以进... 查看详情

vim的常用操作

...式:正常模式下按v可以进入可视模式,在可视模式下,移动光标可以选择文本。按V进入可视行模式,总是整行整行的选中。ctrl+v进入可视块模式。替换模式:正常模式下,按R进入。 移动h或退格:左移一个字符;l或空格:右... 查看详情

如何使 vim 语法突出显示整行?

】如何使vim语法突出显示整行?【英文标题】:HowdoImakevimsyntaxhighlightawholeline?【发布时间】:2011-01-1003:35:30【问题描述】:我想让vim突出显示匹配某些模式的整行。我可以将一行中的所有文本突出显示(通过执行synmatchMyMatch"... 查看详情

vi与vim

...i打开(创建)一个文件时默认处于一般指令模式,此时可以上下左右移动光标、使用快捷键来复制粘贴、删除整行整列。编辑模式:在一般指令模式下,按下“i、I,a、A,r、R,o、O”任意一个时,进入编辑模式,左下角出现INSERT... 查看详情

记录vim经常使用的几个命令

...般模式了(这是默认的模式)。在这个模式中,你可以使用上下左右按键来移动光标,你可以使用删除字符或删除整行来处理文件内容,也可以使用复制、粘贴来处理你的文件数据。 此时可以使用几个命令 查找与替换【/wor... 查看详情