在 Notepad++ 中,我可以使用++ Ctrl/来上下移动当前行。Vim中是否有类似的命令?我浏览了无尽的指南,但一无所获。ShiftUpDown
如果没有,我如何将操作绑定到该组合键?
编辑:Mykola 的答案适用于所有行,除了缓冲区开头和结尾的那些。将第一行向上或底线向下移动会删除该线,而当将底线向上移动时,它最初会跳过两个空格,就像一个棋子!任何人都可以提供任何改进吗?
如果我想将一行与上面的行交换,我通常会执行以下操作
ddkP
解释
假设光标在您想要移动的线上。
上下移动:
: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
等
将以下内容放入您的 .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>
向上移动一行:ddkP
下移一行:ddp
将以下内容添加到 ~/.vimrc 文件中(确保没有 n,m 的映射)
nmap n :m +1<CR>
nmap m :m -2<CR>
现在按下n
键将向下移动一行并向m
上移动一行。
这对我有用:
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 键的单个字符。要输入该字符,C+v, Esc请在 Vim 中使用(C+q, Esc在 Windows 上)。
在命令模式下,将光标放在要向下移动的行上,然后
ddp
说明: dd 将当前行删除到通用缓冲区 p 将其放回光标位置之后,或者如果是整行,则在下一行。
许多文档中关于命令 p 和 P 存在一些混淆。实际上 p 粘贴在光标之后,然后粘贴在光标处。
只需将此代码添加到 .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
一个简单的解决方案是放入您的.vimrc
这些行:
nmap <C-UP> :m-2<CR>
nmap <C-DOWN> :m+1<CR>
我将以下内容放在 .vimrc 文件的末尾:
noremap H ddkkp
noremap N ddp
所以现在'H'和'N'分别上下移动当前行。
当你点击命令:help move
时vim
,结果如下:
:[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
。
对我来说,ddkkp
做到了(而不是ddkP
使用大写的 P,这也可以)。
最简单的方法与 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>
这是 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)(例如,<CAf> 将是 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>
vim 插件 unimpaired.vim [e 和 ]e
如果您想在与特定搜索匹配的多行上执行此操作:
:g/Your query/ normal ddp
或:g/Your query/ m -1
:g/Your query/ normal ddp
或:g/Your query/ m +1
这是适用于我的机器的解决方案 :运行 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
可以使用命令:
:g/^/move 0
参考:https ://vi.stackexchange.com/questions/2105/how-to-reverse-the-order-of-lines
: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