December 20, 2020
この記事は Vim 2 Advent Calendar 2020 の20日目です。
12/12 に PHP Conference Japan 2020 に LT で登壇させていただきました。
19:06 辺りからです。
PHPer のための Vim 実践入門 - Speaker Deck
テーマは「PHPer のための Vim 実践入門」ということで、かなり Vim に振り切った内容で話させていただきました。 時間の都合上 Plugin の紹介までしかできず、具体的な設定については殆ど触れていなかったので、今回は現時点での自分の dotfiles を紹介したいと思います。
dotfiles は以下のリポジトリにまとめています。
README に雑に書いてありますが、まるっと設定を流用したい場合はリポジトリを clone して以下のスクリプトを実行してください。
./bin/link.sh
このスクリプトは単にリポジトリ内の各設定ファイルへの symlink をホームディレクトリ等に作成します。 一応、既存の設定ファイルを上書きを避けるようにスクリプトを書いていますが、利用は自己責任の元で行ってください。
また Vim の実装としては Neovim を利用しており、プラグインには Python と Node.js の neovim パッケージに依存しているものがあります。 それぞれ環境を用意した上で、パッケージをインストールしてください。
pip install pynvimnpm install neovim
プラグイン管理には dein.vim を利用しています。 このプラグインの設定方法に関しては結構情報が多く、記事の趣旨から逸れそうなので割愛します。
LSP 互換の開発補助プラグインは coc.nvim を使用しており、 PHP 開発用途として coc-phpls 、 coc-snippets も使用しています。 今回の登壇資料を準備していて知ったのですが、 Neovim の LSP Client は Neovim 本体の LSP 1 、 coc.nvim 、 vim-lsp の三国志時代になっているそうですね。 今後の展開から目が離せません。
登壇では言及していなかったのですが、実は coc-phpls をそのまま導入するだけでは PHP の補完機能をフルで利用することができません。 coc-phpls が裏で呼び出している Intelephense という Language Server は自動補完や定義ジャンプといった主要機能のみ無料で利用可能としており、シンボルのリネームなどの一部機能は有料 2 での提供となっています。 自分の場合はこのライセンスを購入しており、以下の環境変数に設定したライセンスキーの値を読む設定を行っています。
export PHP_INTELEPHENSE_LICENCE_KEY='YOUR_LICENCE_KEY'
あるいはもっと簡単な方法として以下のように coc-settings.json に記述することもできます。
PHP Intelephense の有償版を Neovim で使ってみる - Qiita
ただし自分のように dotfiles を公開している場合はライセンスキーもそのまま晒すことになるので、この方法は避けるべきです。
coc.nvim が紹介しているキーマッピング例はそのままだと他のプラグインに割り当てるキーマッピングとバッティングする可能性があったので少し変更しています。
自分の場合は deris さんのキーマッピングに関する考察を参考に <Space>
+ [a-z]
でプラグインの機能を呼び出すルールを採用しており、以下のように <Space>
+ c
で coc の機能を呼び出すようにしています。
let mapleader = "\<Space>"nnoremap [coc] <Nop>nmap <Leader>c [coc]" Show all diagnostics.nnoremap <silent><nowait> [coc]a :<C-u>CocList diagnostics<cr>" Manage extensions.nnoremap <silent><nowait> [coc]e :<C-u>CocList extensions<cr>" Show commands.nnoremap <silent><nowait> [coc]c :<C-u>CocList commands<cr>" Find symbol of current document.nnoremap <silent><nowait> [coc]o :<C-u>CocList outline<cr>" Search workspace symbols.nnoremap <silent><nowait> [coc]s :<C-u>CocList -I symbols<cr>" Do default action for next item.nnoremap <silent><nowait> [coc]j :<C-u>CocNext<CR>" Do default action for previous itemnnoremap <silent><nowait> [coc]k :<C-u>CocPrev<CR>" Resume latest coc list.nnoremap <silent><nowait> [coc]p :<C-u>CocListResume<CR>
ファイルツリーのプラグインは defx.nvim 、 defx-icons 、 defx-git を使用しています。
defx-icon でアイコンを表示するには Nerd Font が必要です。 Mac の場合は Homebrew でインストールして、ターミナルのフォントに設定することで利用できます。
brew tap homebrew/cask-fontsbrew cask install font-hack-nerd-font
またキーマッピングは <Space>
+ f
を設定しています。
基本的にはドキュメントにあるキーマッピング例をそのまま利用していますが、以下のようにファイルツリーの開き方に応じて幾つかコマンドを用意しておくと便利です。
nnoremap [defx] <Nop>nmap <Leader>f [defx]nmap <silent> [defx]c :<C-u>Defx -columns=git:icons:filename:type `expand('%:p:h')` -search=`expand('%:p')`<CR>nmap <silent> [defx]r :<C-u>Defx -columns=git:icons:filename:type<CR>
テストのプラグインは vim-test を使用しています。 こちらはテストランナーも自動で検知してくれる素晴らしいプラグインで、あまり多くの設定を書く必要はありません。
キーマッピングは <Space>
+ t
を設定しています。
テストスコープごとにキーマッピングを割り当てています。
nnoremap [vim-test] <Nop>nmap <Leader>t [vim-test]nmap <silent> [vim-test]n :TestNearest<CR>nmap <silent> [vim-test]f :TestFile<CR>nmap <silent> [vim-test]s :TestSuite<CR>nmap <silent> [vim-test]l :TestLast<CR>nmap <silent> [vim-test]v :TestVisit<CR>
Git のプラグインは vim-gitgutter 、 fugitive.vim 、 gv.vim を使用しています。
キーマッピングは <Space>
+ g
を設定しています。
ただ Git 系の機能は比較的呼び出し頻度が高く、もっと少ないタイプで呼び出せるようにしたいと思っています。
例えば hunk の diff を見るためだけに <Space>
+ g
+ h
+ p
と4つのキーを打つ必要があるので、ちょっとイケてないですね。
個々の機能の呼び出しのキーマッピングは Woody さんの Git プラグイン紹介を参考に以下のように設定しています。
nnoremap [git] <Nop>nmap <Leader>g [git]" vim-gitgutternmap [git]hs <Plug>(GitGutterStageHunk)nmap [git]hu <Plug>(GitGutterUndoHunk)nmap [git]hp <Plug>(GitGutterPreviewHunk)" fugitive.vimnmap <silent> [git]a :<C-u>Gwrite<CR>nmap <silent> [git]b :<C-u>Gblame<CR>nmap <silent> [git]c :<C-u>Gcommit<CR>nmap <silent> [git]d :<C-u>Gvdiff<CR>nmap <silent> [git]f :<C-u>Gfetch<CR>nmap <silent> [git]g :<C-u>Ggrepnmap <silent> [git]m :<C-u>Gmergenmap <silent> [git]p :<C-u>Gpush<CR>nmap <silent> [git]r :<C-u>Grebase -i<CR>nmap <silent> [git]s :<C-u>Gstatus<CR>" gv.vimnmap <silent> [git]la :<C-u>GV<CR>nmap <silent> [git]lc :<C-u>GV!<CR>
PHP Conference Japan 2020 で披露した Vim 拡張の具体的な設定内容について紹介しました。 登壇の最後に「LSP と Plugins を駆使すれば Vim でも PHP の開発は十分可能」と発言しましたが、 PhpStorm などと比較するとまだまだ改善の余地はあるのでこれからも拡張を続けたいと思います。 プラグイン自作が必要な匂いもしてきたので、来年は小さなものから開発に挑戦しようかな…という気持ちです。
また公式な場での登壇は今回が初めてでしたが、参加者同士のコミュニケーション用に開設されていた Discord チャンネル上では思ったよりも反響があって非常に嬉しかったです。 今後も( Vim に限らず)参加者の方に面白いと思ってもらえるようなプレゼンをしていきたいと思います。
あと蛇足になりますが、今回の登壇資料の作成には Marp という Markdown からスライドを生成するツールを使用しました。 スライド中にプラグインや参考サイトはリンクとして作っておいたのですが、今回の記事を書く際にそれらをそのままコピペすることができ、意図せず非常に重宝しました。 今後も積極的に使っていこうかなと思います😎
Written by Kosuke Hamada. You should follow him on Twitter