← Vim研究所

Vimでウインドウの位置を入れ替える方法(Ctrl-w r/x/K/J/H/L)

2026-08-03 公開 ・ 更新: 2026-09-03

画面分割したウインドウを1回で狙ったレイアウトにするのは難しいです。かといって、いちいち閉じて開き直すのはスマートではありません。位置を入れ替えるキーバインドを覚えておけば、後からレイアウトを調整できます(ウインドウ間の移動と組み合わせるとさらに扱いやすくなります)。

目次(8項目)
キーこれだけ覚える
Ctrl-w r / Ctrl-w R同じ段・列で位置を回転させる
Ctrl-w x隣のウインドウと中身を入れ替える
Ctrl-w K/J/H/L端へ移動してレイアウトごと変える
Ctrl-w T今のウインドウを新しいタブへ切り出す
Ctrl-w =全ウインドウのサイズを揃える

ウインドウを回転させる

Ctrl-w r   " 下/右へ回転
Ctrl-w R   " 上/左へ回転
BEFORE
┌───┬───┬───┐
│A │ B │ C │
└───┴───┴───┘
Ctrl-w r
AFTER
┌───┬───┬───┐
│ C │A │ B │
└───┴───┴───┘

同じ段・列にあるウインドウ同士で、位置を1つずつ回転させます。カーソルは同じ内容(上の例ではA)にとどまったまま、位置だけが隣へ動きます。水平分割と垂直分割が混ざっている場合は、カレントウインドウと同じ段・列の中だけが対象になります。ただし相手が1枚のウインドウでないと回転そのものが断られるので、その条件は後の節で確かめます。

実際に数えてみます。vim -Nu NONE a.txt で起動して :split b.txt :split c.txt と2回重ねると、上から 1:c.txt 2:b.txt 3:a.txt の3分割になります(winnr()winbufnr() で数えた並びです)。ここで Ctrl-w r を押すと 1:a.txt 2:c.txt 3:b.txt に変わり、winnr() は1から2になりました。カーソルは c.txt に乗ったまま、その c.txt が1番目から2番目へずれた形です。

回転で動くのは中身だけではありません。:resize 5 で1番目を5行に縮めた状態、つまり高さが上から 5 / 19 / 11 の状態で Ctrl-w r を押すと、高さは 11 / 5 / 19 になります。winheight() で見ると、5行に縮めた c.txt は2番目へ移っても5行のままです。枠の中身だけを交換しているのではなく、ウインドウが自分の大きさを抱えたまま席を1つずつずれていきます。大きく開いておいたウインドウを別の位置へ振り分けたいとき、この性質のおかげでリサイズをやり直さずに済みます。

カウントを付けると、その回数だけ回ります。4分割にして上から d.txt c.txt b.txt a.txt を並べ、2Ctrl-w r を押すと b.txt a.txt d.txt c.txt になりました。Ctrl-w R は逆向きなので、押しすぎたときの巻き戻しに使えます。3分割で Ctrl-w r を2回押した状態から Ctrl-w R を1回押すと、1回だけ押したときと同じ並びに戻ります。

隣のウインドウと入れ替える

Ctrl-w x
Ctrl-w Ctrl-x

カレントウインドウと次(1つ下)のウインドウを入れ替えます。次のウインドウがない場合は前(1つ上)のウインドウが相手になります。回転と違い、カーソルは画面上の同じ位置に残ります。

Ctrl-w x はバッファだけを差し替えているように見えますが、win_getid() でウインドウ番号を見ると、動いているのはウインドウそのものです。先ほどと同じ3分割(1:c.txt がid1002、2:b.txt がid1001、3:a.txt がid1000)で1番目にカーソルを置いて Ctrl-w x を押すと、並びは 1:b.txt がid1001、2:c.txt がid1002、3:a.txt がid1000になりました。winnr() は1のままなのに win_getid() は1002から1001へ変わっています。カーソルは画面上の枠に居残り、相手のウインドウがそこへ入ってくる動きです。

2分割では入れ替えた後の見た目が同じなので、この違いには気づけません。上下2分割の1番目から Ctrl-w r を押すと winnr() は2になり、同じ状態から Ctrl-w x を押すと1のままでした。3分割以上にすれば並び自体も変わるので、rは全員が1つずつずれ、xは2枚だけが入れ替わる、という差もはっきり見えます。

最後のウインドウには次がないため、そこでは1つ前と入れ替わります。3分割の3番目(a.txt)にカーソルを置いて Ctrl-w x を押すと 1:c.txt 2:a.txt 3:b.txt になり、a.txtが2番目へ上がってきました。カウントを付ければ離れた相手を直接指定でき、1番目で 3Ctrl-w x を押すと1番目と3番目が入れ替わります。数がウインドウの本数を超えた場合、たとえば3分割で 9Ctrl-w x を押したときは、エラーメッセージも出ないまま何も起きませんでした。

要点:多いウインドウの中で左右に並び替えたいならCtrl-w r/R、隣と1つだけ入れ替えたいならCtrl-w xを使います。

同じ動きはEx版の :wincmd x:wincmd r でも呼べます。前置した数がそのままカウントになるので、:3wincmd x は3番目のウインドウとの交換です。3番目にカーソルがある状態で :1wincmd x を打つと1番目と入れ替わり、winnr() は3のままでした。相手を番号で名指しできるぶん、キーマップや関数に埋め込むときはEx版のほうが読みやすくなります。

" 今のウインドウを一番上のウインドウと入れ替える
nnoremap <Leader>wt :1wincmd x<CR>

回転も入れ替えも断られる配置がある

水平分割と垂直分割が混ざると、Ctrl-w rCtrl-w x も拒否されることがあります。上段に1枚、下段を左右に割った3分割を作って試しました。

:botright split b.txt
:vsplit c.txt

この状態で :echo winlayout() を打つと、いちばん外側が縦並びを表す col で、その中に上段のa.txtを指す leaf と、下段の2枚をひとまとめにした row が並びます。上段のa.txtから見た同じ列の顔ぶれは「a.txt」と「下段のかたまり」の2つで、後者はウインドウ1枚ではありません。ここで Ctrl-w r を押すと E443: Cannot rotate when another window is split が出ました。Ctrl-w x でも同じE443が返り、Neovim 0.12.4でも番号と文面はまったく同じでした。

同じレイアウトでも、下段のc.txtにカーソルを置けば Ctrl-w x は通ります。c.txtとb.txtは row の中に並んだ2枚なので、交換する相手が1枚に定まるからです。E443を見たら「自分と同じ行・列に、さらに分割されたかたまりが居る」と読み替えると、原因の見当がすぐ付きます。winlayout() を打って rowcol の入れ子を数えるのがいちばん確実です。

入れ子をほどきたいときは、winlayout()のいちばん外側と同じ向きへ寄せます。この配置なら外側がcolなので、上下へ送るCtrl-w KCtrl-w Jを押したときだけ3枚が平らに並び、回転も交換も通るようになります。左右へ送るCtrl-w HCtrl-w Lでは、内側にrowがもう1枚できるだけで入れ子が残り、続けてCtrl-w rを押してもE443のままでした。

端に移動して最大化する

回転や入れ替えだけでは実現できないレイアウト変更には、次のキーが使えます。

Ctrl-w K   " 最上段へ移動し、幅を最大化
Ctrl-w J   " 最下段へ移動し、幅を最大化
Ctrl-w H   " 最左列へ移動し、高さを最大化
Ctrl-w L   " 最右列へ移動し、高さを最大化

これは実質的に、カレントウインドウをいったん閉じてからtopleft splitのような形で新しく開き直すのと同じ動作です。垂直分割になっているウインドウを水平分割のレイアウトに変えたい(あるいはその逆)、といった場面で使えます。新しいウインドウにはカレントウインドウの内容がそのまま表示される点は、閉じて開き直す操作と異なります。

数値で追うと、やっているのは配置の組み替えです。120桁40行の端末で :vsplit を2回して3列にすると、幅は winwidth() で 40 / 39 / 39、高さはどれも37でした。:echo winlayout() の返りは row の下に leaf が3つ並ぶだけの平らな構造です。1列目で Ctrl-w K を押すと、そのウインドウは 120x18 の横長になり、外側が col に変わって、その下に動かしたウインドウの leaf と、残り2つを包む row が入る2階建てになります。

続けて Ctrl-w L を押すと入れ子がほどけて元の平らな row に戻り、動かしたウインドウは右端の 40x37 に落ち着きました。winnr() は3で、カーソルは動かしたウインドウに残ります。Ctrl-w r と違って幅や高さは持ち越されず、移動先で計算し直される点は覚えておいてください。:resize 5 で5行に縮めておいたウインドウを Ctrl-w K で最上段へ送ると、全幅に広がり、高さも周囲と等分に取り直されます。

使いどころは、開く場所を選べないウインドウの後始末です。:help windows を実行すると横分割で開き、手元では上下が 120x20 と 120x16 に分かれました。コードを見ながらヘルプを読みたい場面ではこの形が窮屈なので、Ctrl-w L で右端の縦長へ寄せると視線の移動が減ります。逆に、縦に細く開いてしまった一覧系のウインドウは Ctrl-w J で最下段の横長にすると行が折り返さずに読めます。ウインドウ間のカーソル移動と組み合わせると、キーだけで整理が完結します。

タブページへ独立させる

Ctrl-w T

カレントウインドウを新しいタブページとして独立させます。分割が増えすぎて画面が窮屈になったとき、1つだけタブに切り出して整理するのに使えます。カレントタブページにウインドウが1つしかない場合はこのコマンドは失敗します。

左右2分割の状態から Ctrl-w T を押して確かめると、tabpagenr("$") が2、tabpagenr() も2になり、新しいタブの winnr("$") は1でした。カーソルはそのまま新しいタブへ移り、元のタブは分割が1つ減ります。切り出したバッファが消えるわけではないので、タブの切り替えで行き来しながら作業を続けられます。

ウインドウが1枚しかないタブで押した場合は「Already only one window」と表示されて何も起きませんでした。1枚だけの画面をタブへ移しても元のタブが空になるだけなので、そもそも移す先がないという扱いです。Ex版は :wincmd T で、分割を減らす処理をスクリプトにまとめるときはこちらを使います。

サイズを揃える

Ctrl-w =

入れ替えやリサイズをいろいろ試した後、レイアウトを崩しすぎて元に戻すのが面倒になったら、このキーで全ウインドウのサイズをおおよそ均等に揃えられます。1行ずつ広げたり縮めたりするウインドウサイズの変更は別記事にまとめています。

「おおよそ」と書いたのは、きっちり同じにはならないからです。40行の端末で3分割し、:resize 3 で1つを潰した状態、つまり高さ 3 / 21 / 11 から Ctrl-w = を押すと 12 / 12 / 11 に落ち着きました。画面の高さからステータス行とコマンドラインを引いた残りが3で割り切れないので、端数の1行がどこかに寄ります。winheight() の値が1違うだけなので、読んでいて気になることはありません。

回転や交換のあとにこのキーが要る理由も、前の節の実測どおりです。Ctrl-w rCtrl-w x は大きさごとウインドウを動かすので、細く絞ったウインドウを真ん中へ持ってくると、そこだけ細いままの妙な画面になります。並べ替えはrとxで決めて、最後に Ctrl-w = で整えるという順番にしておくと、途中でサイズを直す手間が消えます。1枚だけ大きく見たいだけなら、今のウインドウ以外を閉じるほうが早い場面もあります。

使ってみて

最初に覚えたのがCtrl-w xだけだったので、上下左右がごちゃ混ぜになった4分割で押してはE443に阻まれていました。エラーの意味が「相手が分割されたかたまりだから」だと分かってからは、まずCtrl-w KCtrl-w Jで入れ子をほどいて平らな並びに戻し、それからCtrl-w rで回す、という順番に落ち着きました。崩れたらCtrl-w =で一度そろえてから調整し直すのが手早いです。マウスでドラッグするより、キーだけでレイアウトが完結するのでホームポジションを崩さずに済みます。

まとめ

ウインドウの入れ替えはCtrl-w r/R/xを使います。同じ行・列の全員を1つずつずらすのがrとR、2枚だけを交換するのがxで、動かしたあとにカーソルが中身について行くか場所に残るかも違います。レイアウト自体を変えたいならCtrl-w K/J/H/L、1枚をタブへ逃がすならCtrl-w T、崩れたらCtrl-w =でリセットできます。

ここまでの数値は、Vim 9.1とNeovim 0.12.4(macOS 26.4.1)を120桁40行の端末に -u NONE で起動して測りました。両者で挙動の差は見つかりませんでした。プラグインを入れた環境では起動時に勝手にウインドウを開くものがあり、そのぶん winnr() の並びは記事の数値とずれます。並び順そのものではなく、rとxのどちらでカーソルが移るか、どういう入れ子でE443が出るか、という読み方をしてください。

関連記事

← Vim研究所 トップへ戻る