Vim と vi は違うエディタということを常日頃から主張している、Vim 使いの「ブイ」(仮名)です。第 9 回目のテーマは「タブ」です。最近のブラウザや IDE、テキストエディタでは当たり前となりつつあるタブ機能ですが、うまく使うと大変便利なものです。特に Vim のタブ機能はコンソール上でも使用可能であるため、みなさんもタブを活用するようにしましょう。
1 タブの使用方法¶
実は、Vim を起動した時点で一つのタブが生成されています。ただし、このままではタブの移動ができず意味がないため、新しいタブを生成してみましょう。:tabnew
コマンドを実行すると、新しいタブを生成することができます。引数なしで :tabnew
コマンドを実行すると、空のバッファが開かれます。タブへの移動後に :edit
でファイルを開くか、:tabnew
の引数にファイル名を指定することで、任意のファイルをタブ内に表示することができます。:tabnew
に引数を指定した場合の挙動は、引数なしの
:tabnew
と :edit
を簡略化した表現だと考えると良いでしょう。
GUI の Vim (gvim) で :tabnew
を実行した場合、GUI のタブが表示されますが、CUI の Vim (vim)で :tabnew
を実行した場合、CUI のタブが表示されます。
タブの切り替えには :tabnext
/ :tabprevious
コマンドを使用します。:tabnext
コマンドは次のタブへの移動、:tabprevious
コマンドは前のタブへの移動です。バッファの切り替え用に、:bnext
/
:bprevious
というコマンドがありますが、:tabnext
/
:tabprevious
コマンドはこれらのタブ版です。タブの一覧は、:tabs
コマンドで表示することができます。タブを閉じるときは、:tabclose
コマンドを用います。
タブの移動には専用のキーマッピングも割り当てられており、gt
や
gT
を入力することで、タブを移動することができます。このキーマッピングが使いにくいのならば、次のように別のキーマッピングを割り当てるとよいです。
nnoremap <C-n> gt
nnoremap <C-p> gT
この例では、Vimperator を真似て <C-n>
/ <C-p>
によりタブが移動できるように設定しています。
2 タブのカスタマイズ¶
タブをせっかく使うのならば、マウスでタブを切り替えたいものです。もちろん、GUI の Vim ならばタブの切り替えにマウスを使うことができます。CUI の Vim も、Vim のマウス連携機能を有効にすることで、CUI 上でタブの切り替えをすることができるようになります。Vim のマウス連携機能を有効にするためには、次の行を .vimrc 内に追加します。
set mouse=a
screen や tmux 上で Vim を使用している場合は、次の設定も追加しておくと良いでしょう。screen 上では Vim がマウスを使えるかどうかをうまく検出できないためです。
set ttymouse=xterm2
タブの表示を変更するためには、’tabline’ と ‘guitablabel’ のオプションを変更します。’tabline’ が CUI のタブページ用の設定で、’guitablabel’
は GUI のタブページ用の設定です。これらのオプションの設定方法は複雑なので、:help tabline
と :help guitablabel
を参照してください。
3 タブとバッファの比較¶
タブもバッファも、「同時に複数のファイルを開く」という目的では同じようなものです。だとすると、バッファの代わりにタブを使う理由とは何でしょうか。
まず、タブの場合開いているファイルの一覧を視覚的に確認することができます。次のタブや前のタブが何であるかも一目で分かります。バッファの場合、順番を忘れたら :ls
で確認をしなければなりません。
さらに、タブ毎にウインドウレイアウトは保存されているので、ウインドウレイアウトをそのままにしたまま、一時的に別のファイルをタブで開くということができます。
ただしタブは大量にタブを開くのには向かないインタフェースです。ウインドウのサイズにもよりますが、おおむね 10 を越えると一覧がみづらくなり、20 を越えると普通のやり方では管理が難しくなるでしょう [1]。
4 タブとウインドウとバッファの比較¶
ウインドウレイアウトを同時に複数保存するための場所がタブなので [2]、タブとウインドウには似た仕様があります。これは幾つかコマンドを実行してみると分かりやすいです。
何かファイルを編集し、保存しない状態で :edit {ファイル名}
を実行してみましょう。保存をしていないと、エラーメッセージが表示され他のバッファの編集ができないはずです。これはバッファを切り替えたときにバッファで使用されていたメモリが解放される仕様のためです [3]。メモリを解放するためには、作業内容を保存しなくてはなりません。「バッファを保存しなければ、他のバッファに切り替えることはできない」という、一見理不尽なこの仕様も、Vim がバッファ切り替え時にメモリを解放する、という仕様と照らし合わせると合理的な動作なのです。
では、その保存していない状態のまま :new {ファイル名}
を実行しましょう。今度は何もエラーメッセージが表示されずにウインドウが分割されると思います。バッファの切り替えとは異なり、ウインドウの生成だとバッファのメモリは解放されないからです。
さらに、バッファを保存していない状態のまま :tabnew {ファイル名}
を実行しましょう。今度もエラーメッセージなく新たなタブが生成されるはずです。タブの生成もウインドウのときと同様にバッファのメモリは解放されないからです。
以上の動作より、バッファの切り替えはタブやウインドウの切り替えと比較して重い処理になるのが分かるかと思います。バッファの切り替え時にはファイルの読み込みコストなどが余分にかかるためです。バッファリスト中にいくらバッファが存在したとしても、ウインドウでバッファを開いていない限り余分なメモリを消費することはほとんどありませんが、その分切り替え時のパフォーマンスには影響が出ているのです。
次回は「diff」について解説する予定です。
[1] | ちなみに、こちらで tabline, statuline を複数行に対応させるパッチが開発されていましたが、開発中止となってしまったようです。https://github.com/vim-jp/issues/issues/225 |
[2] | xyzzy だと、タブと似た機能としてフレームというものがあり、個々のフレームがタブとして視覚的に表示されます。Emacs にもフレーム機能がありますが、他のフレームが視覚的に表示されないので分かりづらいです。ただし Emacsでも拡張機能を導入することでタブのようなものをエミュレーションすることが可能です。 |
[3] | この挙動を変更するためには、.vimrc 内で :set hidden を設定します。’hidden’ オプションをオンにすると、バッファを切り替えたときにメモリを解放しなくなるため、バッファを保存前でもバッファを切り替えることができるようになります。ただし、その分メモリを消費します。 |