こんにちは。ナミレリです。この記事ではNeovimでPythonとLuaのLSP(Language Server Protocol)環境を構築する方法を紹介します。
Neovimは、モダンな機能と拡張性に優れた人気のテキストエディタであり、LSPを利用することで、さらに強力な開発環境を実現できます。
Pythonでプログラミングすることが好きな方、Neovimの設定をLuaでカスタマイズすることが好きな方で、Neovimを使い始めたばかりの方に参考にしていただけるようにしていきます。Neovimの基本的な使い方は知っていることを前提に、LSPの導入方法や基本的な設定について紹介します。
Neovimの初期設定や、Neovimの見た目をかっこ良くする設定は下の記事で紹介していますのでぜひご覧ください。
この記事はこんな人にオススメ
- NeovimでLSP環境を構築したいが難しそう
- Pythonでプログラミングすることが好きな方
- Neovimの設定をLuaでカスタマイズすることが好きな方
- Neovimを使い始めたばかりの方
- Neovimを使い始めたが、より深く活用したいと考えている方
- MacBook Pro 14インチ M1Max(メモリ32GB)
- macOS Ventura 13.3.1
- Parallels Desktop 18 for Mac(Parallelsの公式サイト)
- Neovim NVIM v0.9.0-dev-1368
- Ubuntu22.10
- Neovim NVIM v0.10.0-dev-1444
目次
はじめに
Neovimは、Vimの強力な機能を継承しつつ、拡張性とパフォーマンスを追求したエディタです。そして、その魅力は数多くのプラグインが支えています。プラグインを利用することで、Neovimはまるで無限の可能性を秘めた宝箱のように、目を見張るほどの変貌を遂げます。
この記事では、NeovimでPythonとLuaのLSP(Language Server Protocol)環境を構築する方法を紹介します。
みなさんのNeovimをカスタマイズし、究極にモチベーションが上がるエディタ環境を手に入れてください。
前回はNeovimのモチベーションの上がる見た目の設定を中心に紹介していますので合わせてご覧ください。前回の記事はこちらです。前回までの設定ファイルはこちらです。
LSPを構築するおすすめプラグイン
私のおすすめする(使っている)LSP関連のプラグインや必要なソフトウェアの概要は以下となります。この記事でそれぞれの概要やインストール、設定方法を紹介していきます。
LSP系プラグイン
今回の記事でインストールする、LSP関連のプラグインや必要なソフトウェアです。
カテゴリ | LSP系プラグイン | 説明 |
---|---|---|
管理 | williamboman/mason.nvim | LSP、DAP、リンター、フォーマッター を単一のインターフェースを介して 簡単に管理できるプラグイン |
LSP | williamboman/mason-lspconfig.nvim | masonとnvim-lspconfigを 仲介するプラグイン |
LSP | neovim/nvim-lspconfig | LSPクライアントを簡単に設定する ことができるプラグイン |
LSP | LSPに対応していないツールや カスタム機能を使うための プラグイン | |
ライブラリ | nvim-lua/plenary.nvim | ユーティリティ、ライブラリ |
Python Formatter | black (null_ls.builtins.formatting.black) | Pythonのフォーマッターで null-lsから利用する |
Python Formatter | isort (null_ls.builtins.formatting.isort) | Pythonのフォーマッターで null-lsから利用する |
Python Linter | flake8 (null_ls.builtins.diagnostics.flake8) | Pythonのリンターで null-lsから利用する |
Lua Formatter | stylua (null_ls.builtins.formatting.stylua) | Luaのフォーマッターで null-lsから利用する |
Lua Linter | luacheck (null_ls.builtins.diagnostics.luacheck) | Luaのリンターで null-lsから利用する |
補完系プラグインとアイコン
以下は、補完系の便利で素晴らしいプラグインです。こちらもインストールしていきます。
補完系プラグイン | 説明 |
---|---|
hrsh7th/cmp-nvim-lsp | LSPから提供される補完候補をnvim-cmp で利用するプラグイン |
hrsh7th/cmp-buffer | 現在のバッファにある単語を 補完するプラグイン |
hrsh7th/cmp-path | ファイルシステムの パス補完するプラグイン |
hrsh7th/cmp-cmdline | コマンドラインモードでの 補完機能を提供するプラグイン |
hrsh7th/nvim-cmp | メインの補完プラグインで、 入力補完のためのエンジン |
onsails/lspkind.nvim | vscodeのようなアイコンを追加 するプラグイン |
LSP (Language Server Protocol)とは?
LSP(Language Server Protocol)は、開発ツール(エディタやIDE)とプログラミング言語の実装(言語サーバー)の間で通信を行うためのプロトコルです。
このプロトコルの目的は、エディタと言語サーバーが統一されたインターフェースを介してやりとりできるようにすることで、開発ツールの開発者が言語ごとに異なる機能の実装を繰り返すことなく、さまざまな言語に対応した機能を提供できるようにすることです。
LSPは、Microsoftが2016年に発表し、その後オープンソースコミュニティによって広く支持されるようになりました。LSPによって、エディタは言語サーバーにリクエストを送信し、コード補完、定義ジャンプ、リファクタリング、エラーチェックなどの高度な機能を提供できます。言語サーバーは、対応するプログラミング言語やフレームワークの詳細を理解しており、エディタに情報を提供することで、開発者がより効率的にコーディングできる環境を実現します。
では、NeovimでPythonとLuaのLSP環境を構築していきます。
事前準備
言語サーバのインストールや管理をwilliamboman/mason.nvimを使って簡単に実現します。
そのための事前準備として、npm(Node Package Manager)をインストールしておきます。
npmのインストール
MacとUbuntuのそれぞれの場合で、npmのインストール方法は下の通りです。
Macの場合
brew install npm
Ubuntuの場合
sudo apt install npm
npmのバージョン確認
インストールしたnpmのバージョンを確認しておきます。
npm -v
9.6.4
npmは、一言で言うとNode.jsで使用されるパッケージ管理システムです。
npmを使うことで、他の開発者が作成したコード(パッケージやモジュール)を簡単にインストール、管理、アップデート、削除することができます。
補完系プラグインとアイコンのインストール
LSPの構築の前に、補完系プラグインとアイコンのインストールしておきます。インストールするプラグインは下記です。
補完系プラグイン | 説明 |
---|---|
hrsh7th/cmp-nvim-lsp | LSPから提供される補完候補をnvim-cmp で利用するプラグイン |
hrsh7th/cmp-buffer | 現在のバッファにある単語を 補完するプラグイン |
hrsh7th/cmp-path | ファイルシステムの パス補完するプラグイン |
hrsh7th/cmp-cmdline | コマンドラインモードでの 補完機能を提供するプラグイン |
hrsh7th/nvim-cmp | メインの補完プラグインで、 入力補完のためのエンジン |
onsails/lspkind.nvim | vscodeのようなアイコンを追加 するプラグイン |
この記事ではパッケージマネジャーはpacker.nvimを使いますが、お気に入りのパッケージマネージャを使ってインストールしていただいてOKです。
~/.config/nvim/lua/plugins.luaの編集
下のように、~/.config/nvim/lua/plugins.luaを編集し、最下部のend)より前に追加します。
vi ~/.config/nvim/lua/plugins.lua
use("hrsh7th/cmp-nvim-lsp")
use("hrsh7th/cmp-buffer")
use("hrsh7th/cmp-path")
use("hrsh7th/cmp-cmdline")
use("hrsh7th/nvim-cmp")
use("onsails/lspkind.nvim")
:PackerInstallする
保存後にnvimを立ち上げ直すか、:source %で再読み込みし、:PackerInstallするとplugins.luaに書かれていて、インストールされていないプラグインをインストールしてくれます。
:PackerInstall
補完系のプラグインとアイコンがインストールされました。
hrsh7th/nvim-cmpの設定
補完系の設定ファイルは、~/.config/nvim/lua/nvim_cmp_config.luaを作成して設定します。
nvim-cmpの公式を参考に設定していきます。
vi ~/.config/nvim/lua/nvim_cmp_config.lua
-- Set up nvim-cmp.
local cmp = require("cmp")
cmp.setup({
snippet = {
expand = function(args)
-- for luasnip
require("luasnip").lsp_expand(args.body)
end,
},
window = {
completion = cmp.config.window.bordered(),
documentation = cmp.config.window.bordered(),
},
mapping = cmp.mapping.preset.insert({
["<C-b>"] = cmp.mapping.scroll_docs(-4),
["<C-f>"] = cmp.mapping.scroll_docs(4),
["<C-Space>"] = cmp.mapping.complete(),
["<C-e>"] = cmp.mapping.abort(),
["<CR>"] = cmp.mapping.confirm({ select = true }),
}),
sources = cmp.config.sources({
{ name = "nvim_lsp" },
{ name = "luasnip" }, -- for luasnip
}, {
{ name = "buffer" },
}),
})
onsails/lspkind.nvimの設定
次に、lspkind.nvimの設定です。再度~/.config/nvim/lua/nvim_cmp_config.luaを開き、公式を参考に下のようにonsails/lspkind.nvimの設定を追加します。
vi ~/.config/nvim/lua/nvim_cmp_config.lua
-- Set up lspkind.
local lspkind = require("lspkind")
cmp.setup({
formatting = {
format = lspkind.cmp_format({
mode = "symbol",
maxwidth = 50,
ellipsis_char = "...",
before = function(entry, vim_item)
return vim_item
end,
}),
},
})
~/.config/nvim/init.luaの編集
下のようにinit.luaを編集し、起動時に~/.config/nvim/lua/nvim_cmp_config.luaを読み込むようにします。
vi ~/.config/nvim/init.lua
require("nvim_cmp_config")
試しに:Paと入力してTabを押すと自動で補完されることが確認できると思います。
Masonのインストール
それでは、williamboman/mason.nvimとwilliamboman/mason-lspconfig.nvimとneovim/nvim-lspconfigの3つのプラグインを一気にインストールします。
williamboman/mason.nvimは、LSP、DAP、リンター、フォーマッターを単一のインターフェースを介して簡単に管理できるプラグイン。
williamboman/mason-lspconfig.nvimは、masonとnvim-lspconfigを仲介するプラグイン。
neovim/nvim-lspconfigは、LSPクライアントを簡単に設定することができるプラグイン。
公式リポジトリ
williamboman/mason-lspconfig.nvim
Masonのインストールと設定
では、williamboman/mason.nvimとwilliamboman/mason-lspconfig.nvimとneovim/nvim-lspconfigの3つのプラグインを一気にインストールします。
この記事ではパッケージマネジャーはpacker.nvimを使いますが、お気に入りのパッケージマネージャを使ってください。
~/.config/nvim/lua/plugins.luaの編集
下のように、~/.config/nvim/lua/plugins.luaを編集し、最下部のend)より前に追加します。
vi ~/.config/nvim/lua/plugins.lua
use({
"williamboman/mason.nvim",
"williamboman/mason-lspconfig.nvim",
"neovim/nvim-lspconfig",
})
:PackerInstallする
保存後にnvimを立ち上げ直すか、:source %で再読み込みし、:PackerInstallするとplugins.luaに書かれていて、インストールされていないプラグインをインストールしてくれます。
:PackerInstall
3つのプラグインがインストールされました。
Language Serverのインストールと設定
マイクロソフトが開発する高性能なPython用静的型チェッカーであるpyrightとLua言語サーバーであるlua_lsをMasonでインストールしていきます。
~/.config/nvim/lua/lsp_config.luaの作成
LSP関連の設定は、設定する項目も多くなり他のプラグインの設定と分けておくと便利です。ディレクトリの構成は下のようにします。
~/.config/nvim/
├── init.lua
└── lua/
├── lsp_config.lua
├── nvim_cmp_config.lua
├── keymaps.lua
├── options.lua
└── plugins.lua
それでは、LSP関連の設定ファイルとして使う~/.config/nvim/lua/lsp_config.luaを作成します。
vi ~/.config/nvim/lua/lsp_config.lua
require("mason").setup()
require("mason-lspconfig").setup({
ensure_installed = {
"pyright",
"lua_ls",
},
})
require("lspconfig").pyright.setup({})
require("lspconfig").lua_ls.setup({
settings = {
Lua = {
diagnostics = {
globals = { "vim" },
},
},
},
})
pyrightとは、マイクロソフトが開発する高性能なPython用静的型チェッカーです。
lua_lsとは、Lua言語サーバーであるlua-language-serverのことです。
~/.config/nvim/lua/init.luaの編集
下のようにinit.luaを編集し、先程作成した~/.config/nvim/lua/lsp_config.luaを読み込むようにします。
vi ~/.config/nvim/init.lua
require("lsp_config")
その他のLanguage Serverについて
pyrightとlua_ls以外に、bashls、yamlls、jsonls、taplo、rust_analyzerをインストールし設定しています。
LSP | 用途 |
---|---|
pyright | Python言語のためのLSPサーバー |
lua_ls | Lua言語のためのLSPサーバー |
bashls | BashスクリプトのためのLSPサーバー |
yamlls | YAMLファイルのためのLSPサーバー |
jsonls | JSONファイルのためのLSPサーバー |
taplo | TOMLファイルのためのLSPサーバー |
rust_analyzer | Rust言語のためのLSPサーバー |
~/.config/nvim/lua/lsp_config.luaを下のようにしています。
require("mason").setup()
require("mason-lspconfig").setup({
ensure_installed = {
"pyright",
"lua_ls",
-- 以下を追加
"bashls",
"yamlls",
"jsonls",
"taplo",
"rust_analyzer",
},
})
require("lspconfig").pyright.setup({})
require("lspconfig").lua_ls.setup({
settings = {
Lua = {
diagnostics = {
globals = { "vim" },
},
},
},
})
-- 以下を追加
require("lspconfig").bashls.setup({})
require("lspconfig").yamlls.setup({})
require("lspconfig").jsonls.setup({})
require("lspconfig").taplo.setup({})
require("lspconfig").rust_analyzer.setup({})
Masonでリンターとフォーマッターをインストールする
次に、nvimを立ち上げてMasonでリンターとフォーマッターをインストールしていきます。nvimで:MasonでMasonを立ち上げてみましょう。
【Python】リンターとフォーマッターをインストール
Masonの画面で/で検索ボックスを表示し、black、isort、flake8を検索します。iでカーソルの位置のパッケージをインストールすることができるので、検索を確定させてiを押します。
black、isort、flake8の3つのパッケージをiでインストールしたら、数字の1で最上部にジャンプします。
下のキャプチャのようにblack、isort、flake8の3つのパッケージがインストールされていることを確認します。
Masonのインタフェースを起動しなくても、下のようにコマンドでパッケージインストールすることもできます。
:MasonInstall black isort flake8
【Lua】リンターとフォーマッターをインストール
事前準備:Mac
brew install luarocks
事前準備:Ubuntu
sudo apt install luarocks
先程と同じように、Masonの画面で/で検索ボックスを表示し、stylua、luacheckを検索します。
これちらも先程と同じように、iでカーソルの位置のパッケージをインストールすることができるので、検索を確定させてiを押します。
下のキャプチャのようにstylua、luacheckの2つのパッケージがインストールされていることを確認します。
Masonのインタフェースを起動しなくても、下のようにコマンドでパッケージインストールすることもできます。
:MasonInstall stylua luacheck
その他のリンターとフォーマッター
PythonとLua以外に、bashls、yamlls、jsonls、taplo、rust_analyzerの言語サーバ用のリンターをフォーマッターをインストールしています。必要に応じて:MasonInstallコマンドでインストールすることができます。
言語サーバ | 言語 | リンター | フォーマッター |
---|---|---|---|
pyright | python | flake8 | black、isort |
lua_ls | lua | luacheck | stylua |
bashls | bash | shellcheck | shfmt |
yamlls | yaml | yamllint | prettier |
jsonls | json | prettier | |
taplo | toml | prettier | |
rust_analyzer | rust |
:MasonInstall shellcheck shfmt yamllint prettier
リンターとフォーマッターを設定する
次に、インストールしたPython用とLua用のリンターとフォーマッターを設定しnull-lsで使えるようにします。
~/.config/nvim/lua/plugins.luaの編集
下のように、~/.config/nvim/lua/plugins.luaを編集し、最下部のend)より前に追加します。
vi ~/.config/nvim/lua/plugins.lua
use({ "jose-elias-alvarez/null-ls.nvim", requires = "nvim-lua/plenary.nvim" })
:PackerInstallする
保存後、nvimを立ち上げ直すか、:source %で再読み込みし、:PackerInstallします。
:PackerInstallするとplugins.luaに書かれていて、インストールされていないプラグインをインストールしてくれます。
:PackerInstall
~/.config/nvim/lua/lsp_config.luaの編集
~/.config/nvim/lua/lsp_config.luaにPython用とLua用のリンターとフォーマッターの設定を入れます。
vi ~/.config/nvim/lua/lsp_config.lua
local null_ls = require("null-ls")
null_ls.setup({
diagnostics_format = "[#{m}] #{s} (#{c})",
sources = {
null_ls.builtins.formatting.black, -- python formatter
null_ls.builtins.formatting.isort, -- python import sort
null_ls.builtins.diagnostics.flake8, -- python linter
null_ls.builtins.formatting.stylua, -- lua formatter
null_ls.builtins.diagnostics.luacheck, -- lua linter
},
})
その他のリンターとフォーマッターの設定
上記のPythonやlua以外のインストールしたリンターとフォーマッター(shellcheckやprettierなど)の設定を入れます。
local null_ls = require("null-ls")
null_ls.setup({
diagnostics_format = "[#{m}] #{s} (#{c})",
sources = {
null_ls.builtins.formatting.black, -- python formatter
null_ls.builtins.formatting.isort, -- python import sort
null_ls.builtins.diagnostics.flake8, -- python linter
null_ls.builtins.formatting.stylua, -- lua formatter
null_ls.builtins.diagnostics.luacheck, -- lua linter
-- 以下を追加
null_ls.builtins.formatting.shfmt, -- shell formatter
null_ls.builtins.diagnostics.shellcheck, -- shell linter
null_ls.builtins.code_actions.shellcheck, -- shell
null_ls.builtins.formatting.prettier,
null_ls.builtins.formatting.taplo, -- toml formatter
null_ls.builtins.diagnostics.yamllint, -- yaml linter
},
})
LSPの完成
補完の確認
PythonやLuaのファイルを開いてみます。VSCodeのように補完されていると思います。感動しますね。
リンターとフォーマッターの確認
PythonやLuaのファイルを開くと、ワーニングやエラーなど視覚的に表示してくれています。ステータスバーにはエラーやワーニングの数が表示されます。
キーマップの設定
最後に、以下のサイトを参考に、LSPの一般的なキーマップを設定しておきます。たくさんのキーマップを設定しますのでひとつひとつ試してもらいつつも、中でもspace + fでフォーマットできるのはとても便利です。
vi ~/.config/nvim/lua/keymaps.lua
-- Global mappings.
-- See `:help vim.diagnostic.*` for documentation on any of the below functions
vim.keymap.set('n', '<space>e', vim.diagnostic.open_float)
vim.keymap.set('n', '[d', vim.diagnostic.goto_prev)
vim.keymap.set('n', ']d', vim.diagnostic.goto_next)
vim.keymap.set('n', '<space>q', vim.diagnostic.setloclist)
-- Use LspAttach autocommand to only map the following keys
-- after the language server attaches to the current buffer
vim.api.nvim_create_autocmd('LspAttach', {
group = vim.api.nvim_create_augroup('UserLspConfig', {}),
callback = function(ev)
-- Enable completion triggered by <c-x><c-o>
vim.bo[ev.buf].omnifunc = 'v:lua.vim.lsp.omnifunc'
-- Buffer local mappings.
-- See `:help vim.lsp.*` for documentation on any of the below functions
local opts = { buffer = ev.buf }
vim.keymap.set('n', 'gD', vim.lsp.buf.declaration, opts)
vim.keymap.set('n', 'gd', vim.lsp.buf.definition, opts)
vim.keymap.set('n', 'K', vim.lsp.buf.hover, opts)
vim.keymap.set('n', 'gi', vim.lsp.buf.implementation, opts)
vim.keymap.set('n', '<C-k>', vim.lsp.buf.signature_help, opts)
vim.keymap.set('n', '<space>wa', vim.lsp.buf.add_workspace_folder, opts)
vim.keymap.set('n', '<space>wr', vim.lsp.buf.remove_workspace_folder, opts)
vim.keymap.set('n', '<space>wl', function()
print(vim.inspect(vim.lsp.buf.list_workspace_folders()))
end, opts)
vim.keymap.set('n', '<space>D', vim.lsp.buf.type_definition, opts)
vim.keymap.set('n', '<space>rn', vim.lsp.buf.rename, opts)
vim.keymap.set({ 'n', 'v' }, '<space>ca', vim.lsp.buf.code_action, opts)
vim.keymap.set('n', 'gr', vim.lsp.buf.references, opts)
vim.keymap.set('n', '<space>f', function()
vim.lsp.buf.format { async = true }
end, opts)
end,
})
Lspinfoに枠線を付ける
:LspinfoでLSPの情報を見ることができますが、枠線が付いていなくて若干見づらいと思います。
以下のようにすると:LspinfoのLSPの情報に枠線を付けることができます。
~/.config/nvim/lua/lsp_config.luaに以下の設定を入れます。
vi ~/.config/nvim/lua/lsp_config.lua
require('lspconfig.ui.windows').default_options.border = 'single'
Masonにも枠線を付ける
同じように、Masonもデフォルトでは枠線が付いていなくて若干見づらいと思います。
以下のようにすると:Masonに枠線を付けることができます。
~/.config/nvim/lua/lsp_config.luaに以下の設定を入れます。
vi ~/.config/nvim/lua/lsp_config.lua
require("mason").setup({
ui = {
border = 'single',
},
})
参考サイト(公式リポジトリ)
LSP系プラグイン | 説明 |
---|---|
williamboman/mason.nvim | LSP、DAP、リンター、フォーマッター を単一のインターフェースを介して 簡単に管理できるプラグイン |
williamboman/mason-lspconfig.nvim | masonとnvim-lspconfigを 仲介するプラグイン |
neovim/nvim-lspconfig | LSPクライアントを簡単に設定する ことができるプラグイン |
jose-elias-alvarez/null-ls.nvim | LSPに対応していないツールや カスタム機能を使うための プラグイン |
nvim-lua/plenary.nvim | ユーティリティ、ライブラリ |
補完系プラグイン | 説明 |
---|---|
hrsh7th/cmp-nvim-lsp | LSPから提供される補完候補をnvim-cmp で利用するプラグイン |
hrsh7th/cmp-buffer | 現在のバッファにある単語を 補完するプラグイン |
hrsh7th/cmp-path | ファイルシステムの パス補完するプラグイン |
hrsh7th/cmp-cmdline | コマンドラインモードでの 補完機能を提供するプラグイン |
hrsh7th/nvim-cmp | メインの補完プラグインで、 入力補完のためのエンジン |
onsails/lspkind.nvim | vscodeのようなアイコンを追加 するプラグイン |
【おまけ】RustのLSP環境
参考までに、RustのLSPであるrust-analyzerをインストール・設定してみます。
Masonでrust-analyzerをインストールして、下のコードをlsp_config.luaに追加するだけ使えます。
require("lspconfig").rust_analyzer.setup ({})
最後に
最後まで読んでいただきありがとうございます。【Mac】NeovimでPythonとLuaのLSP環境を構築する方法はいかがでしたでしょうか。
NeovimやVimは自分好みにとことんカスタマイズできる使いやすいテキストエディターです。最初は独特の操作を覚える必要がありますが、一度覚えると無くてはならない存在になり、魅力的なエディターになることは間違いないのでぜひ活用してみてください。
NeovimとHHKBの組み合わせは、コーディング体験を最適化し、より生産的で満足のいくものにするための最高のツールです。コーディングの楽しさと効率性を新たなレベルへと引き上げてくれます。
neovim関連記事
Neovimをかっこ良くクールに使う設定