Vimで行全体を上下に移動します


311

Notepad ++では、Ctrl+ Shift+ Up/ Downを使用して現在の行を上下に移動できます。Vimでこれに似たコマンドはありますか?私は無限のガイドを調べましたが、何も見つかりませんでした。

存在しない場合、アクションをそのキーの組み合わせにどのようにバインドできますか?

編集:Mykolaの回答は、バッファーの最初と最後の行を除いて、すべての行で機能します。最初の行を上または下の行に移動すると、その行が削除され、一番下の行を上に移動すると、ポーンのように最初に2つのスペースがジャンプします。誰でも何か改良を提供できますか?


私はスクリプトソリューションを実装するしかありませんでした。私はそれがあなたのニーズにクリーンで採用可能であることを願っています
Mykola Golubyev、2009

31
未来の子供たちのために:vim.wikia.com/wiki/Moving_lines_up_or_down

なぜスクリプトが必要なのかはわかりませんが、Wikiaの記事の例は機能します。簡単なバージョンを以下に掲載しました。3つの異なるマッピングモードを持つWikiaの例はかなり困難な場合があるため(実際には必要ありません。ブロック選択マッピングのみを使用する場合は、ブロック選択(Shift V)を覚えて使用するだけです。これらのショートカット(下記の私の回答を参照してください)

トピックに関するスクリーンキャスト:vimcasts.org/e/26
glts

また、vi SEでも
cfi

回答:


81

以下をあなたの.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>

1
<cj>と<ck>に変更する必要がありました。これは、私の設定に衝突があるように見えるためですが、素晴らしい答えです!
どうも

1
git rebase --interactiveに感謝します。<cj>および<ck>にバインドする必要がありました。cs-up / downが機能しませんでした。
Lari Hotari 2012

2
誰かが別のショートカットを必要とする場合:cは制御用、Aは代替用、私<A-up>はEclipseで使用されているように使用します。
2014

1
消える行はVimのバグではありません!それはむしろddkP、ドキュメントの最後の行で実行するためです。3行のファイルで試してみてください。このような問題を回避するには:m、Vim wikiで提供されているより簡単なマッピングを使用してください。
Serge Stroobandt、2015年

1
私は最後の行を変更<A-up>し、<A-down>私は視覚的に走行時のvimの中にこれらのキーをしようとすると、tmuxは選択が消え、カーソルが移動しラインアップ。選択した行を移動せずに。
Konrad

574

1行を上の行と入れ替えたい場合は、通常次のようにします。

ddkP

説明

  • ddは行を削除し、それをデフォルトのレジスターに追加します。
  • kは1行上に移動します(jは1行下に移動します)
  • Pは現在の行の上に貼り付けます

5
また、いつでも利用できます。:-)
Henno

71
そして、ddp(削除行を現在の行の下に貼り付ける)ラインの下を移動する
bcoughlan

2
一連の行を移動するには、たとえば4 4 ddと言ってから、たとえば2行に移動してから、:2貼り付けたい場所とに移動しますP
グル

2
@グルは4dd代わりにすべき4 ddですか?
Patrick McDonald

3
そしてdd<number>jp、現在の行<number> +1を下に移動します。そしてdd<number>kp、現在の行を<number>行上に移動します。
egelev 2016

230

カーソルが移動したい行にあると仮定します。

上下:mに移動: 移動用

:m +1 -1行下に移動

:m -2 -1行上に移動

(+1は、上または下に移動する行数に応じて任意の数字に置き換えることができます。つまり、+ 2は2行下に移動し、-3は2行上に移動します)

特定の行に移動するには

:set number -数行を表示します(移動先を簡単に確認できます)

:m 3 -3行目の後に行を移動します(3を任意の行に置き換えます)

複数行の移動:

V(つまりShift- V)、コースを上下に移動してVIMで複数の行を選択します

ヒットを選択したら:、上のコマンドを実行して、m +1など


14
私にとって:m -2は1行上に移動します。
Fzs2 2014年

2
このメソッドをvimrcに配置しましたが、「。」を使用してコマンドを繰り返すことができません。それがなぜなのか誰か知っていますか?
Fzs2 2014年

非常に素晴らしい!Notepad ++のソリューションほど快適ではありませんが、それでも、実際に機能しています。
Arturas M 2014

ヘルマン、申し訳ありませんが、私のタイプミス/間違いです。そうです、:m -2で1行上に移動します。私はそれを変えた。また、返信が非常に遅くなって申し訳ありません(.vimrcの部分についてはわかりません)乾杯
Serg

2
あなたはOPが尋ねたようなメモ帳++からのものとしてバインディングで使用する場合は、あなたがの.vimrcに次のように入力する必要があり、コマンドの機能を使用して移動:noremap <c-s-up> :m -2<CR> noremap <c-s-down> :m +1<CR>
KAP

74

行を上に移動します。 ddkP

行を下に移動します。 ddp


1
vimrcでこれを使用すると、「。」を使用してコマンドを繰り返すことができなくなります。
Fzs2 2014年

@HermannIngjaldsson、.繰り返しに使用できるようにしたい場合は、コマンドを関数にラップできると思います。
jacobsimeon 2014年

はい、..さらに行を移動する必要がある場合は、ddの代わりにVを使用できます。
sensorario 2015年

15

これは私のために働きました:

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の場合)。


1
これは、Vimの組み込みコマンドを使用して行を移動するのに適しています。元に戻す操作やエラーが発生しても、適切に動作する可能性が高くなります。
ジョシュリー

1
Escを<kbd> Cv <kbd /> <kbd> Esc </ kbd>(linux)と入力してみませんか。Windowsは、全面的に<kbd> Cv <kbd />を<kbd> Cq <kbd />に置き換えますが、挿入/コマンドモードで特別なキーを入力する方法は同じです
sehe

@sehe:ありがとう、その時は知りませんでした。答えを更新しました。
emil.p.stanchev

1
@RafaelRinaldiは、[niv]noremap通常の|挿入|ビジュアルモードのリマップです。<CR>ですCarriage ReturnEnterキー)。
vp_arth 14

1
@vp_arthませんがない
sehe

13

以下を〜/ .vimrcファイルに追加します(n、mのマッピングがないことを確認してください)

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

nキーを押すと、行が下mに移動し、行が上に移動します。


12

コマンドモードで、カーソルを下に移動する行に置き、次に

ddp

説明:ddは、現在の行を一般バッファーに削除し、pはカーソル位置の後、または行全体の場合は1行下に戻します。

多くのドキュメントでは、コマンドpとPに関していくつかの混乱があります。実際には、pはAFTERカーソルとP ATカーソルを貼り付けます。


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

1
vim.wikia.com/wiki/に従って包括的な説明についてはそこを参照してください。
Serge Stroobandt、2015年

Macで<A-something>が機能しない場合、その理由はわかりません。<Cj> <Ck>に置き換えましたが、Ctrlキーを使用するとうまく機能します。
セドリックニコラス



3

.vimrcファイルの最後に次のコードを追加しました。

noremap H ddkkp
noremap N ddp

したがって、「H」と「N」は現在の行をそれぞれ上下に移動します。


HとNは実際に役立つコマンドです(Hはカーソルを画面の上部と先頭に移動し、Nは前の検索結果に移動します)。したがって、別のキーを使用することをお勧めします
villapx

そうですか。また、それらを再構成しました。画面の上部に移動するには、aを押してから上に移動します。私の本では、常に「すべて」を意味します。以前の結果を検索するには、fを押してから左に移動します。Fは検索を表します。しかし、そのようなそれを持っていない人にとっては、ええ..それは有効です。
Fzs2

1

これはWikia記事の例を使用したMacVimの簡易バージョンです(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のコマンドキーです。Windowsの場合、 "C"(Control)、または "A"(Alt)を試してください(たとえば、<CAf>はControl Alt fになります)。

ウィキアの記事はこれらに「= 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のタブ切り替えは次のとおりです(残りは上記の.gvimrcに入れます)。

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

1

vimプラグインunimpaired.vim [eおよび] e


2
これはやり過ぎのようですが、これには完全なプラグインが本当に必要だとは思いません。vimrcの2行は、OPが望むものを正確に実行します
Daniel Gratzer

1

でコマンド:help movevim押すと、結果は次のようになります。

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

例: 現在の行を1行下に移動します=> :m+1

例: 番号100の行を、番号80 =>の行の下に移動し :100 m 80ます。

例: 番号100の行を番号200 =>の行の下に移動し :100 m 200ます。

例: 番号が200の行の下にある[100、120]内の番号の行を移動=> :100,120 m 200


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


0

:m。+ 1または:m.-2は、1行を移動する場合に使用します。これが複数行を移動するためのスクリプトです。ビジュアルモードでは、Alt-up / Alt-downは、ビジュアル選択を含む行を1行上または下に移動します。挿入モードまたは通常モードでは、カウントプレフィックスが指定されていない場合、Alt-up / Alt-downは現在の行を移動します。countプレフィックスがある場合、Alt-up / Alt-downは、現在の行から開始してその行数だけ1行上/下に移動します。

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

0

特定の検索に一致する複数の行でこれを実行する場合:

  • 上::g/Your query/ normal ddpまたは:g/Your query/ m -1
  • ダウン:g/Your query/ normal ddpまたは:g/Your query/ m +1
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.