rubyの静的型検査(steep)をvimから動かす

![スクリーンショット_090521_094242_PM.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17353/021f137a-e5d2-3d04-9ad5-f159c62a8985.jpeg)

# まずは行うべき設定から

## .vimrc

実際に動作を確認したときの.vimrc全部です。普段使っているものは一旦外しました。

最初の5行はvundleのための記述なので、使っているパッケージマネージャにあわせて適宜やる感じになると思います。

```vimscript
set nocompatible               " be iMproved
filetype off                   " required!

set rtp+=~/.vim/bundle/vundle/
call vundle#rc()

Bundle 'gmarik/vundle'
Bundle 'prabirshrestha/vim-lsp'
Bundle 'mattn/vim-lsp-settings'
Bundle 'prabirshrestha/asyncomplete.vim'
Bundle 'prabirshrestha/asyncomplete-lsp.vim'
let g:lsp_diagnostics_echo_cursor = 1
let g:lsp_diagnostics_echo_delay = 200
let g:lsp_diagnostics_virtual_text_enabled = 0
let g:lsp_diagnostics_signs_enabled = 1
let g:lsp_settings_filetype_ruby = ['solargraph', 'steep']
Bundle 'mattn/vim-lsp-icons'
```

## 実行するべきコマンド

rubyのファイルを開いて実行してください。

引数がないほうはsolargraph(rubyのデフォルト)をインストールしています。solargraphはsteepとは関係ありませんが、両方動かす設定を紹介したかったのでこの形にしてあります。

```
:LspInstallServer
:LspInstallServer steep
```

# 解説

## rubyの静的型検査

すでに先行の記事が多くあります。私が今回の設定を行おうと思った直接のきっかけは [そろそろRailsプロジェクトに型を導入したい人向けの資料](https://ksss.ink/blog/posts/10-ruby-type) です。

登場するgemが多く、理解するまではスムーズではありませんでした。いくつかの記事を読んでまわりましたが、自分が一番rubyの型検査についての理解を得られたのは [Ruby 3の静的解析機能のRBS、TypeProf、Steep、Sorbetの関係についてのノート](https://techlife.cookpad.com/entry/2020/12/09/120454) でした。

## [Language Server Protocol(LSP)](https://microsoft.github.io/language-server-protocol/)

Microsoftが開発した、エディタやIDEでの入力支援などを目的とした通信規格です。

VSCodeでの利用がさかんですが、通信規格にそった実装があればVSCodeに限らず利用できるのが魅力で、vimでは[vim-lspプラグイン](https://github.com/prabirshrestha/vim-lsp)などから利用できます。

vim-lspプラグイン単体では、各種LSPサーバーとの連携（による、入力支援などの）設定を結構しっかりめに書く必要があって、骨が折れるのですが、[vim-lsp-settingsプラグイン](https://github.com/mattn/vim-lsp-settings)を追加で導入すると、いくつかのLSPサーバーについて、非常に簡単に導入できるようになります。steepも導入できるようになりました。（わずか10日前。ホット！）

## vim-lspの設定変数

[設定の変数がものすごく多い](https://github.com/prabirshrestha/vim-lsp/blob/v0.1.4/doc/vim-lsp.txt#L15)です。私も最初は面食らいましたが、マニュアルを読んでいくと、設定の変数名にルールがあるので自分に必要なものが名前で見分けられることがわかります。

今回の設定に関係が深い、コード診断系についてだけ示します。ざっくり、

```
g:lsp_diagnostics_（反映される箇所）_（設定される内容）
```

です。diagnosticsは診断という意味です。

反映される箇所は

- echo→カーソルをあわせたときに下部に表示される
- float→たぶん補完のときみたいな感じで窓が出る、試せてない
- highlights→ハイライト、指摘箇所自体の文字色などが変わる
- signs→指摘箇所の行の左端にマークが表示される、エディタとかIDEでよくあるやつ
- virtual_text→指摘箇所の行の右側に指摘内容がそのまま出る 実際に編集するテキストではないからバーチャルテキスト、なんだと思う

みたいな感じです。なので

```
g:lsp_diagnostics_highlights_enabled
```

は「ハイライト表示を使うかどうか」です。

冒頭に示した設定は、ALEでrubocopの指摘を受けるのに慣れている私が、それに近い感覚で使うために行ったものです。人それぞれ好みの設定をしたら良いところだと思います。

# 確認した環境

- ruby 3.0.2 (on rbenv)
- nvim 0.5.0
- steep 0.46.0
  - bundler不使用で、直接gem installしています
- typeprof 0.15.2
  - 冒頭の画面に出ているrbsファイルの作成に使いました
  - ruby 3.0.2 に最初から入っているバージョンではエラーになったので、gem installを実行して新しいバージョンにしています


# 余談

- vimは当初nvimの0.3.0を使っていたのですが、signの表示がうまくいかず、0.5.0を導入して解決しました。WSL2でdebian10なのですが、パッケージからのインストールがうまくいかず、[直接ダウンロード](https://github.com/neovim/neovim/releases/tag/v0.5.0)して使っています。導入手順は非常に簡単でした（やったことはfuseのインストールとパス通すだけ）。
- rbenv localを利用している場合、vim-lsp-settingsプラグインから導入したLSPサーバーは、rbenv globalのrubyでbundle installを行うため、バージョンが違うと起動しないようでした。私は、LSPサーバーがインストールされているディレクトリ（~/.local/share/vim-lsp-settings/servers/steep など）上で、直接使いたいバージョンのrubyでbundle installして、強引に解決しました。
- 最初は自分で作っているRailsアプリで試していましたが、問題の切り分けが難しかったので、シンプルに型検査にひっかかるためのプログラムを[書きました](https://github.com/skuroki/hello_steep)。冒頭の画像の状況はすぐに再現できると思います。冒頭の設定でRailsアプリでも型検査ができることは軽く確認はしています。
- [solargraph](https://solargraph.org/)は今回ついでに導入したんですが、入力補完がrubyではできないだろうと（勝手に）思ってたレベルでやってくれるので一発で気に入りました。まだ入れない人は入れて、一緒に幸せになりましょう。