[第9回] Neovimのすゝめ – タブを管理する

[第9回] Neovimのすゝめ – タブを管理する

目次

Neovimのタブの概念は違う

タブと聞くとブラウザのタブを想像すると思いますが、Neovimのタブは全くの別物です。
なぜこれをタブと命名したんだと揶揄されるほど誤解を生む原因となっています。

Neovimのタブを理解するには、関連するバッファ・ウィンドウについて理解する必要があります。
公式の解説はNeovim内から以下のヘルプを開くことで確認することが出来ます。

:help windows.txt

要約:
バッファとはメモリに保持しているファイルの内容である。
ウィンドウとはバッファの表示領域である。
タブページとはウィンドウを集めたものである。

ウィンドウはバッファの表示領域である。1つのバッファに対して複数のウィンドウを
開くことができるし、異なる複数のバッファに対して複数のウィンドウを開くこともで
きる。

バッファは編集時にメモリ上にロードされたファイルのことを言う。
オリジナルのファイルはバッファ内容をそのファイルに上書きするまで変更されずにい
る。

分かりやすく解説されているサイトがあるため、併せて確認しましょう。

タブはワークスペース

WindowsやMacなどのOSのウィンドウの概念で例えると分かりやすいでしょう。
Neovimのタブは、OSのワークスペース機能です。

ワークスペースは切り替えると画面全体がスライドして、もう1つのデスクトップが現れます。
つまり、実行しているアプリケーションのウィンドウ郡を保持するセットがワークスペースです。

Neovimのタブはワークスペースです。
決してブラウザ(ウィンドウ)の中でサイト(ファイル)を管理するタブではありません。

タブの切り替えを行うキーはgtですが、面倒だからと<C-h><C-l>に変更する話をよく耳にします。
これはワークスペース機能を無理にタブのように使おうとしているため、本来の用途ではありません。
Neovimのタブはワークスペース相当の機能なので、開いたとしても2,3個、頻繁に行ったり来たりすることもないので gt に振られているのでしょう。

バッファを使いこなす

まず、Neovimのデフォルトではバッファに開かれたファイルを保存していないとバッファの切り替えが出来ないので以下の設定を追加します。

vim.o.hidden = true

そして、バッファの一覧表示や確認をするためにコマンドを一々叩くのは面倒なのでバッファをタブライン(ウィンドウ上部のタブ名を並べる領域)に表示するプラグインを入れます。

ap/vim-buftabline

シンプルにタブラインにバッファを表示します。
タブに番号を振ったり、タブの変更状態に応じて*を表示するなどのオプションが存在します。

Neovimの思想に沿って元々バッファで操作していたようなユーザーにオススメです。

zefei/vim-wintabs

タブラインへのバッファの表示と、ウィンドウごとにスコープを持ちタブラインに表示するバッファを管理します。
例えば、2分割したウィンドウの左側のタブラインにA,Bのバッファ、右側のタブラインにC,D,Eのバッファを表示するようなIDEに近い操作をする場合にオススメです。
沢山のウィンドウを開きながら作業する、ウィンドウ位置でタブを分類するならこちらを入れましょう。

バッファはいくつものウィンドウで開ける

VSCodeはタブが最小単位のため、1つのファイルを複数画面で分割表示するには Ctrl+\でウィンドウを分割する必要があります。
Neovimのバッファはあくまで開かれているファイルというだけでウィンドウと対になるものではありません。
つまり、Neovimのウィンドウを分割するとは新しいウィンドウを作って、そのウィンドウでバッファを開くことを意味します。
ウィンドウとバッファに関連はないので、ウィンドウが2つ、3つとあったとしてもタブラインに表示されるバッファは皆同じです。

※vim-wintabsを使用する場合はウィンドウとバッファが擬似的に関連付けられます。
 擬似的なのでタブラインに表示されていないバッファだとしても指定すれば開けます。

キーマップ

タブラインのバッファを切り替えるために毎回、 :bnext と入力していられません。
以下のようにバッファに関するキーマップを追加しましょう。

api.nvim_set_keymap('n', '<C-n>', '<cmd>bnext<cr>', { noremap = true, silent = true })
api.nvim_set_keymap('n', '<C-p>', '<cmd>bprevious<cr>', { noremap = true, silent = true })
api.nvim_set_keymap('n', '<C-q>', '<cmd>b#<cr><cmd>bd#<cr>', { noremap = true })

 

zefei/vim-wintabsのキーマップ

vim-wintabsを入れている場合、プラグインが各操作をラップしているコマンドをマッピングします。
これらのコマンドで操作することで全てのタブからCloseされた時にバッファから消すか、などのプラグインが提供するオプションの動作に関連してきます。

以下に私の設定値を記載しておきます。

let g:wintabs_autoclose_vim = 1

map <C-n> <Plug>(wintabs_previous) # 前のバッファへ
map <C-p> <Plug>(wintabs_next) # 次のバッファへ
map <C-q> <Plug>(wintabs_close) # 閉じる
map <C-T>u <Plug>(wintabs_undo) # 元に戻す
map <C-T><C-o> <Plug>(wintabs_only) # 現在のバッファ以外閉じる
map <leader>> <cmd>WintabsMove 1<cr> # タブラインの表示位置を右へ移動
map <leader><lt> <cmd>WintabsMove -1<cr> # タブラインの表示位置を左へ移動
map <C-w><C-l> <Plug>(wintabs_move_to_window_right) # 右のウィンドウのタブラインへ移動
map <C-w><C-h> <Plug>(wintabs_move_to_window_left) # 左のウィンドウのタブラインへ移動
map <C-w><C-k> <Plug>(wintabs_move_to_window_above) # 上のウィンドウのタブラインへ移動
map <C-w><C-j> <Plug>(wintabs_move_to_window_below) # 下のウィンドウのタブラインへ移動

 

バッファをファジー検索(あいまい検索)する

バッファをこまめに閉じず、大量に開いて作業をするような方はバッファ一覧を対象にファジー検索して開くバッファを特定すると便利でしょう。
これらのプラグインはfzf等のファジーファインダー系の ファイルをファジー検索して開く プラグインの機能の一つとして追加されていることが多いです。

ファインダープラグインに関しては別途記事に記載したいと思いますが、私はnvim-telescope/telescope.nvimを使用して実現しています。

Neovimのすゝめカテゴリの最新記事