VimでLanguage Serverを活用する(Rust, Vue.js)

遅刻しましたが Vim2 Advent Calendar 2017 22日目の記事です。

VSCodeを使っていると知らない間にお世話になっていたりするLanguage Server Protcol(LSP)ですが、便利なので少しずつVimでも活用してみています。

実際に最近使っているRustとVue.jsの例を紹介をします。

2018/01 Vue.jsのほうをまとめ直しました => Neovim/Vim8で快適Vue.js開発(Vue Language Server)

※ Neovimでしか動作検証してません・・・使っているプラグインはVim対応してるので多分Vimでも動きます

プラグイン構成

補完とLinterが欲しいので以下のプラグインを入れます。

  • LanguageClient-neovim
  • deoplete.nvim
  • neosnippet
  • ale

プラグインマネージャーなお好きなものを使うと良いですが、dein.vimでtomlで設定を読んでいる場合以下のようになります。

[[plugins]]
repo = 'Shougo/context_filetype.vim'

[[plugins]]
repo = 'Shougo/deoplete.nvim'
depends = 'context_filetype.vim'
on_i = 1
hook_source = '''
let g:deoplete#enable_at_startup = 1
'''

[[plugins]]
repo = 'Shougo/neosnippet.vim'
depends = ['context_filetype.vim']
on_event = 'InsertCharPre'
on_ft = 'snippet'

[[plugins]]
repo = 'autozimu/LanguageClient-neovim'
depends = 'deoplete.nvim'
on_ft = ['rust', 'vue']
build = './install.sh'
hook_source = '''
set hidden
let g:LanguageClient_serverCommands = {
    \ 'vue': ['vls'],
    \ 'rust': ['rustup', 'run', 'nightly', 'rls'],
    \ }
let g:LanguageClient_autoStart = 1
nnoremap <silent> K :call LanguageClient_textDocument_hover()<CR>
nnoremap <silent> gd :call LanguageClient_textDocument_definition()<CR>
nnoremap <silent> <F2> :call LanguageClient_textDocument_rename()<CR>
'''

[[plugins]]
repo = 'w0rp/ale'

今回の話に無関係な設定は消してあります、全設定が知りたい人は↓

embed.ly

LanguageClient-neovim

あまりVimでLSPを使っている人を見たことがないのでデファクトがわからないのですが、勝手にこれをデファクトだと思って使っています。

  • Langserver.orgで紹介されていて全チェック入ってるので全機能使える
  • ドキュメントを見る限りVimでもNeovimでも動く
  • deoplete.nvimとaleと自動で連携するので便利
  • あと多くの部分がRustで書かれていてカッコイイ・・・

同様のプラグインにvim-lspやvim-lscもありますが試していないので、ユーザーの方いたら意見を聞いてみたいです。

Rust

RLSを使います。

完全に便利なのでvim-racerから完全に乗り換えました。

以下RLSのインストール方法です。

% rustup update
% rustup component add rls-preview --toolchain nightly
% rustup component add rust-analysis --toolchain nightly
% rustup component add rust-src --toolchain nightly

rustupが入っていない場合はここにあるコマンドでインストールします。

LSPの前にRustを書くときはrust.vimを入れておく必要があります。

[[plugins]]
repo = 'rust-lang/rust.vim'
on_ft = 'rust'
hook_source = '''
let g:rustfmt_autosave = 1

rustfmtを入れて自動で整形するのがおすすめです。

これでVimを起動すると最高のRust開発環境が待っています。

Vue.js

VLSを使います。

VLSはVSCodeでVue.js書いたことがある人ならお世話になっているVetur内部のLanguage Serverです。

単体でインストールできるので下記のコマンドで導入します。

$ npm install vue-language-server -g

deoplete.nvimでvueファイルのような複数言語の混ざったファイルはcontext/_filetype.vimで判定して補完しています。

vueファイルには対応していなかったのでPRを出して対応しました。

ハイライトにはposva/vim-vueを使います。

これで万事うまくいけばよかったのですが・・・

補完がうまく効いていないのが現状です。aleはちゃんと効きます。deoplete.nvimの本来の補完(html,js,css)は効くのでなんとか開発はできます。

せっかくのアドベントカレンダーでうまく動かない...では残念なのでnvim-completion-managerを使ってみました。

deoplete.nvimの部分をnvim-completion-manager(ncm)に置き換えます。

[[plugins]]
repo = 'roxma/nvim-completion-manager'
on_ft = ['vue']
on_i = true
hook_source = '''
inoremap <expr> <CR> (pumvisible() ? "\<c-y>\<cr>" : "\<CR>")
imap <expr> <CR>  (pumvisible() ?  "\<c-y>\<Plug>(expand_or_nl)" : "\<CR>")
imap <expr> <Plug>(expand_or_nl) (cm#completed_is_snippet() ? "\<C-U>":"\<CR>")
inoremap <c-c> <ESC>
inoremap <expr> <Tab> pumvisible() ? "\<C-n>" : "\<Tab>"
inoremap <expr> <S-Tab> pumvisible() ? "\<C-p>" : "\<S-Tab>"
'''

embed.ly

scaffoldやjs補完は効いています。ただ、ncmのcontextの解釈が完全でないためHTML部分で効く補完が弱いです。

この記事を書きながらncmでは動くなとつぶやいていたらShougoさんがやってきました。

embed.ly

embed.ly

Issueあげるアドバイスをもらったので近日中に時間を作ってやります。

正直deoplete.nvimが好きなのでncmに乗り換えるより、deoplete.nvimで最高のVue.js開発環境にしていきたいので頑張りたいです。

Vimが最高のVue.js開発環境になったらまた記事を書こうと思います。


Language Server Protcolは補完やLint以外にもrenameや定義参照など便利な機能があるので他の言語も積極的に導入を試みたいと思っています。

Show comments

Adsense

Share

  • このエントリーをはてなブックマークに追加

About

どこにでもいる平凡なプログラムを書く人間のログ。

Recently

Tags

-->