hamakou108 blog

Neovim のカスタマイズ (2024年版)

Cover Image for Neovim のカスタマイズ (2024年版)

久々に Neovim のカスタマイズを行ったので、その内容について記す。

環境

  • macOS (x86_64) Sonoma 14.4.1
  • Neovim v0.9.5

設定テンプレートの選定

Neovim カスタマイズの出発点として、今回は公開されている設定テンプレートから始めることにした。以前にいちから設定を行ったことがあったが、設定方法を調べるのに苦労したり、後から適切な設定が見つかって手戻りしたりと、なんだかんだで時間がかかりすぎて途中で飽きてしまい、挫折してしまった経験がある。設定テンプレートから始めることで、あまり時間をかけすぎずに良い設定方法が見つけられるのではないか、と考えた。カスタマイズが一段落ついた今振り返ってみると、この方針は正解だったように思う。

Neovim の設定テンプレートは幾つか公開されている。中には設定テンプレートというよりは Neovim distribution と呼んだ方が適切なものもあるが、ツール自体に依存せずに中身の設定だけを使い回せそうなものも幾つかあった。候補に上がったのは以下の4つ。

ちなみに GitHub のスター数の遷移は以下の通り。

https://star-history.com/#nvim-lua/kickstart.nvim&AstroNvim/AstroNvim&NvChad/NvChad&LazyVim/LazyVim&Date

悩んだ末、最終的には kickstart.nvim を選んだ。 kickstart.nvim は "a starting point for your configuration" とうたっているだけあって、 Neovim distribution のような Neovim のラッパーではなく、純粋な設定ベストプラクティスのような形になっている。各設定項目に対するドキュメンテーションも充実していることから、今回の取り組みにちょうど良さそうだった。様々なプラグインや Neovim distribution を試してこれが最も自分に適していた、という Reddit の投稿 も後押しになった。

kickstart.nvim の導入

kickstart.nvim の README に従って進めた。 "Recommended Step" として記されている、リポジトリをフォークしてからクローンする方針を採用した。

git clone [email protected]:hamakou108/kickstart.nvim.git
cd kickstart.nvim
git remote add upstream [email protected]:nvim-lua/kickstart.nvim.git
git fetch upstream

さらに自分の場合、個人の dotfiles リポジトリのサブモジュールとして扱うようにした。

サブモジュール化した理由

自分は Neovim を含む CLI ツールの設定を dotfiles リポジトリにまとめている。このリポジトリをクローンして特定のコマンドを叩くと、必要な設定ファイルが適切な場所に展開されるようになっている。 従来通り Neovim の設定も dotfiles を通して管理したいと思い、選択肢として2つの方法を思い浮かべた。

  1. kickstart.nvim のファイル郡を dotfiles にコピペする
  2. kickstart.nvim をフォークしたリポジトリを dotfiles のサブモジュールにする

最終的には方法2を採用した。方法1を採用した場合、 kickstart.nvim のアップデートに追従することが困難になるのが懸念だった。 Neovim 界隈、特にプラグインの栄枯盛衰は早い。 Neovim 本体の機能が充実するにつれてプラグインの種類も増えてきた印象があるが、これらの動きを自分一人で追いかけて Neovim をアップデートし続けるのは困難だと感じている。 kickstart.nvim は使用しているプラグインの動きに合わせて日々更新されており、これに追従すれば最低限は OK という点で方法2に分があった。

ただ、方法2にも懸念はある。本流の kickstart.nvim に追従するということは、フォークしたリポジトリを定期的に sync するということなので、そのときに発生したコンフリクトはその都度解消する必要がある。例えば以下の PR のような breaking change が発生した場合、コンフリクト解消作業はかなり大変そうに思える (この PR は自分がフォークする前にマージされているので、幸いコンフリクトの解消作業は不要だった)。

wip: start exploring some new ideas (Lipo-suction and EVEN MORE LAZY!) by tjdevries · Pull Request #635 · nvim-lua/kickstart.nvim

記事投稿時点で運用を始めてから1ヶ月ほどになるが、大きなコンフリクト解消作業は特に発生していないので、とりあえずこの方針で運用を続けてみるつもりだ。

サブモジュールの管理

まず、メインリポジトリである dotfiles の方に、サブリポジトリであるフォークした kickstart.nvim をサブモジュールとして追加する。

git submodule add [email protected]:hamakou108/kickstart.nvim.git config/nvim

以降、メインリポジトリをクローンする際には基本的に --recursive オプションを付け、サブリポジトリの内容もクローンするように指示する必要がある。

git clone --recursive [email protected]:hamakou108/dotfiles.git

サブリポジトリを更新した場合

例えばフォーク元のリポジトリの更新に追従する場合、サブリポジトリ側を更新することになる。メインリポジトリ側でこの更新を (マージして) 取り込むには、次のコマンドを実行する。

git submodule update --remote --merge

こうすると、サブモジュールの参照するリビジョンが最新のものに更新される。この時点ではステージングされただけの状態なので、忘れずにコミットし、プッシュする。

メインリポジトリ上でサブモジュールを更新した場合

自分の dotfiles は、初期化コマンドを実行すると各ツールの規定の設定ファイル配置先にシンボリックリンクが作成され、リポジトリの内容がリンクを通して参照されるような作りになっている。このため、 Neovim のカスタマイズを行う際はメインリポジトリである dotfiles のサブモジュール内の Neovim 設定ファイルを編集する。このような場合、サブリポジトリ側にその更新を反映する必要がある。

まず、メインリポジトリ上のサブモジュールのディレクトリに入る。すると、メインプロジェクトのブランチとは別にサブモジュール用のブランチを作成できるようになるので、 (なければ) トラッキングブランチと適当な作業用ブランチを作成する。

ファイルの編集、コミットまでは通常通り行えば良い。この更新を次の4箇所に反映する必要がある。

  1. メインプロジェクト
  2. リモートのメインリポジトリ
  3. リモートのサブリポジトリ
  4. ローカルのサブリポジトリ

まず 1 については、メインプロジェクトのディレクトリに移ってコミットすれば良い。 2 と 3 については、次のコマンドでまとめて反映することができる。

git push --recurse-submodules=on-demand

4 については、ローカルのサブリポジトリ上で git pull を叩いて更新を取り込む。

kickstart.nvim のカスタマイズ

さて、肝心な Neovim の話に移っていく。 kickstart.nvim はそれ自体で設定がほぼ完成しているので、特に必要がなければ設定に手を加える必要はない。 Vim を起動すると何かしらエラーが発生し、その解決方法が分からないという事態は Vim カスタマイズあるあるだと思うが、自分の環境では最初から特に問題なく動作して感動した。

入力補完の機能を試している様子
入力補完ができるよ!
構文エラーチェックの機能を試している様子
構文エラーを教えてくれるよ!
全文検索の機能を試している様子
全文検索もできちゃうよ!

Neovim を起動するとプラグインのインストールが自動で開始される。プラグイン管理には folke/lazy.nvim が使用されており、 :Lazy でプラグインのインストール状況を表示できる。

kickstart.nvim の設定ファイルには、設定そのものに加えて非常に充実したコメントが記載されている。そのため kickstart.nvim の内容を理解するには init.lua を上から下まで読むのがベストだと思う。 :Tutor の使い方も載っているので、 Neovim 入門者にも向いている。 Lua の学習リソースが紹介されていた点も、 Lua に馴染みがない自分としては嬉しかった。

すべての設定を紹介するのは大変なので、以降では特に自分がカスタマイズした点について紹介する。

基本機能

Neovim の基本機能については Nerd Font の有効化のみ行った。 Nerd Font をダウンロードして、 vim.g.have_nerd_fonttrue に変更すれば良い。すると、 Fuzzy Finder やステータスライン上に Nerd Font のアイコンが表示されるようになる。

LSP

init.lua の neovim/nvim-lspconfig プラグインの設定内にある servers というテーブルに、必要な LSP サーバーを指定する。 LSP サーバーごとのカスタマイズが特に不要であれば、 LSP サーバー名だけを書いて値は空にしておけば良い。指定したプラグインは mason-tool-installer.nvim によって自動的にインストールされる。カスタマイズする場合、始めから指定されている Lua 用の LSP サーバー lua_ls の設定が参考になるだろう。 lua_ls.settings の部分はどの LSP サーバーでも共通のフォーマットで、その値の部分は各 LSP サーバーのフォーマットになっている。

プロジェクトによっては init.lua の設定だけでなく、プロジェクト側でも設定が必要な場合がある。例えば Pyright を使用する際、 venv などの仮想環境を作成している場合は pyrightconfig.json または pyproject.toml で仮想環境のパスを指定しなければならない。

オプショナル設定の有効化

人によって好みが分かれるような設定はオプショナルとして扱われており、デフォルトでは無効化されている。 init.lua 中で require がコメントアウトされている箇所があり、これを外せば有効化される。自分の場合、デバッグ関連の設定は使わなさそうだったので無効化したままにしておき、それ以外の以下の設定を有効化した。

  • "kickstart.plugins.indent_line"
  • "kickstart.plugins.lint"
  • "kickstart.plugins.autopairs"
  • "kickstart.plugins.neo-tree"
  • "kickstart.plugins.gitsigns"

所感

一通りのカスタマイズが終わり、今のところ特に問題なく利用できている。まだ各設定のキーバインドを覚えきれておらず操作がもたつくこともあるが、 folke/which-key.nvim がキーバインドをサジェスト表示してくれるので、それほど困ってはいない。

キーバインドのサジェストが表示される様子
とりあえずスペースキーを押して、次にどのキーを押せば良いか考えている

ここ数年、プログラミングに利用するエディタは VSCode と JetBrains のいずれかで、 Neovim は少し複雑なテキスト編集時のみ使っていた。今回のカスタマイズで操作感が IDE にかなり近づいたので、徐々に Neovim の使用比率を上げていこうと思う。