🦁
Vim 本体の自動補完設定試用
Vim 本体の自動補完が充実してきたので VimComplete が Deprecate になりました。
本体の自動補完に移行すべく以下のような設定で試しています。
まだ本格使用は辛いかな。 まだ進化しそうなのが楽しみです。
でも、
- 2025-09-29 更新
- yegappan/lsp での自動補完はやめるように変更。
- 2025-10-05 更新
- vsnip を本体の補完候補に追加。
- 2025-10-06 更新
- vsnip に補完関数を merge してもらった ので変更。
- vim-submode を使わずに同様の動作をするように変更。
- LSP の割り当てを filetype 指定時に変更。
- augroup の初期化を追記。
- 2025-10-19 complete 変更
環境
- Windows11
- gVim 9.1.1863
良いところ
- 補完プラグインが不要
イマイチなところ
自分が使えこなせていないだけの可能性もあり。
vsnip も問題なさそうなので常用できそう。
-
ポップアップの補完候補を選択しても挿入はされないみたいなので<C-l>で挿入している。
これに慣れないので VimComplete に戻りそう。
lsp の自動補完は補完候補の選択で挿入されるのでますます…。
<C-n>,<C-p>に<Down>,<Up>を割り当てていたからだった。 -
lsp の補完はなんだか気になる動きをする。lsp を使う filetype では , ( などで lexima が動かない場合がある。-
vsnip の展開の際に入力した文字列が消されず残る(場合がある?)
yegappan/lsp の補完でなく本体の補完で omnifunc を使うようにしたら良さそう。
-
lsp を使わない filetype では snippet が補完候補に表示されない。
vsnip の候補を表示できるように complete オプションに渡す関数を Gemini に書いてもらった。
vsnip に補完関数を merge してもらった - 設定によってはバグっぽい動作がまだある。
- completefuzzycolletct=keyword としたら意図しない文字列の挿入がされたっぽい [9.1.1782]
-
VimComplete に比べると遅く感じる。収集する候補が多くなっている設定なのかも。
気のせいっぽい?
lsp を使っている場合に遅い件は改善された。 patch 9.1.1825: completion: flicker when LSP server is slow · vim/vim@c51d1cc
使用プラグイン
それぞれのインストール方法などは書きません。使える状態になっているものとして以下記述します。
- yegappan/lsp
- hrsh7th/vim-vsnip : snippet
- rafamadriz/friendly-snippets : vsnip で使う snippet 集。自分に合うかはわからない。とりあえずインストールしただけ。
使用lsp
自動補完の設定
- 自動補完の開始は 0.2 秒後に
-
completeの変更- t 削除: 自分の環境ではタグ補完で固まるようだったので。
- u,i 削除: とりあえずいらなそう。
- b^5: 「バッファリスト内の、現在読み込まれている別のバッファから検索」ということなので関係ないものがありそうだからマッチ数を減らしてみる。ヘルプを開いていると日本語がわんさか出てくるみたい。
- k 追加: plantuml, autohotkey のファイルタイプで dictionary を指定しているので、そこから補完。
- o 追加: lsp を使えるように omnifunc で補完。
- Fvsnip#completefunc 追加: vim-vsnip で提供される補完関数
vsnip#completefuncで補完。
vimrc
set autocomplete
set autocompletedelay=200
set complete=o,k,Fvsnip#completefunc,.,w,b^5
set completefuzzycollect=keyword
set completeopt-=preview completeopt+=menuone completeopt+=fuzzy completeopt+=popup
" 補完候補が表示されていたら選択して挿入。補完候補が出ていないときの動作はお好みで。
inoremap <expr> <C-n> pumvisible() ? '<C-n>' : '<Cmd>normal! gj<CR>'
inoremap <expr> <C-p> pumvisible() ? '<C-p>' : '<Cmd>normal! gk<CR>'
filetype ごとの設定
autohotkey
https://github.com/fincs/SciTE4AutoHotkey/ の source/ahk2.standard.api と source/ahk.keys.api を結合したものを dictionary へ。
https://github.com/AutoHotkey/AutoHotkeyDocs/tree/v2 をダウンロードして syntaxgen\CreateAhk2.ahk, syntaxgen\CreateKeys.ahk で再生成してみたけど変わっていなかった。
~/_vim/after/ftplugin/autohotkey.vim
setlocal dictionary=~/path/to/autohotkey.txt
plantuml
plantuml.jar -language で出力した内容を dictionary へ
~/_vim/after/ftplugin/plantuml.vim
setlocal dictionary=~/path/to/plantuml.txt
yegappan/lsp の設定
lsp を使う場合も yegappan/lsp の自動補完は使わない。
vsnip は直接使うので lsp では使わない。
lsp.vim
augroup vimrc_lsp
autocmd!
augroup END
let s:lspOpts = #{
\ autoComplete: v:false,
\ condensedCompletionMenu: v:true,
\}
endif
autocmd vimrc_lsp User LspSetup call LspOptionsSet(s:lspOpts)
function s:LspHas(feature)
return !lsp#buffer#CurbufGetServer(a:feature)->empty()
endfunction
function s:lspKeymap() abort
if s:LspHas("hover")
setl keywordprg=:LspHover
endif
if s:LspHas("declaration")
nnoremap <buffer> gd :LspGotoDeclaration<CR>
nnoremap <buffer> gD :LspPeekDeclaration<CR>
endif
nnoremap <buffer> <Space>al <Cmd>LspDiagShow<CR>
nnoremap <buffer> <C-]> <Cmd>LspGotoDefinition<CR>
nnoremap <buffer> <Space>ar <Cmd>LspRename<CR>
nnoremap <buffer> <Space>aR <Cmd>LspReferences<CR>
" like submode
nnoremap <Plug>(lsp) <Nop>
nnoremap <Plug>(lsp)p <Cmd>LspDiagPrev<CR><Plug>(lsp)
nnoremap <Plug>(lsp)n <Cmd>LspDiagNext<CR><Plug>(lsp)
nnoremap <Space>an <Cmd>LspDiagNext<CR><Plug>(lsp)
nnoremap <Space>ap <Cmd>LspDiagPrev<CR><Plug>(lsp)
nnoremap <Space>aj :echo 'Use Space an'<CR>
nnoremap <Space>ak :echo 'Use Space ap'<CR>
endfunction
autocmd vimrc_lsp User LspAttached call s:lspKeymap()
LSP の割り当ては filetype 指定時。
LSP のパスはそれぞれへ変更してください。
go
~/_vim/after/ftplugin/go.vim
call LspAddServer([
\ #{name: 'gopls',
\ filetype: 'go',
\ path: fnamemodify('~/bin/gopls.exe', ':p')->substitute('\', '/', 'g'),
\ args: ['serve'],
\ syncInit: v:true,
\ },
\])
toml
~/_vim/after/ftplugin/toml.vim
call LspAddServer([
\ #{name: 'taplo',
\ filetype: 'toml',
\ path: 'taplo',
\ args: ['lsp', 'stdio'],
\ },
\])
typescript
~/_vim/after/ftplugin/typescript.vim
call LspAddServer([
\ #{name: 'deno',
\ filetype: ['typescript'],
\ path: 'deno',
\ args: ['lsp'],
\ },
\])
vsnip の設定
vsnip.vim
imap <silent><expr> <Tab>
\ pumvisible() ? '<Down>' :
\ vsnip#jumpable(1) ? '<Plug>(vsnip-jump-next)' :
\ '<Tab>'
smap <silent><expr> <Tab> vsnip#jumpable(1) ? '<Plug>(vsnip-jump-next)' : '<Tab>'
imap <silent><expr> <S-Tab>
\ pumvisible() ? '<Up>' :
\ vsnip#jumpable(-1) ? '<Plug>(vsnip-jump-prev)' :
\ '<C-h>'
smap <expr> <S-Tab> vsnip#jumpable(-1) ? '<Plug>(vsnip-jump-prev)' : '<S-Tab>'
imap <silent><expr> <C-j>
\ pumvisible() ? '<C-n>' :
\ '<C-j>'
imap <silent><expr> <C-k>
\ pumvisible() ? '<C-p>' :
\ '<Cmd>normal! D<CR>'
" <C-l> が押しやすいと感じているのでこちらで
imap <silent><expr> <C-l>
\ pumvisible() ?
\ vsnip#expandable() ? '<Plug>(vsnip-expand)' :
\ '' :
\ vsnip#jumpable(1) ? '<Plug>(vsnip-jump-next)' :
\ ''
" 各環境に従って変更
let g:vsnip_snippet_dirs = [
\ expand('~/vimfiles/plug/vsnip'),
\ expand('~/_vim/path/to/friendly-snippets/snippets'),
\]
Discussion