ddc.vim導入時に詰まったところメモ(LSP)
はじめに
nvim-lspに何度も手を出そうとしてはどこかで詰まってcoc.nvimに帰ってきているのですが、闇の力に興味が出てまたnvim-lspに挑戦しているairRnotです。今回、ddc.vimの導入時にLSPとの連携部分で色々と詰まったのでそのポイントについて書いていこうと思います。
環境
neovimはv0.10.0で、プラグインマネージャはlazy.nvimです。LSPの設定は以下の通りです。
長いので省略
return {
{
"williamboman/mason.nvim",
build = ":MasonUpdate",
event = { "BufReadPre", "BufNewFile" },
opts = {},
},
{
"williamboman/mason-lspconfig.nvim",
dependencies = {
"neovim/nvim-lspconfig",
"creativenull/efmls-configs-nvim",
"Shougo/ddc-source-lsp",
"uga-rosa/ddc-source-lsp-setup",
},
event = { "BufReadPre", "BufNewFile" },
config = function()
local lspconfig = require "lspconfig"
require("ddc_source_lsp_setup").setup()
local capabilities = require("ddc_source_lsp").make_client_capabilities()
require("mason-lspconfig").setup_handlers {
function(server_name)
lspconfig[server_name].setup {
capabilities = capabilities,
}
end,
["lua_ls"] = function()
lspconfig.lua_ls.setup {
capabilities = capabilities,
settings = {
Lua = {
diagnostics = {
globals = { "vim" },
},
workspace = {
checkThirdParty = false,
},
format = {
enable = false,
},
},
},
}
end,
["efm"] = function()
local stylua = require "efmls-configs.formatters.stylua"
local languages = {
lua = { stylua },
}
lspconfig.efm.setup {
capabilities = capabilities,
filetypes = vim.tbl_keys(languages),
init_options = {
documentFormatting = true,
documentRangeFormatting = true,
},
settings = {
rootMarkers = { ".git/" },
languages = languages,
},
}
end,
}
local augroup = vim.api.nvim_create_augroup("LspFormatting", {})
vim.api.nvim_create_autocmd("LspAttach", {
group = augroup,
callback = function(ev)
vim.keymap.set("n", "<C-k>", "<cmd>lua vim.lsp.buf.hover()<CR>")
vim.keymap.set("n", "gf", "<cmd>lua vim.lsp.buf.format({ async = false })<CR>")
vim.keymap.set("n", "gr", "<cmd>lua vim.lsp.buf.references()<CR>")
vim.keymap.set("n", "gd", "<cmd>lua vim.lsp.buf.definition()<CR>")
vim.keymap.set("n", "gD", "<cmd>lua vim.lsp.buf.declaration()<CR>")
vim.keymap.set("n", "gi", "<cmd>lua vim.lsp.buf.implementation()<CR>")
vim.keymap.set("n", "gt", "<cmd>lua vim.lsp.buf.type_definition()<CR>")
vim.keymap.set("n", "gn", "<cmd>lua vim.lsp.buf.rename()<CR>")
vim.keymap.set("n", "<Leader>.", "<cmd>lua vim.lsp.buf.code_action()<CR>")
vim.keymap.set("n", "ge", "<cmd>lua vim.diagnostic.open_float()<CR>")
vim.keymap.set("n", "g]", "<cmd>lua vim.diagnostic.goto_next()<CR>")
vim.keymap.set("n", "g[", "<cmd>lua vim.diagnostic.goto_prev()<CR>")
local client = vim.lsp.get_client_by_id(ev.data.client_id)
if client == nil then
return
end
if client.supports_method "textDocument/formatting" then
vim.api.nvim_clear_autocmds { group = augroup, buffer = ev.bufnr }
vim.api.nvim_create_autocmd({ "BufWritePre" }, {
group = augroup,
buffer = ev.bufnr,
callback = function()
vim.lsp.buf.format { async = false }
end,
})
end
end,
})
vim.lsp.handlers["textDocument/publishDiagnostics"] =
vim.lsp.with(vim.lsp.diagnostic.on_publish_diagnostics, { virtual_text = false })
end,
},
}
とりあえずluaのlspと、efmを通してstyluaだけ使えるようにしています。
詰まりポイント
ddc-source-lsp
は一度名前が変わっている
ddcとLSPを連携させるときはddc-source-lsp
を使うと思いますが、このpluginは2023年の秋頃まではddc-source-nvim-lsp
という名前でした。
どうやら、名前が変わった理由は
Because it is not only for
nvim-lsp
.
だそうです。
ddc-source-lsp
に関する記事を読むと、
vim.fn["ddc#custom#patch_global"]("sources", { "nvim-lsp" })
vim.fn["ddc#custom#patch_global"]("sourceOptions", {
["nvim-lsp"] = {
mark = "lsp",
forceCompletionPattern = "\\.\\w*|:\\w*|->\\w*",
},
})
というように、"nvim-lsp"
と指定されていることがあるのはこの影響ですね。現在は単に"lsp"
と指定すれば大丈夫です。最初はどちらが合っているのかわからず少し戸惑いました。
ちなみに、markに"[LSP]"
と指定している方もいるのですが、これは単純に
右側に出る文字列を指定しているだけなので気にする必要はないです。
<CR>
は補完の確定ではない
<CR>
はデフォルトでは補完の確定ではありません。<CR>
を押してもただ改行されるだけです。coc.nvimは気にしなくても<CR>
で補完してくれたので気がつくのに結構てごずりました。
おそらくデフォルトだと<C-y>
が確定です。(uiがpumの場合は自分でkeymapを書かないとだめです)
E1206: Dictionary required for argument 1
というエラーが出る
ここが今回一番ハマった部分です。
補完を確定した際に、以下のようなエラーが発生しました。
Error detected while processing function <SNR>73_on_complete_done_after[12]..<SNR>73_get_expand_text:
line 15:
E1206: Dictionary required for argument 1
結論としては、hrsh7th/vim-vsnip-integ
を依存に入れていたのが原因でした。
vnsip使うからなんとなくintegの方も入れていたのですが、これが間違いでした。ただLSPと連携させるだけならhrsh7th/vim-vsnip
だけで十分です。
補完したものがすぐに消滅する
snippet系において、補完を確定したあとすぐに消滅してしまうという挙動が起きていました。
原因は、vim scriptをluaに書き直した際のミスにありました。
ddc-source-lsp
のREADMEには以下のように書かれています。
call ddc#custom#patch_global('sourceParams', #{
\ lsp: #{
\ snippetEngine: denops#callback#register({
\ body -> vsnip#anonymous(body)
\ }),
\ enableResolveItem: v:true,
\ enableAdditionalTextEdit: v:true,
\ }
\ })
body -> vsnip#anonymous(body)
が波括弧で囲まれていたので、luaに書き直した際にも波括弧で囲んでいました。
vim.fn["ddc#custom#patch_global"]("sourceParams", {
lsp = {
snippetEngine = vim.fn["denops#callback#register"] {
function(body)
vim.fn["vsnip#anonymous"](body)
end,
},
enableResolveItem = true,
enableAdditionalTextEdit = true,
},
})
しかし、luaの場合は波括弧は必要ありませんでした。
vim.fn["ddc#custom#patch_global"]("sourceParams", {
lsp = {
snippetEngine = vim.fn["denops#callback#register"](function(body)
vim.fn["vsnip#anonymous"](body)
end),
enableResolveItem = true,
enableAdditionalTextEdit = true,
},
})
これで、無事に補完ができるようになりました。
おわりに
詰まったときは、GitHubで他の方の設定を漁るのが結構効果的でした。
また、闇の力は識者の方が多くいらっしゃり、本当に助かりました。
しかし、まだLSPと最低限の連携をしただけなので、これからもっと拡張していきたいです。
Discussion