MAGAZINE

ルーターマガジン

Ruby

VimでモダンなRuby開発環境を構築する

2021.11.02
Pocket

最近VSCodeからVimに乗り換えたエンジニア、kanekoです。Vimの魅力はそのカスタマイズ性と、何よりかっこいいことにあると思います。黒い画面でカーソルを高速に動かし、目にも止まらぬ速さでファイルを編集するVimmerには畏敬の念が絶えません。さて、今回はそんなVimでモダンなRuby開発環境を構築する方法についてまとめます。ここで言うモダンとは、コード補完や定義ジャンプなどの開発支援環境が整っており、快適に開発ができることと定義します。では、早速本題に入ります。

環境

  • MacOS Catalina
  • neovim 0.5.0
  • Ruby 3.0.0
  • Rubocop 1.22.1

※プラグインの関係上、neovimを使用します。

使用するプラグイン

  • coc.nvim
  • ale
  • vim-endwise

coc.nvimの導入

まず初めにcoc.nvimを導入します。coc.nvimはLSP(Language Server Protocol)をサポートするためのプラグインで、それ以外にもLanguage Server自体のインストール、設定の管理なども合わせて行うことができる非常に便利なプラグインです。リポジトリの説明に従ってインストールします。
https://github.com/neoclide/coc.nvim
私はプラグインの管理にVim-Plugを使っているので、以下を追記しました。

Plug 'neoclide/coc.nvim', {'branch': 'release'}

プラグインのインストールが完了したら、次はLanguage Serverのインストールです。ここではRubyのLanguage Serverとしてsolargraphを使います。インストールは以下のVimコマンドを打ち込むだけで完了します。

:CocInstall coc-solargraph

さて、ここで試しにRubyファイルを作ってみましょう。"hoge".まで打つと以下のように補完されました。

Stringに適用できるメソッドを候補として表示してくれています。これはめちゃくちゃ捗りますね!

補完機能をもう少し便利に使うために、init.vim(.vimrc)に以下の設定を追記します。

function! s:check_back_space() abort
  let col = col('.') - 1
  return !col || getline('.')[col - 1]  =~ '\s'
endfunction

inoremap <silent><expr> <Tab>
      \ pumvisible() ? "\<C-n>" :
      \ <SID>check_back_space() ? "\<Tab>" :
      \ coc#refresh()

この設定によって、Tabキーを使って補完候補を選択することができます。使用感としてはVSCodeの補完と全く同じになります。

aleの導入

次に、aleを導入します。aleとは非同期のコードチェックを行ってくれるプラグインで、任意のタイミングでコードチェックを実行し、エラー箇所をハイライトしてくれます。これにより、コードを実行したと思ったらシンタックスエラーですぐに止まってしまった、というような悪い開発体験から解放されます。こちらもREADMEに従ってインストールします。コードのチェックにはRubocopを使用するので、Rubocopがない場合はgem install rubocopでインストールしておいてください。
https://github.com/dense-analysis/ale#installation
私はVim-plugを使用しているので、以下の記述を追加しました。

Plug 'dense-analysis/ale'

ここで、coc.nvimとaleを連携するために、READMEに従って以下の設定をinit.vim(.vimrc)に追記します。

let g:ale_disable_lsp = 1
let g:ale_lint_on_text_changed = 1

最後の記述はテキストが変更されるたびにコードチェックを走らせるための設定です。ここまでできたらもう一度Rubyファイルを開き、コードチェックが走っているかをチェックします。例えば文字列のクォーテーションをうっかり閉じ忘れた場合は...。

このように、左側にシンタックスエラーを示す赤いマークと、ステータスバーに具体的なエラーの内容を表示してくれます。シンタックスエラー以外のRubocopのエラーは黄色で表示してくれるため、実行に支障が出るエラーと出ないエラーが分かるようになっています。

定義ジャンプの設定

大規模な開発を行う際にはメソッドの定義ジャンプの機能が欠かせません。この機能はcoc.nvimで提供されています。READMEの例にある通りにキーマップを設定します。

nmap  gd (coc-definition)

これで、メソッド呼び出し箇所の上でgdを叩くとメソッド定義元にジャンプすることができるようになりました。早速以下のようなファイルを作って試してみましょう。

test.rb

def hoge_method
  "hoge"
end

test2.rb

require_relative './test'
hoge_method

ここで、test2.rbのhoge_methodの上でgdコマンドを押すと、カレントバッファがtest.rbを開き、hoge_methodの定義部分にカーソルが乗っています。戻る場合はctrl+oで戻ることができます。

vim-endwise

ここまででコード補完、シンタックスチェック、定義ジャンプの機能を導入してきました。これだけでも十分に便利なのですが、もう一つ痒いところに手が届くプラグインを紹介します。それがvim-endwiseです。


https://github.com/tpope/vim-endwise

このプラグインは単純明快、特に設定は必要ありません。メソッド定義やdo~endで必要なendを自動で挿入してくれます。シンプルイズベスト、VimでRubyを書くならほぼ必須のプラグインと言えるでしょう。

まとめ

ここまでのinit.vim(.vimrc)の設定をまとめると以下のようになります。

" coc.nvim タブで補完候補選択
 function! s:check_back_space() abort
   let col = col('.') - 1
   return !col || getline('.')[col - 1]  =~ '\s'
 endfunction
 inoremap  
    \ pumvisible() ? "\" :
    \ check_back_space() ? "\" :
    \ coc#refresh()
" coc.nvim gdで定義ジャンプ
nmap  gd (coc-definition)
" aleの設定
let g:ale_disable_lsp = 1
let g:ale_lint_on_text_changed = 1
" プラグイン
call plug#begin()
Plug 'neoclide/coc.nvim', {'branch': 'release'}
Plug 'dense-analysis/ale'                      
Plug 'tpope/vim-endwise' 
call plug#end()

このように、これだけの設定でVimでもIDE並みの開発環境を構築することができます。あとはvim-airlineで見た目をより見やすくしたり、Railsを使う場合はvim-railsを導入したりと、用途やお好みに合わせて改善の余地はまだまだあります。最近はVSCodeに押され気味なVimですが、ぜひ皆さんもVimを使って自分だけのRuby開発環境を構築してみてください!

Pocket

CONTACT

お問い合わせ・ご依頼はこちらから