【Neovim】`textDocument/documentHighlight`を怒らせずに、カーソル下の変数名をハイライトしたい!
vim初心者の備忘録シリーズ
NeovimのファイラーはFernを使用しているのですが、Fern内でrenameをしようとすると、
CursorHoldI Autocommands for "*" の処理中にエラーが検出されました:
method textDocument/documentHighlight is not supported by any of the servers registered for the current buffer
と怒られることに気がつきました。
色々探っていると、options.lua
で以下のような設定をしていたのが原因だとわかりました。
-- enable highlight
vim.cmd [[
set updatetime=500
augroup lsp_document_highlight
autocmd!
autocmd CursorHold,CursorHoldI * lua vim.lsp.buf.document_highlight()
autocmd CursorMoved,CursorMovedI * lua vim.lsp.buf.clear_references()
augroup END
]]
詳しいことはわかりませんが、Fernのrename画面のfiletypeはfern-replacer
で、これがtextDocument/documentHighlight
に対応していない故のエラーかなと思いました。
この時点のlspの設定
※mason.nvim
, nvim-lspconfig
, null-ls.nvim
, lazy.nvim
を使用しています。
return {
{ "neovim/nvim-lspconfig", event = { "BufReadPre", "BufNewFile" } },
{
"williamboman/mason-lspconfig.nvim",
dependencies = { "williamboman/mason.nvim", "neovim/nvim-lspconfig", "hrsh7th/cmp-nvim-lsp" },
event = { "BufReadPre", "BufNewFile" },
config = function()
require("mason-lspconfig").setup_handlers {
function(server_name)
local opts = {
capabilities = require("cmp_nvim_lsp").default_capabilities(),
}
if server_name == "lua_ls" then
opts.settings = {
Lua = {
diagnostics = { globals = { "vim" } },
format = { enable = false }, -- To prevent indent conflicts with stylua
},
}
end
-- print("Setting up " .. server_name .. " with mason")
require("lspconfig")[server_name].setup(opts)
end,
}
end,
},
{
"jose-elias-alvarez/null-ls.nvim",
event = { "BufReadPre", "BufNewFile" },
config = function()
local null_ls = require "null-ls"
local augroup = vim.api.nvim_create_augroup("LspFormatting", {})
null_ls.setup {
-- If you install something in Mason, you should add it here. Refer to "https://github.com/jose-elias-alvarez/null-ls.nvim/blob/main/doc/BUILTINS.md" for more information.
sources = {
null_ls.builtins.formatting.stylua,
},
on_attach = function(client, bufnr)
if client.supports_method "textDocument/formatting" then
vim.api.nvim_clear_autocmds { group = augroup, buffer = bufnr }
vim.api.nvim_create_autocmd("BufWritePre", {
group = augroup,
buffer = bufnr,
callback = function()
-- on 0.8, you should use vim.lsp.buf.format({ bufnr = bufnr }) instead
-- on later neovim version, you should use vim.lsp.buf.format({ async = false }) instead
vim.lsp.buf.format { async = false }
end,
})
end
end,
diagnostics_format = "#{m} (#{s}: #{c})",
}
end,
},
{
"jay-babu/mason-null-ls.nvim",
dependencies = {
"williamboman/mason.nvim",
"nvim-lua/plenary.nvim",
"jose-elias-alvarez/null-ls.nvim",
},
event = { "BufReadPre", "BufNewFile" },
config = function()
require("mason-null-ls").setup {
automatic_setup = true,
handlers = {},
}
end,
},
}
ここで、この部分に注目してみてください。
null_ls.setup {
-- If you install something in Mason, you should add it here. Refer to "https://github.com/jose-elias-alvarez/null-ls.nvim/blob/main/doc/BUILTINS.md" for more information.
sources = {
null_ls.builtins.formatting.stylua,
},
on_attach = function(client, bufnr)
if client.supports_method "textDocument/formatting" then
vim.api.nvim_clear_autocmds { group = augroup, buffer = bufnr }
vim.api.nvim_create_autocmd("BufWritePre", {
group = augroup,
buffer = bufnr,
callback = function()
-- on 0.8, you should use vim.lsp.buf.format({ bufnr = bufnr }) instead
-- on later neovim version, you should use vim.lsp.buf.format({ async = false }) instead
vim.lsp.buf.format { async = false }
end,
})
end
end,
diagnostics_format = "#{m} (#{s}: #{c})",
}
if client.supports_method "textDocument/formatting" then?
……解決策が見えた気がします。
if client.supports_method "textDocument/formatting" then
みたいなことができるなら、if client.supports_method "textDocument/documentHighlight" then
もできるはずです。
しかし、null-ls
内でやっても仕方がないので、lspconfig
内でやります。
lsp.lua
修正後のreturn {
{ "neovim/nvim-lspconfig", event = { "BufReadPre", "BufNewFile" } },
{
"williamboman/mason-lspconfig.nvim",
dependencies = { "williamboman/mason.nvim", "neovim/nvim-lspconfig", "hrsh7th/cmp-nvim-lsp" },
event = { "BufReadPre", "BufNewFile" },
config = function()
require("mason-lspconfig").setup_handlers {
function(server_name)
local opts = {
capabilities = require("cmp_nvim_lsp").default_capabilities(),
on_attach = function(client, bufnr)
if client.supports_method "textDocument/documentHighlight" then
local lsp_document_highlight = vim.api.nvim_create_augroup("lsp_document_highlight", {})
vim.api.nvim_create_autocmd({ "CursorHold", "CursorHoldI" }, {
group = lsp_document_highlight,
buffer = bufnr,
callback = function()
vim.lsp.buf.document_highlight()
end,
})
vim.api.nvim_create_autocmd({ "CursorMoved", "CursorMovedI" }, {
group = lsp_document_highlight,
buffer = bufnr,
callback = function()
vim.lsp.buf.clear_references()
end,
})
end
end,
}
if server_name == "lua_ls" then
opts.settings = {
Lua = {
diagnostics = { globals = { "vim" } },
format = { enable = false }, -- To prevent indent conflicts with stylua
},
}
end
-- print("Setting up " .. server_name .. " with mason")
require("lspconfig")[server_name].setup(opts)
end,
}
end,
},
{
"jose-elias-alvarez/null-ls.nvim",
event = { "BufReadPre", "BufNewFile" },
config = function()
local null_ls = require "null-ls"
local augroup = vim.api.nvim_create_augroup("LspFormatting", {})
null_ls.setup {
-- If you install something in Mason, you should add it here. Refer to "https://github.com/jose-elias-alvarez/null-ls.nvim/blob/main/doc/BUILTINS.md" for more information.
sources = {
null_ls.builtins.formatting.stylua,
},
on_attach = function(client, bufnr)
if client.supports_method "textDocument/formatting" then
vim.api.nvim_clear_autocmds { group = augroup, buffer = bufnr }
vim.api.nvim_create_autocmd("BufWritePre", {
group = augroup,
buffer = bufnr,
callback = function()
-- on 0.8, you should use vim.lsp.buf.format({ bufnr = bufnr }) instead
-- on later neovim version, you should use vim.lsp.buf.format({ async = false }) instead
vim.lsp.buf.format { async = false }
end,
})
end
end,
diagnostics_format = "#{m} (#{s}: #{c})",
}
end,
},
{
"jay-babu/mason-null-ls.nvim",
dependencies = {
"williamboman/mason.nvim",
"nvim-lua/plenary.nvim",
"jose-elias-alvarez/null-ls.nvim",
},
event = { "BufReadPre", "BufNewFile" },
config = function()
require("mason-null-ls").setup {
automatic_setup = true,
handlers = {},
}
end,
},
}
これで無事に怒られずにハイライトを有効にできました。
ちなみに、
set updatetime=500
で、ハイライトがかかるまでの時間を調節できます。
この書き方だとon_attach
が固定されてしまうので、こういう感じにしました。
return {
{ "neovim/nvim-lspconfig", event = { "BufReadPre", "BufNewFile" } },
{
"williamboman/mason-lspconfig.nvim",
dependencies = { "williamboman/mason.nvim", "neovim/nvim-lspconfig", "hrsh7th/cmp-nvim-lsp" },
event = { "BufReadPre", "BufNewFile" },
config = function()
require("mason-lspconfig").setup_handlers {
function(server_name)
local highlight_variable = function(client, bufnr)
if client.supports_method "textDocument/documentHighlight" then
local lsp_document_highlight = vim.api.nvim_create_augroup("lsp_document_highlight", {})
vim.api.nvim_create_autocmd({ "CursorHold", "CursorHoldI" }, {
group = lsp_document_highlight,
buffer = bufnr,
callback = function()
vim.lsp.buf.document_highlight()
end,
})
vim.api.nvim_create_autocmd({ "CursorMoved", "CursorMovedI" }, {
group = lsp_document_highlight,
buffer = bufnr,
callback = function()
vim.lsp.buf.clear_references()
end,
})
end
end
local opts = {
capabilities = require("cmp_nvim_lsp").default_capabilities(),
on_attach = function(client, bufnr)
highlight_variable(client, bufnr)
end,
}
if server_name == "lua_ls" then
opts.settings = {
Lua = {
diagnostics = { globals = { "vim" } },
format = { enable = false }, -- To prevent indent conflicts with stylua
},
}
end
if server_name == "pylsp" then
opts.settings = {
pylsp = {
plugins = {
pycodestyle = {
maxLineLength = 88,
},
},
},
}
end
if server_name == "eslint" then
opts.on_attach = function(client, bufnr)
highlight_variable(client, bufnr)
vim.api.nvim_create_autocmd("BufWritePre", {
buffer = bufnr,
command = "EslintFixAll",
})
end
end
-- print("Setting up " .. server_name .. " with mason")
require("lspconfig")[server_name].setup(opts)
end,
}
end,
},
{
"jose-elias-alvarez/null-ls.nvim",
event = { "BufReadPre", "BufNewFile" },
config = function()
local null_ls = require "null-ls"
local augroup = vim.api.nvim_create_augroup("LspFormatting", {})
null_ls.setup {
-- If you install something in Mason, you should add it here. Refer to "https://github.com/jose-elias-alvarez/null-ls.nvim/blob/main/doc/BUILTINS.md" for more information.
sources = {
-- lua
null_ls.builtins.formatting.stylua,
-- python
null_ls.builtins.diagnostics.flake8.with {
extra_args = { "--max-line-length=88" },
},
null_ls.builtins.formatting.black,
null_ls.builtins.formatting.isort,
-- javascript
null_ls.builtins.formatting.prettier.with {
prefer_local = "node_modules/.bin",
},
},
on_attach = function(client, bufnr)
if client.supports_method "textDocument/formatting" then
vim.api.nvim_clear_autocmds { group = augroup, buffer = bufnr }
vim.api.nvim_create_autocmd("BufWritePre", {
group = augroup,
buffer = bufnr,
callback = function()
-- on 0.8, you should use vim.lsp.buf.format({ bufnr = bufnr }) instead
-- on later neovim version, you should use vim.lsp.buf.format({ async = false }) instead
vim.lsp.buf.format { async = false }
end,
})
end
end,
diagnostics_format = "#{m} (#{s}: #{c})",
}
end,
},
{
"jay-babu/mason-null-ls.nvim",
dependencies = {
"williamboman/mason.nvim",
"nvim-lua/plenary.nvim",
"jose-elias-alvarez/null-ls.nvim",
},
event = { "BufReadPre", "BufNewFile" },
config = function()
require("mason-null-ls").setup {
automatic_setup = true,
handlers = {},
}
end,
},
}
最近思ったのですが、この設定まったくダメですね。
結局callbackが実行されるときにtextDocument/documentHighlight
がsupportされているかを検証しないので普通に怒られます。
うーん、解決策が思いつかない。