この記事は
私は、株式会社エニグモでチームのマネージャをしている後藤です。 マネージャ業務の傍ら開発作業を行うこともあります。
この記事はEnigmo Advent Calendar 2024の10日目の記事です。
この記事では多くのRubyを使っている人が、使っているであろうruby-lspを少し便利にする ruby-lsp-addons
について紹介しながら、VSCode
でどのように活用できるのかについて紹介したいと思います。
ruby-lspとは
ruby-lsp とは、Ruby言語向けに Microsoft が定義している、Language Server Protocolを実装したサーバになります。
Language Server Protocol
(以下 LSP
) は、プログラム中に定義されたクラス名、関数名、変数名などを取得できるAPIとデータ型を定義したものになります。プログラム中のデータを取得するAPIを定義しておくことで、エディタから対象言語に対応した LSP
サーバーを通して 関数定義情報を表示、関数/変数の定義箇所へのジャンプ、関数名/変数名を使った入力補間ができるようになります。
LSP
の登場以前は universal-ctags + GNU Global などを用いて同様の機能を実現することが多かったように思いますが、VSCode
の登場と合わせて LSP
の提案と普及が進みました。その結果、多くのエディタで LSP
がサポートされるようになり、最近は補間や関数ジャンプのための機能が LSP
に集約されつつあるように思います。
Visual Studio Code
(VSCode) の場合は、
ruby-lsp プラグインを VSCode
に追加することで rubyソース編集次に ruby-lsp を使った関数ジャンプや入力補間が使えるようになります。
ruby-lsp-addons
ruby-lsp ですが、当然ながら ruby の文法しかサポートしていません。ただ、Ruby on Rails の場合はモデルの has_many、blongs_to、validates などなど多数の DSL がありこれらもOUTLINEなどに表示して欲しいところですが、その機能を ruby-lsp に実装するのも違っている気がします。
そんな問題を解決しようとしているのが、 ruby-lsp-addons
機構になります。
公式のドキュメントは
Add-ons | Ruby LSP
にあります。ただ、公式ドキュメントにもあるように実験的な取り組みのようで、 ruby-lsp
のメジャーバージョンが変わると、インターフェイスが変わって addons が動かなくなることもありますし、将来a addons のサポートが終わってしまう可能性があることを心にとめて置いてください。
それでは、
について紹介していきたいと思います。
ruby-lsp-rails
こちらの add-on を使えるようにするには、ruby-lsp-rails
gem を追加します。
名前からわかる通り、rails 固有の機能サポートを追加するadd-onになります。 今回は、gitlabhq/gitlabhqのソースの一部を表示しながら、 公式ドキュメントからいくつかの機能を抜粋して紹介したいと思います。
modelのDSLサポート
# frozen_string_literal: true module Achievements class Achievement < ApplicationRecord include Avatarable include StripAttribute belongs_to :namespace, inverse_of: :achievements, optional: false has_many :user_achievements, inverse_of: :achievement has_many :users, through: :user_achievements, inverse_of: :achievements strip_attributes! :name, :description validates :name, presence: true, length: { maximum: 255 }, uniqueness: { case_sensitive: false, scope: [:namespace_id] } validates :description, length: { maximum: 1024 } def uploads_sharding_key { namespace_id: namespace_id } end end end
のようなコードがあると、 VSCode
の OUTLINE
には以下のように Rails 固有の DSL で定義された項目も表示されます。
コントローラーメソッドからviewへのジャンプ
コントローラのメソッド画面にviewを開くリンクが追加されます。
上の絵の赤枠で囲ったリンクが表示されるようになります。
この、Jump to view
をクリックすることで view が表示されます。
地味に、便利です。
その他の機能
公式ドキュメントを読むと、モデルの belongs_to のアソシエーション先にジャンプできる機能、コントローラーのメソッド定義箇所からルーターの定義にジャンプできる機能などがあることになっていますが、上手く機能していないようです。この辺は実験的な取り組みということを温かく見守ることしましょう。
ruby-lsp-rspec
次は、ruby-lsp-rspec です。
こちらも add-on を使えるようにするには、ruby-lsp-rspec
gem を追加します。
こちらも名前から想像できる通り、 rspec
向けの機能拡張を行う add-on になります。
以下のような specファイルを開くと、
# frozen_string_literal: true require "spec_helper" RSpec.describe Diffs::StatsComponent, type: :component do include RepoHelpers subject(:component) do described_class.new(diff_files: diff_files) end let_it_be(:project) { create(:project, :repository) } let_it_be(:repository) { project.repository } let_it_be(:commit) { project.commit(sample_commit.id) } let_it_be(:diffs) { commit.raw_diffs } let_it_be(:diff) { diffs.first } let_it_be(:diff_refs) { commit.diff_refs } let_it_be(:diff_file) { Gitlab::Diff::File.new(diff, diff_refs: diff_refs, repository: repository) } let_it_be(:diff_files) { [diff_file] } describe "rendered component" do subject { page } let(:element) { page.find(".js-diff-stats-dropdown") } before do render_inline component end ...
VSCode
の OUTLINE
に以下のように、 examples のテキストが表示されるため、 spec ファイルの流れを追うのも、修正をするのも楽になります。
また、以下のようにspecファイル上に Run | Run In Terminal | Debug
リンクが追加されます。
このRunなどをクリックすることで、rspecのテストを実行できます。また、これらのテスト機構が、 VSCode
の テスト機能に統合されているため、 以下のような VSCode
標準の、 Test: Run Test at Curosr などの機能が利用できるようになります。
また、テスト結果についてもGUIで表示られるようになります。
テスト結果がエラーになっているのは、DBなどを構築せずテストだけ実行したためで、gitlab のバグではありません。
使いたいんだけど、プロジェクトの Gemfiles に組み込めないんだけど
VSCode
の ruby-lsp ですが、インストール時の設定では、プロジェクトに bundle install
されているものを使う設定になっていると思います。そのため、プロジェクトの他のgemとの依存関係の問題で使いたくても最新の ruby-lsp
が使えない、なんて問題に出会う事があると思います。
そのような場合は、 ruby-lsp
などの ruby 開発サポート系ツールだけをインストールしたリポジトリを準備し、bundler でインストールした bin ディレクトリへ PATH
を通しておいて、 VSCode
上の設定を変更することで、プロジェクトは独立した形で、 ruby-lsp
を使うことができます。
手順は以下のようなGemfileを準備し
# frozen_string_literal: true source 'http://rubygems.org' gem 'ruby-lsp' gem 'ruby-lsp-rails' gem 'ruby-lsp-rspec'
対象ディレクトリで、
bundle config path vendor bundle install
しておき、VSCode
の settings.json
にいかの項目を追加します。
"rubyLsp.bundleGemfile": "${インストールディレクトリ}/Gemfile"
私の場合は、asdf を使ってrubyをいれているのもあってrubocop、erblint などをひとまとめにしたチェック系ツールをまとめたリポジトリを作り、homebrewとasdf用の環境セットアップをするラッパースクリプトを通して、bundle exec するシェルスクリプトから各種ツールを起動するリポジトリを作って使っています。
また、PCが変わっても VSCode
の設定が変わらないよう上記リポジトリを
/opt/ruby_tool
へcloneしています。
参考のために、 ruby_toolへのリンクも貼っておきます。頻繁にバージョンを上げたり、ツールを入れ替えたりしているので、ご利用される際は、forkしてお使いください。
最後に
最後までお読みくださりありがとうございました。
明日の記事の担当は 森田 さんです。お楽しみに。
また、株式会社エニグモでは、ツールやエディタのカスタマイズを愛する人エンジニアもそうでないエンジニアも広く募集しております。興味のある方は、以下の求人一覧をご覧ください。
株式会社エニグモ すべての求人一覧