LSPクライアントをcoc.nvimにした話¶
以前 Pythonの補完環境をjedi-vimからvim-lspに移行した話 — kashew_nuts-blog という記事を書きましたが、現在は neoclide/coc.nvim に完全移行しています。
coc.nvimとは¶
いろんな記事で説明されてますが、Vim8/Neovim向けのインテリセンスエンジンでLSPのフルサポートを謳ったプラグインです。
移行理由¶
移行しようと思った理由は以下の3つです。「これなんてVSCode?」となったとかならなかったとか。
自動補完が「ちょうどいい」感じで補完してくれる
拡張が豊富で、LSPに限らずIDEとしての機能を提供してくれる
Language Serverの設定でvimrcが膨れない
1. 自動補完が「ちょうどいい」感じで補完してくれる¶
vim-lspではオムニ補完、 prabirshrestha/asyncomplete.vim も使うと自動補完が使えるようになります。個人的には自動補完はほしい補完ソースを、「期待したタイミングで」動かすのが面倒でした。 LSP導入以前にも自動補完プラグインを使うのに、「連携のための設定」を書くのに苦労していました。
vim-lspを使ってるときはオムニ補完で自分で補完のタイミングをコントロールして書けてよかったのですが、coc.nvimは「これでいいのでは?」というくらい楽に動いたので一気に虜になりました。
2. 拡張が豊富で、LSPに限らずIDEとしての機能を提供してくれる¶
昨今LSPで各言語ごとに開発環境をインストールするのが楽になってきましたが、インストール自体は手動で行う必要がありました。 よく知らない言語を触るときにLanguage Serverのセットアップで時間を使うのは大変です。
最近では mattn/vim-lsp-settings がでてきたので事情が変わってきましたが、 coc.nvimはcoc.nvim自体がLanguage Serverを含む拡張をインストールできます。 Gitやエクスプローラーなどの拡張もあるので他のVimプラグインを探す時間も省けます。
3. Language Serverの設定でvimrcが膨れない¶
LSPを活用するにはクライアント側の設定だけでなく、Language Serverの設定も書いたりします。 vimrcにその両方を書いていくとどうしてもvimrcが肥大化していきますが、coc.nvimはLanguage Serverの設定をJSONファイルに書けます。 キーマッピングやcoc.nvimで使う拡張などはvimrcに書く必要がありますが、設定を分離できるのでvimrcが肥大化しにくいです。
インストール要件¶
現在のインストール要件は以下となっています。
Vim >= 8.0.1453
node.js >= 8.10.0
npm
当初2019年に試したときはVimの場合Python3インターフェイスや neoclide/vim-node-rpc 、yarnに依存していましたが、現在は依存が消えているので使いやすくなりました。(ソースからビルドするときはyarnが必要となります。
Vimの下限のバージョンはUbuntu 18.04LTSとかならデフォルトで満たしていますが、できればpopup-windowを活用するのに、8.2以上だとよりよいでしょう。 node.jsも現在のLTSの下限である10.x系にしたほうがよいと思います。
詳細は Install coc.nvim を参照のこと。
インストール方法¶
vim-plugを使ってる場合、 vimrcに以下のように記述します。
その後、Vimを再起動しコマンドラインモードで :PlugInstall
すればOKです。
Plug 'neoclide/coc.nvim', {'branch': 'release'}
Quick Start の通りですね。
使い方¶
coc.nvimをインストールしたあとは拡張やLanguage Serverをインストールして使うだけ。 どんな設定ができるかや、Language Serverの設定をすればいいかは以下のWikiやヘルプを参照するとよいです。
まずは自分の使うFileTypeの拡張を入れたり、設定ファイルの記述を便利にするために :CocInstall coc-json
はしておくとよいでしょう。
popup-windowについて¶
coc.nvimに限らずVimのLSPクライアントを活用していくとき、popup-windowが有効になっていると便利です。
コマンドラインモードで :echo has('popupwin')
を実行したとき、 1
が返ってくると有効になっています。
Vim8.2を使っていれば問題なくpopup-windowが使えると思いますが、colorschemeが追従しているかも確認しておくとよいかもしれません。 自分は昔から tomasr/molokai を使っていますが、popup-windowで使うハイライトの指定がされていません。
下記のドキュメントを参考に、ハイライトの指定を行いました。
" 設定したハイライト
" ~/.vim/colors/molokai.vim
hi Pmenu guifg=#f8f6f2 ctermfg=15 guibg=#35322d ctermbg=236
hi PmenuSel guifg=#000000 ctermfg=16 gui=bold cterm=bold
hi PmenuSbar guibg=#35322d ctermbg=236
hi PmenuThumb guifg=#d9cec3 ctermfg=252
他のcolorschemeもいくつか見て、最終的に sjl/badwolf を参考にさせていただきました。 使ったときのイメージはこんな感じです。
https://twitter.com/kashew_nuts/status/1229781512050003968
気になるところ¶
良い点もあれば気になるところもあるということでかんたんに書きます。
設定ファイルがJSONのため、PATHの設定を書くと異なるOS間で共通化しにくい
NeoVimでのみサポートとかあるので、coc及び拡張の機能が自分の「Vim」に対応しているか確認する必要がある
トラブルシューティングにはJavaScript/TypeScriptまわりの知識が必要になる
現状なにか詰まったりしたときに「そういえばそうだったな」と思うぐらいなので、気に留めておくぐらいでいいかもしれません。
Pythonの補完環境をjedi-vimからvim-lspに移行した話¶
VimでPython書いてますか?
長らくPythonの補完用プラグインとして davidhalter/jedi-vim を使用してきましたが、 あの mattn (@mattn_jp) さんがCollaboratorになった prabirshrestha/vim-lsp や palantir/python-language-server がいよいよ実用的になってきたので移行してみました。
とはいえ実際に使うにはまだ設定するところもちょこちょこあるので、一度まとめておこうと思います。
前提とする環境¶
Vim: 8.0以上、かつコンパイルオプションで jobs, timer, channel, lambda が有効になっている
Python: 2.7もしくは3.4以降 (pyenvやAnacondaでインストールしたPythonは考慮しない)
Note
VimでPython/Python3インターフェースを有効にする必要があるかもしれませんが、少なくともドキュメントには記載されていませんでした。もし必要な場合は以前書いたVimとPythonの補完についてのメモを参照してください。
その後Python/Python3インターフェースを無効にした状態で試したところ、問題なく動作しました。外部インターフェイスに依存せず補完や定義ジャンプができるのはいいですね。
LSP(Language Server Protocol)とは¶
ざっくりいうと自動補完や定義ジャンプ、ドキュメントのホバー表示などエディタごとに実装していた機能を、言語Serverを用意して複数の開発ツールで使えるようにしましょうというものです。LSPを活用することでエディタのプラグインなどは最小限の労力で言語をサポートできるようになります。
各エディタ用にLSPを使うプラグインや機能を用意する必要がありますが、補完機能をサポートするサーバーが共通化できるのでそのServerが便利になると1つのエディタだけでなく複数のエディタで活用できるメリットがあります。
どのようなプロトコルでどのように通信しているのかは、 Microsoftが公開しているドキュメント が詳しいのでそちらを参照してください。 Software Design 2018年3月号 にも詳しく書いています。(残念ながら紙の書籍は2019/01/26現在在庫がないようです)
LSP導入¶
Python用のLanguage ServerとClientとなるVimプラグインを導入します。ServerとClientは以下になります。
Language Server: palantir/python-language-server
Client: prabirshrestha/vim-lsp
Language Serverの導入¶
python-language-server
をpipコマンドを使ってインストールします。
どこからでも使えるようにグローバルな環境に入れますが、macOSやLinuxを使っている人は注意する必要があります。
OSが使うPythonに様々なライブラリが入っており、無理やりインストールしようとすると後で困る可能性があるからです。
ここではユーザーディレクトリにインストールすることでその問題を回避します。
以下のPATHにインストールされるので、予め ~/.bash_profile
などに PATH
の設定を追加しておいてください。
インストールされる箇所は site.USER_BASE によって決まります。
Windows:
%APPDATA%\Python
macOSで www.python.org からPythonをインストールした場合:
~/Library/Python/X.Y/bin
(X.YはPythonのバージョン)macOSでHomebrewを使いPythonをインストールした場合:
~/.local/bin
Ubuntuの場合:
~/.local/bin
ターミナルを開き以下のコマンドを使いインストールします。
$ pip install --user python-language-server
インストールが完了したら $ which pyls
などでLanguage ServerにPATHが通っていることを確認してください。
インストールに失敗したり、whichコマンドで何も出力されない場合、 PATH
の設定がうまく言っていない可能性があるので確認してみてください。
pipコマンドを実行した結果でもわかりますが、 python-language-server
はこれまでもPythonの自動補完や静的解析で使われていた davidhalter/jedi をLSPで使えるようにしたものです。フォースの魂は脈々と受け継がれるようですね。
Clientの導入¶
vim-lspは依存で prabirshrestha/async.vim が必要なので合わせてインストールします。 私は junegunn/vim-plug を使用しているので、以下のようにvimrcに記述します。
" vimrc
Plug 'prabirshrestha/vim-lsp'
Plug 'prabirshrestha/async.vim'
Vimを開いたまま :so $MYVIMRC のようにして設定の変更を読み込み、 :PlugIntall するとプラグインをインストールできます。
Vimプラグインの設定¶
ServerとClientとなるVimプラグインは導入しましたが、実際に連携するには設定が必要です。以下のようにvimrcに追記します。
" vimrc
" デバッグ用設定
let g:lsp_log_verbose = 1 " デバッグ用ログを出力
let g:lsp_log_file = expand('~/.cache/tmp/vim-lsp.log') " ログ出力のPATHを設定
" 言語用Serverの設定
augroup MyLsp
autocmd!
" pip install python-language-server
if executable('pyls')
" Python用の設定を記載
" workspace_configで以下の設定を記載
" - pycodestyleの設定はALEと重複するので無効にする
" - jediの定義ジャンプで一部無効になっている設定を有効化
autocmd User lsp_setup call lsp#register_server({
\ 'name': 'pyls',
\ 'cmd': { server_info -> ['pyls'] },
\ 'whitelist': ['python'],
\ 'workspace_config': {'pyls': {'plugins': {
\ 'pycodestyle': {'enabled': v:false},
\ 'jedi_definition': {'follow_imports': v:true, 'follow_builtin_imports': v:true},}}}
\})
autocmd FileType python call s:configure_lsp()
endif
augroup END
" 言語ごとにServerが実行されたらする設定を関数化
function! s:configure_lsp() abort
setlocal omnifunc=lsp#complete " オムニ補完を有効化
" LSP用にマッピング
nnoremap <buffer> <C-]> :<C-u>LspDefinition<CR>
nnoremap <buffer> gd :<C-u>LspDefinition<CR>
nnoremap <buffer> gD :<C-u>LspReferences<CR>
nnoremap <buffer> gs :<C-u>LspDocumentSymbol<CR>
nnoremap <buffer> gS :<C-u>LspWorkspaceSymbol<CR>
nnoremap <buffer> gQ :<C-u>LspDocumentFormat<CR>
vnoremap <buffer> gQ :LspDocumentRangeFormat<CR>
nnoremap <buffer> K :<C-u>LspHover<CR>
nnoremap <buffer> <F1> :<C-u>LspImplementation<CR>
nnoremap <buffer> <F2> :<C-u>LspRename<CR>
endfunction
let g:lsp_diagnostics_enabled = 0 " 警告やエラーの表示はALEに任せるのでOFFにする
vim-lspは警告やエラーの表示などもできますが、そちらは w0rp/ale に寄せているため機能を無効化しています。 ALEについては 2018年版Life ChangingだったVimプラグインTOP3 に書きましたのでそちらを参照してください。
vimrcに記載したら保存、終了します。
使用感について¶
jedi-vimと比べたときのメリット/デメリットを書いていきます。
メリット¶
高速化されたのが一番大きいですね。
Vimの起動が高速化できた(Ubuntu環境で100〜150ms、macOS環境でも200〜300ms短縮)
補完候補がでる時間が高速化できた
発展途上の技術なので進化を体験していける
他の言語と使用できるプラグインを共通化できるため、vimrcからプラグインを減らせた
デメリット¶
まだ発展途上というところからきてると思うのですが、少しだけ今までできていたことができない感じがあります。
言語用のServerが別途インストールが必要なので環境を壊さわないようにするのに気を使う。
jedi-vimはjediを
git submodule
で独立して入れていたので楽だった。
Vimを起動後に
:setf python
しても補完や定義ジャンプが動かない。既存のPythonファイルを開いたり、
$ vim hoge.py
などすると動くが、少し気になる。
リネームが不安定(動かない?)
動かすには python-rope/rope が必要という情報もあるがそれでも動かない
jedi-vimはじゃじゃ馬だったり、マルチバイト文字が対象行に混じっていると動かなかったりしたが….
2018年の振り返りと2019年抱負¶
2018年の総括¶
https://twitter.com/kashew_nuts/status/1079732019314081792
だいたいこんな感じでしたが、せっかくなのでちょっと細かく見ていきたいと思います。
開発面¶
引き続きPython x Djangoの組み合わせで開発をしています。去年はDjango REST frameworkを使い始めました。 一昨年に比べて去年は以下のようなことを考えることが多かったように思います。
どの技術やアーキテクチャを採用するのか
なぜその技術・やり方を選択するのか
一度選択したものをどのように良くしていくのか
チームメンバーにどのように仕事をしてもらうと全体がよくなるのか
上記をどうやって伝えていくか・継続していくか
そもそもの理解が足りていないためきっちり応えられなかったり、 全体を見る機会をもっと早めに作れたのにそれを選択しなかったがために後でしっぺ返しを食らったりしていた気がします。
普通に開発してると足を止める暇がなくなるので、「足を止めて振り返ったり、現状がどうで今後どうしていくことを考える機会をつくる」のがいいのだろうなと思いつつ、それをはじめて継続するにはどうしたらいいのかなと思う今日この頃です。
書籍執筆・レビュー¶
初の執筆を経験した年でした。
6月に、共著で執筆していたPythonプロフェッショナルプログラミング第3版が出版されました。
プライベートでは後半にレビューに1件かかわらせてもらってるが、スケジュールが変更されたそうなので2019年にリブート会をするらしいです。
クライミング¶
さらなるレベルアップには日々の行動を変えないとなーという感じですね。
アメリカのヨセミテ国立公園でクライミング漬けの1週間を過ごしました。なんという幸せ。次は2週間くらい行きたい。
Blogはこちら ヨセミテツアー日記 — kashew_nuts-blog
国内でも瑞牆でキャンプデビューしたり、小川山、御岳にいったりしました。
成果は初段 1本、1級3本、2級 2本, V5 2本, V4 1本
ジムでのクライミングも週1〜2回ぐらいのペースで通っていた気がします。
3年連続初段は1本らしいので、もうちょっと落とせるようになりたいですね。
発表とか¶
PyCon KyushuやPyConJPというカンファレンスの場での発表実績も解除できました。Blogは以下。
何度かメンターをしている Python入門者の集い でも発表しましたね。
個人活動的な¶
計29回。多いのか少ないのかはわからないですが、2019年は外岩シーズンのイベントは参加は控えるかもしれない。
けれどもなんかしらの行動につながる会への参加はしていきたいですね。
Python mini Hack-a-thon
BPStudy
購入したものとか¶
買ってよかったなーと思うのを厳選するなら以下の5つ。
Inspiron 13インチ 7000シリーズのフルスペック版: 現在はUbuntuデスクトップで運用
Apple iPhone XR 128GB: 色はコーラルを選択。6sからの乗り換え。バッテリー持ちの良さは安心
Amazon Kindle Paperwhite: 読書が捗るけど、PDFはA4が多いから向かないですね….
Anker PowerCore Fusion 5000: プラグ搭載型なので移動時の持ち物が減って便利
Cable Matters USB C to DisplayPort 変換アダプター: Ubuntuデスクトップでも4K対応