fzf を pry(Rails コンソール)で使う方法

結論

1. rb-readline の gem をインストールする

$ gem install rb-readline

2. .pryrc に以下のように書きます。

.pryrc は Ruby のスクリプトの形で書きます。

require 'rb-readline'
require 'readline'

if defined?(RbReadline)
  def RbReadline.rl_reverse_search_history(sign, key)
    rl_insert_text `cat ~/.pry_history | fzf --tac |  tr '\n' ' '`
  end
end

3. pry を実行して fzf が動作するか確かめる

fzf が動作すれば OK です。

f:id:gregminster:20200513073505p:plain

Rails で使うとき

Rails で使うとき($ rails console で使うとき)はやや複雑です。

パターン1. Gemfile に rb-readline を追加して、.pryrc を前述のように書く

楽なのはこの方法です。Gemfilerb-readline を追加しインストールして、.pryrc を前述のように書いて Railsアプリ のルートに置きます。

ただこの方法ですと、プロジェクト全体で rb-readline がインストールされることになります。

パターン2. Gemfile はそのままで、.pryrc に判定文を追加する

Gemfile を汚したくない場合には、.pryrc に追記をした上で、.pryrc のみを用います。追記をした上での .pryrc は以下のようになります。

# Inspired by https://gist.github.com/skojin/794915
if defined?(::Bundler)
  current_gemset = '/USER_NO_HOME_DIRECTORY/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0'
  $LOAD_PATH.concat(Dir.glob("#{current_gemset}/gems/*/lib")) if current_gemset
end

require 'rb-readline'
require 'readline'

def RbReadline.rl_reverse_search_history(sign, key)
  rl_insert_text `cat ~/.pry_history | fzf --tac |  tr '\n' ' '`
end

require をする前に gem の読み込み先を指定します。指定した読み込み先に rb-readline がインストールされていることが必要です。

上記の例では rbenv を用いた上で、2.7.1 の Ruby にインストールされた rb-readline を用いています。インストール場所がハードコードされていますが、個人的にはこれは許容範囲と思っています。

上記の .pryrc をホームディレクトリに置いてしまうとバージョン違いの危険性が生まれるため*1、それぞれの Railsプロジェクト のルートに置くのが望ましいと思っていて、その際にはハードコードするのが明示的で良いと思ったからです。

まあ難しいところだと思います。

参考(というかほぼ答え)

(参考)fzf とは

コマンド履歴*2をいい感じに表示、検索、再利用するためのツールです。

*1:ホームディレクトリには、追記部分を削除した .pryrc を置けば問題ないです

*2:history

Powered by はてなブログ