木曜日, 5月 1, 2025
ホームニューステックニュースNeovim 0.11時代のMasonを使ったLSP設定

Neovim 0.11時代のMasonを使ったLSP設定



Neovim 0.11におけるLSPの設定についてはいくつか素晴らしい記事が書かれていますが、私自身の手でまとめておくことも重要であると考え、記事を書くこととしました。そのため記事の内容に既存の記事と重複する点がございますことをご容赦ください。


今までのNeovimの言語サーバー関連のプラグインは、下記のような関係でした。

  • mason ・・・言語サーバー本体の管理、runtimepathへの格納
  • nvim-lspconfig ・・・言語サーバーの適切なデフォルト設定、Neovimへのアタッチ等を行うための各種ライブラリを内包したフレームワーク
  • mason-lspconfig ・・・lspconfigmasonでインストールされた各種サーバーの橋渡し

このような設定ファイルを書いて設定を行っていました。mason-lspconfigの設定の中に、nvim-lspconfigのメソッドが入り込んでいることがわかります。

設定ファイルが長いため格納します

lsp.lua

require("mason").setup({})
require("mason-lspconfig").setup({
	ensure_installed = {
		"lua_ls",
		"vtsls",
		"volar",
	},
})

require("mason-lspconfig").setup_handlers({
	function(server_name)
		require("lspconfig")[server_name].setup({})
	end,

	["vtsls"] = function()
		require("lspconfig").vtsls.setup({
			filetypes = { "typescript", "javascript", "javascriptreact", "typescriptreact", "vue" },
			settings = {
				vtsls = { tsserver = { globalPlugins = {} } },
			},
			before_init = function(params, config)
				local result = vim.system(
					{ "npm", "query", "#vue" },
					{ cwd = params.workspaceFolders[1].name, text = true }
				)
					:wait()
				if result.stdout ~= "[]" then
					local vuePluginConfig = {
						name = "@vue/typescript-plugin",
						location = require("mason-registry").get_package("vue-language-server"):get_install_path()
							.. "/node_modules/@vue/language-server",
						languages = { "vue" },
						configNamespace = "typescript",
						enableForWorkspaceTypeScriptVersions = true,
					}
					table.insert(config.settings.vtsls.tsserver.globalPlugins, vuePluginConfig)
				end
			end,
		})
	end,

	["lua_ls"] = function()
		require("lspconfig").lua_ls.setup({
			settings = {
				Lua = {
					diagnostics = {
						globals = { "vim" },
					},
				},
			},
		})
	end,
})

内容としては、masonの初期化、mason-lspconfigにサーバーの一覧を渡して自動でインストールさせ、mason-lspconfigの機能を使用して、インストールされたサーバーのループを回し、nvim-lspconfigに入っている初期設定で問題のないものはそのまま、追加で設定が必要なものはそちらの設定を行い、いずれにせよlspconfigに渡してNeovimにアタッチさせる…といったものになっています。

Neovim 0.11でのLSPまわりの変更は、従来nvim-lspconfigを用いて行われてきたNeovimへの言語サーバーのアタッチや、言語サーバーへの設定の受け渡しが、Neovim本体で行えるようになったものです。たとえばmason-lspconfigsetup_handlersメソッドでの自動設定は、以下のように置き換えられるようになりました。

require("mason-lspconfig").setup_handlers({
	function(server_name)
		
		vim.lsp.enable({server_name})
	end,
})

同時にlspconfigは適切なデフォルト設定を提供する設定ファイル集となり、従前使われてきた言語サーバー設定関連のメソッドは将来的に廃止される予定です。

Redditなどでは、昨今Masonのメンテナンスが滞っているのでは、という疑念から、新しい記述への変更が脱Masonとセットにされているような風潮があります。実際miseなどを使うことで、言語サーバーの手動管理の負担は十分に軽減できます。

実際はMasonでインストールできるパッケージのレジストリであるmason-registryは活発な更新が続いており、またMason本体は十分に成熟したプラグインであることから、作者はこれ以上の拡張には保守的なようです。

https://github.com/mason-org/mason-registry

これをどう捉えるかは使い手次第ですが、私は当分の間は言語サーバーの管理にはMasonを使い続けることにしました。

nvim-lspconfigが新しい記法に対応した直後は、対応が間に合わなかった言語サーバーも多くあったため様子見を兼ね、段階的に置き換えを進めていきました。

まずlua_lsだけ新しい記法に変更し、Neovimの設定ファイルを開いて問題なく言語サーバーが作動しているか確認しました。

lsp.lua

require("mason-lspconfig").setup_handlers({
	function(server_name)
		require("lspconfig")[server_name].setup({
			capabilities = blink_capabilities,
		})
	end,
	...
	["lua_ls"] = function()
		vim.lsp.enable("lua_ls")
	end,
})

volar tailwindcss など比較的重要なサーバーが、新しい記法への移行に間に合っていなかったため、https://github.com/neovim/nvim-lspconfig/issues/3705 を確認してそちら以外のサーバーを新記法で有効化するように変更しました。また、各種サーバーの設定はひとまずvim.lsp.configをベタ書きして対応しました。
ポイントとしては、インストールするサーバーをserversテーブルとして定義しておいて、mason-lspconfigの自動インストールとvim.lsp.enableに渡している辺りです。

lsp.lua

function mergeTables(t1, t2)
	local result = {}
	for i = 1, #t1 do
		result[#result + 1] = t1[i]
	end
	for i = 1, #t2 do
		result[#result + 1] = t2[i]
	end
	return result
end

local servers = {
	"intelephense",
	"lua_ls",
	"vtsls",
}


local legacy_servers = {
	"astro",
	"tailwindcss",
	"volar",
}

require("mason").setup()
require("mason-lspconfig").setup({
	ensure_installed = mergeTables(servers, legacy_servers),
})
...
vim.lsp.config("lua_ls", {
	settings = {
		Lua = {
			diagnostics = {
				globals = { "vim" },
			},
		},
	},
})

vim.lsp.enable(servers)
for _, server_name in ipairs(legacy_servers) do
	require("lspconfig")[server_name].setup({
		capabilities = blink_capabilities
	})
end

使っているサーバーの移行が全て完了した後は、legacy_servers関連の記述をすべて除去しました。また設定をベタ書きしていた原因であった問題の対処法が判明したため、言語サーバーに渡す設定を別のファイルに分割しています。

lsp.lua

local servers = {
	"astro",
	"intelephense",
	"lua_ls",
	"tailwindcss",
	"volar",
	"vtsls",
}

require("mason").setup()
require("mason-lspconfig").setup({
	ensure_installed = servers,
})

vim.lsp.enable(servers)

after/lsp/lua_ls.lua

return {
	settings = {
		Lua = {
			diagnostics = {
				globals = { "vim" },
			},
		},
	},
}

最終的にはとてもスッキリした設定ファイルになったので、満足しています。

mason-lspconfigを取り除けるか

一見mason-lspconfigの役割はensure_installedの提供のみになったため、これも置き換えられそうに見えます。

https://github.com/williamboman/mason-lspconfig.nvim/blob/main/lua/mason-lspconfig/ensure_installed.lua

しかしmason内部で使われているパッケージ名とlspconfigで使われている言語サーバーの名称のマッピングなどの処理が行なわれているため、mason-lspconfigについては残しておくことにしました。lazy.nvimのプロファイルを見ても、起動時間への影響はほとんどありません。

各プラグインの役割が明確になったことで、masonを使い続ける場合にも設定がよりシンプルに書けるようになり、設定を行う際の認知負荷も減ったように感じます。

フラッグシティパートナーズ海外不動産投資セミナー 【DMM FX】入金

Source link

Views: 0

RELATED ARTICLES

返事を書く

あなたのコメントを入力してください。
ここにあなたの名前を入力してください

- Advertisment -

Most Popular