【Neovim】kickstart.nvimをベースにElixirの開発環境を整える

2022/12/28に公開

kickstart.nvimというリポジトリがあり、あらかじめNeovimの代表的なプラグインの設定が入った設定ファイルが公開されています。

コアメンテナーによる解説動画も出されており、init.lua ファイルを置くだけで一通り機能の揃った開発環境を構築できます。この環境を題材に、自分の復習もかねて、Elixirの環境を整える手順についてまとめてみます。

https://www.youtube.com/watch?v=stqUbv-5u2s

Neovimの起動

kickstart.nvim のリポジトリに置いてあるDockerfileを利用して、検証環境を構築します。

$ docker build . -t kickstart.nvim:latest
$ docker run --rm -it kickstart.nvim:latest /bin/sh

# コンテナ内
$ nvim

以下のようなメッセージが表示され、Enterを押してプラグインのインストールが走ればOKです。

==================================
    Plugins are being installed
    Wait until Packer completes,
       then restart nvim
==================================
Press ENTER or type command to continue

以下、コンテナ内で作業を進めます

Elixirのインストール

ElixirのLanguage ServerであるElixirLSを動かすためにはElixirの実行環境が必要です。ここではコンテナ内にElixirをインストールして準備します。Dockerfileを書き換えて再ビルドしても構いません。Elixirの導入はこの記事の主題ではないためサラッと進めます。

$ apk add elixir

検証用Mix Projectの作成

Mixプロジェクトを作成して、初期設定のままElixirファイルを開いてみましょう。

$ mix new sample
$ cd sample
$ nvim lib/sample.ex

ステータスラインやカラースキーマは設定できているものの、Elixirのコードにシンタックスハイライトは効いていません。もちろん補完などもない状態です。これをイイ感じにしていきましょう。

d0c0bdf6-77b9-4d3f-a9ab-a8b47c4a8db2.png

TreesitterにElixirを追加する

kickstartの init.lua にはnvim-treesitterの設定が最初から入っており、設定項目の ensure_installedelixir を追加することでtree-sitterによるハイライトが可能になります。

init.lua を開き、設定を追加します。 help の前あたりに追加してみましょう。

$ nvim ~/.config/nvim/init.lua
-  ensure_installed = { 'c', 'cpp', 'go', 'lua', 'python', 'rust', 'typescript', 'help' },
+  ensure_installed = { 'c', 'cpp', 'go', 'lua', 'python', 'rust', 'typescript', 'elixir', 'help' },

ファイルを保存後、一度Neovimを終了し、再度 .ex ファイルを開くと、シンタックスハイライトが効いています🎉

$ nvim lib/sample.ex

4dc1eda4-3bf1-4143-af61-22f5a76314e6.png

LSP(ElixirLS)を設定する

続いて、LSPを設定してコードジャンプや補完を利用できるようにします。

まずはMason経由でElixirLSをインストールしておきます。Neovimを起動した状態でインストールコマンドを実行します。

:MasonInstall elixir-ls

ウィンドウが開いてインストールが進み、Installed のセクションに elixir-ls が増えていればOKです。

684d57cc-c6ce-40bd-a017-44e67250e8e5.png

$HOME/.local/share/nvim/mason/bin 配下に実行ファイル(中身はシェルスクリプト)があるのを確認しておきましょう。このパスを setup 時の cmd フィールドに指定する必要があります(参考

$ ls /root/.local/share/nvim/mason/bin/
elixir-ls  elixir-ls-debugger  lua-language-server

再び init.lua を変更します。

$ nvim ~/.config/nvim/init.lua

2022/12/28時点でのコードで339行目~371行目付近の mason_lspconfig の設定をいじります。

最終的に require('lspconfig').elixirls.setup { cmd = {...} } のように実行される書き方であればこの辺りは自由に書き換えて問題ないです。

local servers = {
  elixirls = {
    -- MasonInstall elixir-ls でインストールされるElixirLSのシェルファイルを指定する
    cmd = { '/root/.local/share/nvim/mason/bin/elixir-ls' },
  },

  sumneko_lua = {
    settings = {
      Lua = {
        workspace = { checkThirdParty = false },
        telemetry = { enable = false },
      },
    },
  },
}
mason_lspconfig.setup_handlers {
  function(server_name)
    require('lspconfig')[server_name].setup {
      capabilities = capabilities,
      on_attach = on_attach,
      settings = servers[server_name]["settings"],
      -- `cmd` フィールドの設定を追加
      cmd = servers[server_name]["cmd"]
    }
  end,
}

あとは再びNeovimを終了→起動してElixirファイルを開いてみます。

$ nvim lib/sample.ex

試しに Enum と入力してみると、補完が出てきました。LSPの設定が通っています🎉

594ee09a-59af-452b-aea5-3c7a72b29cbe.png

初期設定で入っているkeymapを色々と試してみましょう。Enumにカーソルを置いた状態で K を入力するとドキュメントも確認できます(nmap('K', vim.lsp.buf.hover, 'Hover Documentation')の記述による挙動)

2709e954-f983-4146-b95a-845bce840e3c.png

<leader>ds と入力すると、モジュール、関数の一覧、移動ができます(nmap('<leader>ds', require('telescope.builtin').lsp_document_symbols, '[D]ocument [S]ymbols') の記述による挙動)

840890b3-1381-44ac-aede-810ddd5f4cd4.png

なんらか関数を追加して、関数名にカーソルを置いた状態で gd と入力すると、関数定義へとコードジャンプできます。(nmap('gd', vim.lsp.buf.definition, '[G]oto [D]efinition') の記述による挙動)

fc685ea0-79bb-4dc7-ba52-e172a4cf935b.gif

好きなプラグインを入れる

TreesitterとLSPの設定が終わったら、あとはElixir関連のプラグインを好みで入れたら良いと思います。ちなみに私は vim-elixir の方だけ入れています(多分なくても問題ないかも?)

https://github.com/mhanberg/elixir.nvim
https://github.com/elixir-editors/vim-elixir

kickstart.nvim では .config/nvim/lua/custom/plugins.lua のパスにプラグイン追加用の関数を書いておけば自動でプラグインを追加できる機構になっているため、kickstart.nvim のまま進める場合はそのようにすると良いでしょう。詳細はREADMEを参照してください。

https://github.com/nvim-lua/kickstart.nvim#example-pluginslua

friendly-snippets を入れるとよく使う構文のsnippetが使えて便利です。この辺りもお好みで導入しましょう。

https://github.com/rafamadriz/friendly-snippets/blob/main/snippets/elixir.json

また、null-lsを導入してcredoを実行するというのもアリだと思います。こちらも以前記事にしたので良ければ参考にしてください。

https://zenn.dev/koga1020/articles/583be482690a3c

まとめ

kickstart.nvim の紹介と、Elixirの設定を追加する流れを解説しました。この辺りは情報が少なくて手探りで設定ファイルを書き進めていたので、おさらいも兼ねて動作確認をしてみました。Neovimの検証ができるDockerfileも学べたのも有意義でした。

Happy Hacking!

Discussion