🐷

バッファ切り替えをもっと便利に!tabLocalBuffer.nvim

に公開

やりたいことはバッファのグループ化

Neovimで作業するの楽しいなぁ。
楽しすぎていろんなファイル開き過ぎてバッファ移動が面倒になることってありますよね。
自分は今までtelescope.nvimのバッファ検索をよく使ってました。がバッファ移動時に検索作業を入れるのがあまり本質っぽくないなと。
そこでバッファの移動を少し便利にできないかなと思いいろいろ考えました。

で思ったのが、タブを使ってバッファをグループ化するという考えです。
グループ化とはどういうことかというとNeovim の標準のタブ切り替えコマンド :bnext / :bprevious をタブごとに閉じた形で扱えるようにするという感じです。

もちろん単純な切り替えスピードでいうとtelesope.nvimを使ったバッファ切り替えのほうが早いですが、
タブごとに緩いグループを決めることで作業者の頭も整理できるのではないか?あとタブ移動とバッファ移動コマンドだけで完結するのがスムーズなフローを感じられる気がする

そんな思いで作りました!(AIフル活用)

https://github.com/akasataikisiti/tabLocalBuffer.nvim

できること

主な機能は上で書いた通りですが。バッファをタブでグループ化するときに使えるエディタ機能も備えています。
使用感は以下の通りです。

使用例

コマンドは次の通りです。

移動系
  • :TabLocalBnext
    :bnext のタブローカル版

  • :TabLocalBprevious
    :bpreb のタブローカル版

タブ操作系
  • :TabLocalMoveToNewTab
    現在のウィンドウのバッファを元に新しいタブを作る

  • :TabLocalEditTabBuffers
    タブ、バッファのグループ化をするためのエディタを開く

バッファ削除系
  • :TabLocalDeleteBuffer
    バッファを削除する(ただし所属するタブに別のバッファがある場合はタブを閉じない)

  • :TabLocalWriteDetachBuffer
    バッファを保存して削除する(ただし所属するタブに別のバッファがある場合はタブを閉じない)

  • :TabLocalDetachBuffer
    バッファを所属タブから外す。バッファ自体は閉じない

設定例

導入は lazy.nvim ならこんな形です。

{
  "akasataikisiti/tabLocalBuffer.nvim",
  config = function()
    require("tablocal_buffer").setting({
      keymaps = {
        bnext = "<S-l>",
        bprevious = "<S-h>",
        move_to_new_tab = "st",
        open_editor = "<M-a>",
      },
    })
  end,
}

設定では各コマンドコマンドに対するキーマッピングの割り当てができます。

タブ情報の編集エディタについて

:TabLocalEditTabBuffers を実行するとタブとバッファの紐づけをテーブル形式で編集することができるようになります。
これを実行すると、各タブの所属バッファを Lua テーブルとして編集できるフローティングウィンドウが開きます。

:TabLocalEditTabBuffers
return {
  groups = {
    { "init.lua", "README.md" },
    { "main.ts", "test.ts" },
  },
  unassigned = {
    "scratch.txt:18",
  },
}

この例ではタブが二つ作られそれぞれのタブに二つのバッファが紐づきます。
またunassignedはどこにも所属していないバッファになります。

groups がタブごとのバッファ集合で、unassigned がどのタブにも所属していないバッファです。
これを編集して閉じる(:q)と、その内容が各タブへ反映されます。

groupsテーブルの要素数を増やすとその分タブが作られます。

バッファの表示名

バッファライン上にそのバッファがどのタブに表示しているのかを表示させるためにget_buf_tabnrというAPIを公開しています。

私はバッファラインの表示にbufferline.nvimというプラグインを使用しているのですが、以下のような設定でバッファ名を編集しています。

bufferline.setup({
  options = {
    ...
    name_formatter = function(buf)
      local ok_tablocal, tablocal = pcall(require, "myplugs.tablocal_buffer")
      if not ok_tablocal then
        return buf.name
      end

      local tnr = tablocal.get_buf_tabnr(buf.bufnr)
      if tnr then
        return string.format("#%d %s", tnr, buf.name)
      else
        return buf.name
      end
    end,
...
  },
})

この設定で#1 init.lua,#2 README.md みたいに所属するタブがわかるようにしています。

本当は所属するタブごとにタブの色わけとかできたらいいなぁと思ったのですが、bufferline.nvimだとそういう設定ができなそうなので、名前表示で対応しました。
もしこういう設定ができそうなプラグイン等があったら教えてほしいです。

改善点

  • タブローカルバッファの情報を保持したセッションセーブ・ロード機能みたいなのが欲しい。
  • 複数のファイルを渡してneovimを立ち上げたとき。全部のバッファをタブ1に所属させる。
  • delete系コマンドに対するマッピング設定ができない

おわりに

大量に開いたバッファの管理に苦労している人がいたらぜひtabLocalBuffer.nvimを試してみてください!
telescope.nvimなどと併用してもいいと思います。私も結局は併用しています。
若干まだ動作が安定してないなかったりしますが、その時はissueを立ててもらえたらうれしいです。

それでは!三 `・ω・)シュバッ

Discussion