ale と LanguageClient-neovim の lint 比較

02/03/2019

読む際の注意

  • eslint, prettier, ale, LanguageClient-neovim, javascript-typescript-langserver を使って、何かを作ったことはありません。
  • eslint, prettier の設定方法や設定の解説は書いていません。
  • ale, LanguageClient-neovim, javascript-typescript-langserver の install 方法は書いていません、公式 github を参照してください。
  • language server protocol(lsp) の説明はしていません。
  • ale と LanguageClient-neovim は使い始めて、1週間も経っていないです。
  • ale と類似している syntastic, neomake は使った経験はありません。
  • ale も lsp 対応しているが、上手く連携できず、やっていません。
  • LanguageClient-neovim と類似している coc.nvim, vim-lsc, vim-lsp は使ったことがないです。
  • LanguageClient-neovim は lsp の指定と lint(diagnostics) 部分しか書いておりません。補完やコード実行などについては書いていません。
  • 比較は eslint + alt と LanguageClient-neovim + javascript-typescript-langserver の組み合わせでのみ比較しました。他の組み合わせで調査はしていません。
  • g:ale_lines などの変数を書く際、 g: は省略します。

環境

  • OS:Ubuntu Server 18.04 (vagrant を使用して作成)
  • neovim: v0.3.1

結論

  • ale: linter との連携設定を基本的にしなくてよく、 lint のタイミングを自由に設定でき、エラー・警告一覧を作成してくれる。lint の素早さは lsp に負けているが、速度はそんな重要ではないと思うので、特別な理由がない限り ale を選んだほうが良いと考えられる。
  • LanguageClient-neovim : lint の速さは ale より速い。insert 時・書き込み時に lint することはできず、コードを変更する毎に lint が実行される。ale のようにグローバル変数(g:LanguageClient_***)を変更するだけで、一覧を作成することはできない

読めばわかること

  • ale の linter と formater の設定方法
  • LanguageClient-neovim の Language Server の設定方法
  • ale と LanguageClient-neovim の問題箇所のハイライトとマーク表示の設定
  • ale の lint の実行タイミングを insert, 保存時などに変更する方法
  • ale のメッセージの書式の変更方法
  • ale の問題箇所一覧を自動的に表示・非表示にする方法
  • ale の lint 結果を lightline に表示する方法

ソフトの軽い説明

  • eslint: JavaScript の構文(syntax)と書式(format)をチェックし、修正してくれるソフト。1行の長さなどはチェックできないので、書式は prettier に任せ、構文チェックをメインに使う。
  • prettier: 書式をチェックし、修正してくれるソフト。 eslint はやれないけど、prettier ではやれるものがある。JavaScript だけではなく、html, css, yaml などにも使える。
  • ale: 非同期で構文・書式チェックをしてくれる、vim の plugin。 ale 自体が構文・書式チェックをする機能はなく、eslint などが必要で、ale は vim と linter や formater の中継役という位置。 JavaScript 以外にも色んな言語の linter や formater に対応している。lsp と連携することもでき、lsp を使用すれば、補完なども使用可能
  • LanguageClient-neovim: vim/neovim の lsp クライアント の plugin。lint 以外にも、補完やリネーム、定義ジャンプ、コード実行などができる。

ale

g:ale_liners などのようなグローバル変数の g: は以後省略して書きます。

速度

lint を実行して結果がでるまで約3秒。1秒くらいにならないかと思う。buffer 保存時に formatter と linter を両方実行するように設定すると、 lint 結果がでるまで6秒かかる。

linter の指定

  • linter を自動的に検知してくれるので、linter の設定をしなくてもOK。
  • 指定する場合、 ale_liners = {‘javascript’: [‘eslint’]} のように設定する

lint の実行タイミング

  • ale_lint_on_text_changed: テキストが変更された時
    • always: テキストが変更されたら、毎回 lint を実行する。 default 値
    • normal: normal モード時にのみ
    • insert: insert モード時にのみ
    • never: テキストが変更されても、 lint は実行しない
  • ale_lint_on_enter: buffer を開いた時。default は Yes(1)
  • ale_lint_on_save: buffer 保存時。 default は Yes(1)
  • ale_lint_on_insert_leave: insert モードから離れた際: default は No(0)

表示

  • ale_sign_***: 該当箇所がある行を示す記号(以後サイン)。左端に表示される。*** は error などが入る。
    以下 default 一覧
    • error: >>
    • style_error: g:ale_sign_error
    • warning:
    • style_warning: g:ale_sign_warning
    • info: g:ale_sign_warning
  • highlight: warning などは Error 部分がその名前に変わっているだけです。詳細は ‘help ale-highlights’ を読んでください。
    • ALEError: エラー箇所のハイライト
    • ALEErrorLine: エラーがある行全体のハイライト
    • ALEErrorSign: Error のサインのハイライト

メッセージ

  • ale_echo_msg_format: メッセージの書式。 default は ‘%code: %%s’
    • %s: 問題の内容
    • %…code…%: エラーコード
    • %linter%: linter の名前
    • %severity%: 問題の重大度。Error, Warning
  • ale_echo_msg_***_str: メッセージの %severity% で表示される文字。 *** は error, warning, info が入る
    Default 値は書いた順に、 Error, Warning, Info
  • ale_echo_cursor: カーソルが修正箇所に移動したら、command line window 部分にメッセージが表示。 default は表示する(1)
  • ale_cursor_detail: カーソルが修正箇所に移動したら、 preview-window が出現して、そこに問題の内容を表示。 g:ale_echo_msg_format の書式のメッセージではない。 default は表示しない(0)

修正一覧を作成

  • ale_open_list: lint を実行したら、修正の一覧が表示されている window を表示する。default は表示しない(0)
  • ale_keep_list_window_open: 修正箇所が0になっても、一覧を表示している window を開いたままにするか。 default では閉じる(0)
  • ale_set_locklist: lint 結果を location-list に記入するか。 default は Yes(1)
  • ale_set_quickfix: lint 結果を quickfix に記入するか。ale_set_loclist が 1 の場合は無効になる。 default は No(0)
    ※ quickfix は全体で一つのものを共有するので、他のツールで quickfix を使用している場合は、location-list を使用したほうが良い。
  • 修正箇所にジャンプする際は、 ale_previous_wrap, ale_next_wrap のコマンドで可能

lightline との連携

前までは、変数 ale_statusline_format とコマンド ALEGetStatusLine があったぽいが、私が使用しているV2.3.0以降(詳細の Version は help に書いていなかったのでわからない)ではなくなっている。自分で一から設定するのがめんどくさかったため、lightline-ale を使用

LanguageClient-neovim

速度

ale より速い。1秒かかるかかからないかくらい

lsp の指定

LanguageClient_serverCommands = { ‘javascript’: [‘language-server-stdio.js’], } のように、 lsp を指定しないといけない。

lint の実行タイミング

  • テキストが変更された場合のみで、コマンドで実行、保存時に実行などはできない
  • テキストが変更されたときも、 insert 時のみ、 normal 時のみもできない
  • LanguageClient_diagnosticsEnable を 0 にして、 lint を無効にすることが可能だが、LanguageClient-neovim を再起動しないと設定は反映されない

表示

  • LanguageClient_diagnosticsDisplay の値を変更する。 default は下を参照
  • texthl: 該当箇所のテキストの Highlight の名前
  • signText: サインの文字
  • signTexthl: サインの文字の Highlight の名前
// 引用元 https://github.com/autozimu/LanguageClient-neovim/blob/next/doc/LanguageClient.txt
{
         1: {
             "name": "Error",
             "texthl": "ALEError",
             "signText": "✖A,
             "signTexthl": "ALEErrorSign",
         },
         2: {
             "name": "Warning",
             "texthl": "ALEWarning",
             "signText": "⚠A,
             "signTexthl": "ALEWarningSign",
         },
         3: {
             "name": "Information",
             "texthl": "ALEInfo",
             "signText": "ℹA,
             "signTexthl": "ALEInfoSign",
         },
         4: {
             "name": "Hint",
             "texthl": "ALEInfo",
             "signText": "➤A,
             "signTexthl": "ALEInfoSign",
         },
 }

メッセージと修正一覧と lightline との連携

設定値だけを変更するだけではできない

ale の formatter 設定

  • ale_fixers = {‘javascript’: [‘prettier’],} のように、 formatter を設定する。formatter は検知しないので、設定を書かないと動かない
  • ale_fix_on_save: buffer 保存時に format するか。default は No(0)

参考資料

ale

https://rcmdnk.com/blog/2017/09/25/computer-vim/