新年あけましておめでとうございます。
リアルタイムで読まれていない方は、こんにちは。
ヒコーキ好きのみこやんです。
VimmerなのでVimネタ続きになってしまいますが、こちらもやっとマトモに調整できた嬉しさから記事に。
とはいえ、今回のネタは「ちゃんと従来から理解して運用できていたVimmer」さんにとっては「オイオイ」っていう内容なので、ユルく読んでいただけると幸いです。
今回は、ALEによるLintとfixerを運用する話題です。
VSCodeやAtomといったモダンなエディタを使っている方がほとんどの開発者の世界では、各プログラミング言語に応じて、記述されているコードを動的に(すなわち入力時リアルタイムで)Lintや整形の違反を警告してくれるサポート機能をあたりまえのように使っていると思います。場合によっては警告どころか強制的に修正される場合もあるでしょう。
Vimにおいてもそうした需要が当然のようにあります。
古いVimmerの方だと、これまではsyntax highlighterのようなプログラミング言語の文法に応じた表示の色分けをする程度だったり、言語によっては専用プラグインを導入することで特定言語のLintやfixerによるサポートを受けることができていると思います。
これは現在でも有効な方法だとは思いますが、時代の要請により、Lintやfixerなどの開発支援ツールを外部サービスに依存することで、多様・多彩な支援を受けられるようになってきました。その1つの解決策として生まれたのがLanguage Server Protocolと言えるでしょう。Microsoftが提唱し、VSCodeでの実装を機に発展していった経緯があるようです。
こうした隆盛にVimも追従していった結果、ALEというプラグインが生まれ発展してきたところではないでしょうか。
ALEとは
本題をALEに戻します。
ALEは「Asynchronous Lint Engine」の略で、読んで字の如く非同期的にLintをサポートするエンジンです。
ALEは、先ほどのLanguage Server Protocolを「おしゃべり」できるプラグインです。したがって、Language Server Protocolをおしゃべりできる外部のLinterやfixerであれば、どんな言語であれ「会話」することで開発者支援をすることができます。
つまり、現在Vimで開いているプログラムファイルの言語の種類が理解でき、かつその言語の外部Linterやfixerが指定されていることで、コーディング中に動的に文法エラーや書式の不整合などをチェックし警告してくれます。設定次第では、保存時に自動的に修正してくれるなども可能です。
まさに、VSCodeなどのモダンなIDEと同じことをVimmerも享受できるわけです。
ALEのインストール
前回の記事で説明した通り、私はVimプラグイン管理にdeinを使っているため、以下の設定を.vimrcに記述するだけです。
1 |
call dein#add('dense-analysis/ale') |
保存したら一旦Vimを終了させ、再度起動してからインストールのコマンドを発行します。
1 |
:call dein#install() |
ALEのプラグインもGitHub経由で提供されているため、dein以外のプラグイン管理ツールでも、だいたい同じような感じで作業できると思います。
ALEの設定
ALEにはLinterとFixerの設定以外にもいくつか設定項目があります。
基本的にはデフォルトでも問題ない場合が多いですが、私が設定している項目をいくつかご紹介したいと思います。
警告・エラー表示に関する設定
LinterやFixerで分析された結果は、該当する行にシンボル(マーク)を表示することでプログラマに知らせます。
Airlineなどの、いわゆるイケてるステータスラインプラグインや、それらを使うのによく使われるPowerline Fontsなどを導入している方は、その中からVSCodeのようなカッコよさげな警告・エラーシンボルなどを選んで使えるかもしれません(三角ビックリマークなどのような、交通標識っぽいものなど)。
私もそのあたりはいろいろトライしてみましたが、最終的にはめんどくさくなり、今は単なる「●」記号で、警告は黄色、エラーは赤色にしています。
最初、私もPowerline Fontsかr選んでみたり、しかしフォントによっては描画ズレを起こしてグチャグチャになることもあったので、警告を普通の全角のエクスクラメーション(!)、エラーをバツ(×)にしていたのですが、はっきり言って識別しづらく見落としやすかったので、最終的に落ち着いたのが、中塗りされた●に色をつけたもの、となりました。みなさんはクールなアイコンを選択してみてください(AirlineやPowerline Fontsはググると様々な方が書かれていると思います)。
色は各自で認識しやすいもので設定をするのがオススメです。
1 2 3 4 |
let g:ale_sign_error = "●" let g:ale_sign_warning = "●" highlight ALEErrorSign ctermfg=9 guifg=#C30500 highlight ALEWarningSign ctermfg=11 guifg=#ED6237 |
ちなみに、この警告表示カラム(シンボルカラム)は、デフォルトでは警告やエラーがあるときだけ表示されます。
しかし、そのたびに桁が増えたり減ったりしてしまって若干うざったく感じました。
そこで、私は警告やエラーがないときでもシンボルカラムを表示したままにしておくようにしています。
1 |
let g:ale_sign_column_always = 1 |
また、QuickFixへのエラー・警告一覧表示がずっとでっぱなしになるのはコード編集スペースの妨げになるため、表示をオフに設定しています。
1 |
let g:ale_open_list = 0 |
保存時チェックに関する設定
ファイル保存時に、ALEによるFixerのチェックを走らせて、自動整形を行った結果を保存するように設定しています。
ただし、これは人によってはうっとうしい(あるいは邪魔である、整形は手動で行いたい…など)場合もあると思います。そういう場合はこのフラグは未設定か0で設定するとよいでしょう。
1 |
let g:ale_fix_on_save = 1 |
ALE自体の設定は、おおむねこんな感じです。
続いてLinterとFIxerのインストールと設定を行なっていきます。
php-cs-fixerの設定
php-cs-fixerは、正式名「PHP Coding Standards Fixer」といい、GitHub上でオープンソースとして開発されています。
いわゆるPSRに準拠するコーディング規約や、その他いくつかのコーディング標準などにも対応するLinterとFixerです。
インストール方法はいくつかあり、各自の環境やインストールのしやすさで選ぶのがよいでしょう。
ちなみに私はGitHub上でリリースされているpharファイルをwgetやcurlでダウンロードして使用しています。
/usr/local/binのようにシステムグローバルに展開してもいいでしょうし、ホームディレクトリ直下にbinディレクトリを作成して環境変数PATHを通して個人環境のみで使用できるようにしても、いずれでも動作します。ちなみに私は後者でセットアップしています。
1 |
let g:ale_php_cs_fixer_executable = $HOME . "/bin/php-cs-fixer" |
インストールが完了したら、設定でphp-cs-fixerコマンドのパスを指定しておくと良いでしょう。
私の場合は、ホームディレクトリの直下にbinディレクトリを作成してプライベートコマンドを配置するようにしているので、php-cs-fixerも以下のようにパスを設定しています。こちらは、各自のインストール環境に合わせた設定を行ってください。
なお、php-cs-fixerがちゃんと動作するかどうか、Vimに設定する前にコマンドラインから起動して確認しておくほうがよいでしょう。
もしこれで正しく起動しない場合は、ダウンロードやインストールに失敗している可能性があります。
バージョン表記の確認や、たとえば可能なら簡単なコードを書いて挙動を確認するのでもよいでしょう。
バージョンを確認するには、以下のように–versionオプションを指定することで表示されます。
1 2 |
$ php-cs-fixer --version PHP CS Fixer 3.4.0 Si! by Fabien Potencier and Dariusz Ruminski (47177af) |
あるいは、こんなコードを書いてみます。
1 2 3 4 5 6 7 8 |
$ cat test/test.php <?php $a = 'test'; if ($a == 'test') { echo 'OK'; } |
このコードのあるディレクトリをターゲットに、php-cs-fixerの出力を見てみることもできます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
$ php-cs-fixer -n fix --rules @PhpCsFixer --dry-run --diff test/ Loaded config default. Using cache file ".php-cs-fixer.cache". 1) bug/bug.php ---------- begin diff ---------- --- /Users/ezura.atsushi/prog/php/bug/bug.php +++ /Users/ezura.atsushi/prog/php/bug/bug.php @@ -2,6 +2,6 @@ $a = 'test'; -if ($a == 'test') { +if ('test' == $a) { echo 'OK'; } ----------- end diff ----------- Checked all files in 0.007 seconds, 12.000 MB memory used |
ここで適用しているコーディング標準は「@PhpCsFixer」ですが、これはかなり玉石混交というか、ほとんどのルールが含まれているため、上記の例ではif文の条件にヨーダ記法の使用がオススメされていますね。
チェック内容はともかく、一旦ここでは、php-cs-fixerの動作が確認できればOKとします。
次に、php-cs-fixerをLinterとFixerとして適用する設定を行います。
LinterとFixerのいずれにもphp-cs-fixeを採用しているため、以下のようにそれぞれにphp-cs-fixerを指定しています。
1 2 3 4 5 6 7 |
let g:ale_linters = { \ 'php': ['php_cs_fixer'], \} let g:ale_fixers = { \ 'php': ['php_cs_fixer'], \} |
ここで注意が1点。
コマンドは「php-cs-fixer」とケバブケース(cabab-case)になっていますが、ALEの設定では「php_cs_fixer」とスネークケース(snake_case)になっています。ダッシュ(ハイフン)とアンダーバー(アンダースコア)の違いに注意してください。
またALEのドキュメントなどにも記載がありますが、LinterやFixerは複数指定することができます。
ここではまず、動かなかった場合の問題の切り分けや見極めが複雑になることから、いったんphp-cs-fixerだけの設定を推奨します。
動いたら、他のLinterやFixerを追加で指定するとよいでしょう。
ここまで設定できたら、Vimを一度終了させて、さきほどのテストPHPファイルを開いてみましょう。
diffで示された箇所が、Vimの編集画面上でマークされ、QuickFixにメッセージが表示されていれば、無事セットアップは完了です。
ちなみに、もしメッセージも出ず、アラートのマーク(さきほど設定した「●」マーク)がつかない場合は、Vimのコマンド「:ALEInfo」を実行してみてください。
1 |
:ALEInfo |
ALEによってPHPのLinterとFixerの起動ログが残されているので、もし動作していない場合は、そのログにエラーの意味が記載されている場合があります。
よくあるのはパスの間違いだと思いますので、パスが通っているか、Vimから起動できるようになっているかなど、十分に確認してみるのがよいでしょう。
php-cs-fixerが使えるようになりました
ひとまず、ここまでの設定でphp-cs-fixerが使えるようにはなったかなと思います。
ただ、PhpCsFixerルールの適用などをしていると、実用上非常にうっとうしい警告や修正が行われることになります。
さきほどの例で見たように、ヨーダ記法などを推奨されても「イマドキ……」というウンザリ感がでてしまうことでしょう。
プロジェクトにマッチすればいいのですが、アンマッチなルールで警告されたりすると、かえって開発効率が下がってしまいかねません。
次回は、プロジェクトルールファイルを用意して、カスタム仕様にチューニングしていこうと思います。
(ひきつづき、開発ネタじゃなくてスミマセン……)
プログラミングもサーバもフロント(チョトだけ)もインフラ(オンプレ中心)もwebもゲームも組み込みも幅広く何でも雑多にやってきた古株ですが、フルスタックではありません。好きなものはプログラミングと計算機科学。我々と一緒に好きなプログラミングを楽しみませんか?