[[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>