🦔

vimcomplete を使い始めた

2025/01/18に公開

Vim の補完プラグインは Shougo/ddc.vim を使っていたけれど、deno を使わなくて比較的高速なプラグインを試したいなと思ったので girishji/vimcomplete を選択。
(ddc.vim を使う前には prabirshrestha/asyncomplete.vim を使ってました。)
全然煮詰め切れていないけど、vimcomplete ユーザーは少なそうなのでとりあえず公開しちゃう。
一応 Meguro.vim #27 の成果かな。アカツキ さんありがとうございます!

設定ファイル

とりあえず設定ファイル。
環境によって Shougo/dein.vimShougo/dpp.vim を切り替えて使っているのでキメラな状態。

vimcomplete.toml
[[plugins]]
repo = 'girishji/vimcomplete'
hooks_file = '~/vimfiles/rc/dein/vimcomplete.vim'
merged = false
extAttrs = { installerFrozen = true }

[[plugins]]
repo = 'hrsh7th/vim-vsnip'
on_event = 'InsertEnter'
hooks_file = '~/vimfiles/rc/dein/vsnip.vim'

[[multiple_plugins]]
plugins = ['vimcomplete', 'vim-vsnip']
hook_source = '''
imap <silent><expr> <C-l>
      \ pumvisible() ?
      \   vsnip#expandable() ? '<Plug>(vsnip-expand)' :
      \   '' :
      \ vsnip#jumpable(1) ? '<Plug>(vsnip-jump-next)' :
      \ ''
'''
[[multiple_hooks]]
plugins = ['vimcomplete', 'vim-vsnip']
hook_source = '''
imap <silent><expr> <C-l>
      \ pumvisible() ?
      \   vsnip#expandable() ? '<Plug>(vsnip-expand)' :
      \   '' :
      \ vsnip#jumpable(1) ? '<Plug>(vsnip-jump-next)' :
      \ ''
'''

[[plugins]]
repo = 'rafamadriz/friendly-snippets'
merged = false
rtp = ''

[[plugins]]
repo = 'hrsh7th/vim-vsnip-integ'
on_source = 'vim-vsnip'

[[plugins]]
repo = 'yegappan/lsp'
hooks_file = '~/vimfiles/rc/dein/lsp.vim'
vimcomplete.vim
" hook_add {{{
let g:vimcomplete_enable_by_default = v:false
let g:vimcomplete_do_mapping = v:false

let s:options = #{
      \ completor: #{
      \   shuffleEqualPriority: v:true,
      \   triggerWordLen: 2,
      \   showCmpSource: v:false,
      \ },
      \ buffer: #{
      \   enable: v:true,
      \   priority: 10,
      \   urlComplete: v:true,
      \   envComplete: v:true,
      \   filetypes: ['autohotkey', 'cfg', 'gitcommit', 'javascript', 'markdown', 'plantuml', 'rst', 'snippet', 'python', 'toml', 'vim', 'xsl'],
      \ },
      \ dictionary: #{
      \   enable: v:true,
      \   priority: 11,
      \   matcher: 'ignorecase',
      \   properties: #{
      \     autohotkey: #{
      \       sortedDict: v:false,
      \       onlyWords: v:true,
      \     },
      \     plantuml: #{
      \       sortedDict: v:false,
      \       onlyWords: v:true,
      \     },
      \   },
      \   filetypes: ['autohotkey', 'plantuml'],
      \ },
      \ lsp: #{
      \   enable: v:true,
      \   priority: 10,
      \   maxCount: 5,
      \   filetypes: ['go', 'python', 'toml', 'typescript'],
      \ },
      \ omnifunc: #{
      \   enable: v:false,
      \   priority: 8,
      \   filetypes: ['plantuml'],
      \ },
      \ vsnip: #{
      \   enable: v:true,
      \   priority: 11,
      \   filetypes: ['go', 'plantuml', 'rst', 'vim'],
      \ },
      \ vimscript: #{
      \   enable: v:true,
      \   priority: 9,
      \ },
      \}

autocmd vimrc VimEnter * call g:VimCompleteOptionsSet(s:options)
autocmd vimrc VimEnter * VimCompleteEnable autohotkey cfg gitcommit go javascript markdown plantuml python rst snippet toml typescript vim xsl
" }}}
" autohotkey {{{
setlocal dictionary=~/vimfiles/rc/ddc/autohotkey.txt
" }}}
" plantuml {{{
setlocal dictionary=~/vimfiles/rc/ddc/plantuml.txt
" }}}
vsnip.vim
" hook_source {{{
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> <C-n> <Down>
imap <silent><expr> <C-k>
      \ pumvisible() ? '<C-p>' :
      \ '<Cmd>normal! D<CR>'
imap <silent> <C-p> <Up>

let g:vsnip_snippet_dir = expand('~/vimfiles/rc/vsnip')
" }}}
lsp.vim
" hook_add {{{
function s:lspSet() abort
  let s:lspOpts = #{autoComplete: v:false}
  call LspOptionsSet(s:lspOpts)

  let s:lspServers = [
        \ #{name: 'deno',
        \   filetype: ['typescript'],
        \   path: 'deno',
        \   args: ['lsp'],
        \ },
        \ #{name: 'gopls',
        \   filetype: 'go',
        \   path: fnamemodify('~/_vim/lspservers/gopls/gopls.exe', ':p')->substitute('\', '/', 'g'),
        \   args: ['serve'],
        \   syncInit: v:true,
        \ },
        \ #{name: 'taplo',
        \   filetype: 'toml',
        \   path: 'taplo',
        \   args: ['lsp', 'stdio'],
        \ },
        \]
  call LspAddServer(s:lspServers)
endfunction
autocmd vimrc User LspSetup call s:lspSet()

function s:lspKeymap() abort
  nnoremap <buffer> <Space>al <Cmd>LspDiagShow<CR>
  nnoremap <buffer> K <Cmd>LspHover<CR>
  nnoremap <buffer> gd <Cmd>LspGotoDefinition<CR>
  nnoremap <buffer> <C-]> <Cmd>LspGotoDefinition<CR>
  nnoremap <buffer> <Space>ar <Cmd>LspRename<CR>
  nnoremap <buffer> <Space>aR <Cmd>LspReferences<CR>

  " submode
  call submode#enter_with('lsp', 'n', 'br', '<Space>aj', '<Cmd>LspDiagNext<CR>')
  call submode#enter_with('lsp', 'n', 'br', '<Space>an', '<Cmd>LspDiagNext<CR>')
  call submode#enter_with('lsp', 'n', 'br', '<Space>ak', '<Cmd>LspDiagPrev<CR>')
  call submode#enter_with('lsp', 'n', 'br', '<Space>ap', '<Cmd>LspDiagPrev<CR>')
  call submode#map('lsp', 'n', 'brs', 'j', '<Cmd>LspDiagNext<CR>')
  call submode#map('lsp', 'n', 'brs', 'n', '<Cmd>LspDiagNext<CR>')
  call submode#map('lsp', 'n', 'brs', 'k', '<Cmd>LspDiagPrev<CR>')
  call submode#map('lsp', 'n', 'brs', 'p', '<Cmd>LspDiagPrev<CR>')
endfunction
autocmd vimrc User LspAttached call s:lspKeymap()
" }}}

vimcomplete を使うにあたって

  • prabirshrestha/vim-lsp から yegappan/lsp に変更。vim-lsp の方が多機能なのかな? よくわかってない。
  • デフォルトキーマップを無効にできなかったので PR PR1, PR2 (それぞれミスってるけど)
  • postfixHighlight を使おうと思っているけどキーマップをどうにかしないといけないので、まだ使っていない。
  • friendly-snippets はとりあえず入れてるだけの状態。
  • vimcomplete はまだまだ手を入れる余地があると思うので、有識者にも使ってみてもらって PR を送ってもらいたいな。
GitHubで編集を提案

Discussion