[[blink.cmp (Neovim)|blink.cmp]]が[[LazyVim]]にも取り入れられているということと、依存プラグインや設定も少なくてシンプルになりそうということ、そして[[Rust]]製なので非同期で高速... ということもあって試してみることにした。[[blink.cmp (Neovim)|blink.cmp]]を1からセットアップするのは楽だけど、[[nvim-cmp]]からの移行はそこそこ大変だったので、その辺のメモ。
## インストール
とりあえず[[blink.cmp (Neovim)|blink.cmp]]をインストールする。
<div class="link-card-v2">
<div class="link-card-v2-site">
<img class="link-card-v2-site-icon" src="https://cmp.saghen.dev/favicon.png" />
<span class="link-card-v2-site-name">cmp.saghen.dev</span>
</div>
<div class="link-card-v2-title">
Installation | Blink Completion (blink.cmp)
</div>
<div class="link-card-v2-content">
Performant, batteries-included completion plugin for Neovim
</div>
<a href="https://cmp.saghen.dev/installation"></a>
</div>
## 設定
```lua
return {
"saghen/blink.cmp",
version = "1.*",
---@module 'blink.cmp'
---@type blink.cmp.Config
opts = {
keymap = { preset = "enter" },
appearance = {
nerd_font_variant = "mono",
},
completion = { documentation = { auto_show = true } },
sources = {
default = { "lsp", "path", "snippets", "buffer" },
},
fuzzy = {
-- versionを指定してないとバイナリが特定できずLuaにfallbackするwarningが表示される
implementation = "prefer_rust_with_warning",
},
},
opts_extend = { "sources.default" },
}
```
## 要件
### [[cmp-nvim-lsp]]
[[LSP]]との依存。現状は[[nvim-lspconfig]]が依存している。
### [[cmp-buffer]]
開いているバッファのワード補完ができればOK。
### [[cmp-path]]
ファイルパスの補完ができればOK。
### [[cmp-cmdline]]
そこまで満足していないけど現状の挙動。
![[Pasted image 20250405142745.png|frame]]
*何もしなければ候補は出ない*
![[Pasted image 20250405142759.png|frame]]
*Tabで補完が出る*
さらに `Tab` で候補を選択していく。
### [[cmp-dictionary]]
登録したユーザー辞書の補完ができればOK。
### [[SchemaStore.nvim]]
[[JSON Schema]]の定義に従って補完ができればOK。
### [[lspkind-nvim]]
[[LSP]]の種類が出ればOK。
![[Pasted image 20250405143018.png]]
### [[LuaSnip]]
スニペット補完ができればOK。
![[Pasted image 20250405143052.png]]
### [[nvim-highlight-colors]]
カラーが出ること。
![[Pasted image 20250405152815.png]]
## cmp-nvim-lspを切り離す
まずは [[cmp-nvim-lsp]] を [[nvim-lspconfig]] の依存から外す。
`capabilities` については以下のissueが解決するまで引き続き必要。
<div class="link-card-v2">
<div class="link-card-v2-site">
<img class="link-card-v2-site-icon" src="https://github.githubassets.com/favicons/favicon.svg" />
<span class="link-card-v2-site-name">GitHub</span>
</div>
<div class="link-card-v2-title">
Migrate to vim.lsp.config (non-breaking) · Issue #3494 · neovim/nvim-lspconfig
</div>
<div class="link-card-v2-content">
Description With vim.lsp.config neovim/neovim#31031 , Nvim 0.11+ now has an interface for defining LSP configs. ...
</div>
<img class="link-card-v2-image" src="https://opengraph.githubassets.com/4befa55f2fdfa60903f9a8a698136c57fe4d409e7a02a00218afd2b48acbdba2/neovim/nvim-lspconfig/issues/3494" />
<a href="https://github.com/neovim/nvim-lspconfig/issues/3494"></a>
</div>
[[blink.cmp (Neovim)|blink.cmp]]のドキュメントに記載されている。
<div class="link-card-v2">
<div class="link-card-v2-site">
<img class="link-card-v2-site-icon" src="https://cmp.saghen.dev/favicon.png" />
<span class="link-card-v2-site-name">cmp.saghen.dev</span>
</div>
<div class="link-card-v2-title">
Installation | Blink Completion (blink.cmp)
</div>
<div class="link-card-v2-content">
Performant, batteries-included completion plugin for Neovim
</div>
<a href="https://cmp.saghen.dev/installation#lsp-capabilities"></a>
</div>
[[nvim-lspconfig]]の設定に加える。関連部分だけ記述。
```lua
return {
"neovim/nvim-lspconfig",
dependencies = { "saghen/blink.cmp" },
config = function()
local lspconfig = require("lspconfig")
local capabilities = require("blink.cmp").get_lsp_capabilities({
textDocument = {
completion = {
completionItem = {
snippetSupport = true,
},
},
foldingRange = {
dynamicRegistration = false,
lineFoldingOnly = true,
},
},
})
```
## 対応
### [[cmp-nvim-lsp]]
以下が設定されていればOK。
```lua
opts = {
sources = {
default = { "lsp", },
},
}
```
### [[cmp-buffer]]
以下が設定されていればOK。
```lua
opts = {
sources = {
default = { "buffer", },
},
}
```
### [[cmp-path]]
以下が設定されていればOK。
```lua
opts = {
sources = {
default = { "path", },
},
}
```
### [[cmp-cmdline]]
何も設定しなくても補完が効く。
![[Pasted image 20250405151353.png|frame]]
virtual textが表示される
[[virtual text (Neovim)|virtual text]]の段階でファジー補完になっているため、スペルミスや省略形でも表示されるのは凄い。
![[Pasted image 20250405151505.png|frame]]
*Tabを押すと一覧が表示される*
1つ目が選択済なので `Tab` をそのあとに1回押す必要もない。
### [[cmp-dictionary]]
[[blink-cmp-dictionary]]で対応できた。
```lua
sources = {
default = { "dictionary", "lsp", "path", "snippets", "buffer" },
providers = {
dictionary = {
module = "blink-cmp-dictionary",
name = "Dict",
min_keyword_length = 3,
opts = {
dictionary_files = {
vim.fn.stdpath("config") .. "/lua/envs/cmp-dictionary.txt",
},
},
},
},
}
```
### [[SchemaStore.nvim]]
[[SchemaStore.nvim]]は引き続き必要。[[nvim-cmp]]の話ではないので、[[LSP]]の方に設定されていればそのままで良い。
### [[lspkind-nvim]]
これは標準で出る。
### [[LuaSnip]]
関係個所の要素だけ記載。
```lua
{
dependencies = { "L3MON4D3/LuaSnip" },
opts = {
sources = {
default = { "snippets" },
},
snippets = { preset = "luasnip" },
}
}
```
[[LuaSnip]]の設定。
```lua
return {
"L3MON4D3/LuaSnip",
config = function()
require("luasnip").setup({})
require("luasnip.loaders.from_snipmate").lazy_load()
require("luasnip.loaders.from_lua").lazy_load()
end,
}
```
### [[nvim-highlight-colors]]
- [[blink.cmpとnvim-highlight-colorsの連携]]
## 見た目
- [[補完ウィンドウに枠線をつける (blink.cmp)|補完ウィンドウに枠線をつける]]
## キーバインド
[[nvim-lspconfig]]の設定は以下。
```lua
mapping = cmp.mapping.preset.insert({
["<F5>"] = cmp.mapping.complete(),
["<CR>"] = cmp.mapping.confirm({
select = true,
}),
["<C-p>"] = cmp.mapping.abort(),
["<Tab>"] = cmp.mapping(function(fallback)
if luasnip.expand_or_locally_jumpable() then
luasnip.expand_or_jump()
else
fallback()
end
end, { "i", "s" }),
["<S-Tab>"] = cmp.mapping(function(fallback)
if luasnip.locally_jumpable(-1) then
luasnip.jump(-1)
else
fallback()
end
end, { "i", "s" }),
}),
```
[[手動で候補を表示 (blink.cmp)|手動で候補を表示]]する設定だけでOKそう。
```lua
opts = {
keymap = {
preset = "enter",
["<F5>"] = { "show", "show_documentation", "hide_documentation" },
},
```
## fuzzyすぎる問題
これは一旦静観。
![[Pasted image 20250405153814.png]]
## シグニチャ
[[lsp_signature.nvim]]を使わなくてもよさそう?
```lua
completion = {
signature = { enabled = true },
}
```
と思ったけど入力時以外にパラメータ見れなくなってしまうから一旦保留。
## [[obsidian.nvim]]
[[obsidian.nvim]]はしばらくオートコンプリートなしで様子見する。現状も[[telescope.nvim]]の結果を挿入することが多いので何とかなる気がしている。
## 参考
<div class="link-card-v2">
<div class="link-card-v2-site">
<img class="link-card-v2-site-icon" src="https://eiji.page/_astro/favicon.CX26OJt7.svg" />
<span class="link-card-v2-site-name">eiji.page</span>
</div>
<div class="link-card-v2-title">
Neovim補完プラグインblink.cmpの使い方とカスタマイズ
</div>
<div class="link-card-v2-content">
ソフトウェアに関する備忘録を書く個人ブログです!
</div>
<img class="link-card-v2-image" src="https://eiji.page/og/neovim-blink-cmp-intro.png" />
<a href="https://eiji.page/blog/neovim-blink-cmp-intro/"></a>
</div>