Windows 10 HomeのEmacs(26.2)からrgrepを実行したときに、ripgrepが起動されるように設定してみた。

By | 2019年9月26日

かなり長い前置き。

Windows 10 HomeにインストールしたEmacs 26.2(MinGW版)を使ってPlay framework+Scalaで実装したログイン認証とかセッションとか、データベースへの読み書き及び追加並びに削除機能を備えたものすごく簡単な(※無理解な周囲の発言です。)Webアプリケーションを作ろうと2週間ほど格闘した結果…

なんとか動きました!!

長かった… (ノД`)

Emacsでの作業を行うにあたり、使用感を統合開発環境におけるものにできるだけ近づけるために、

  1. neotree: ディレクトリ構造の階層表示。
  2. Metals: 入力補完。
  3. 独自開発のツール: データベースの定義からデータベースへのアクセス用のScalaのコードを出力する簡易ツール。コマンドラインで使用する。

をインストールしたり作成したりして用意をしました。

そうこうしているうちに、本体のWebアプリケーションの開発が終わってしまいました。

ただ、

「ファイルを跨いだファイルの中身の検索機能(日本語の文字列が検索できれば尚可)」

がないのが徐々に気になりだしたので、「Emacs grep」的な検索語でGoogle先生にお伺いを立ててみたところ、「rgrep」なるものがあることを発見。

「これだ!!🎯」と思い、

…と、うっかりツイート🐵してしまいましたが、日本語の検索を行うためにはちょっとした工夫が必要であることが判明しました。


スポンサーリンク

そこで、工夫をしてみることにしました。

スポンサーリンク

さっそく工夫してみた。

まず、lgrepが使えないか調べます。

Windows標準のgrepはUnixのgrepと仕様が異なることと、日本語の文字列に対応させるために、lvのシンボリックリンク版であるlgrepをインストールして使うことを試みました。

しかし、ビルドができなかったり、Windows標準のコマンドプロンプトで直接使えなかったりしたので、使用を断念しました。

ripgrepの登場です。

lv,lgrepが使えないということで、ちょっと絶望的な気分になりながら、それら以外にWindowsで使えるものがないか調べてみたところ、ripgrepなるものを発見しました。

grepよりも高速であることがウリのようですが、今回の設定の趣旨的にはUTF-8対応でかつ、MSYS2やCygwinが不要であることの方が本Webサイトの管理人たるpandaの興味を引きました。🐼

ripgrepのインストール

そこで、ripgrepをインストールしてみることにしました。

開発元のWebサイト(GitHub)を見に行くと、いろいろなインストールの方法が記述されていて、使う側の関心の高さを伺わせますが、以前Metalsのインストール及びセットアップを行った際にscoopをインストールしたので、Windowsのコマンドプロンプトから以下のコマンドを実行してripgrepをインストールします。ripgrepの実行ファイルは、rg.exeという名前でインストールされます。

c:\Users\pandanote> scoop install ripgrep

スポンサーリンク

 

なお、scoopをインストールしていない別のPCで、MSVCでビルドされているexeファイル(rg.exe)をダウンロードして適当なディレクトリにコピーして使ってみましたが、問題なく動作することを確認することができました。

Emacsから起動するための設定。

ripgrepがインストールできて動作確認ができたら、Emacsから起動するための設定を行います。

%HOME%\.emacs.dの下にあるinit.elに以下の設定を追加します。findコマンドについてはたまたまインストールされていたGit for Windowsに同梱のものを利用しています。また、nullデバイスを設定するとエラーとなってしまうので、設定を行わないこととしました。

(setq find-program “\”C:\\Program Files\\Git\\usr\\bin\\find.exe\””
grep-program “\”C:\\Users\\pandanote\\scoop\\shims\\rg.exe\””
grep-use-null-device nil)

 

さらに、サブプロセスに渡すパラメータの文字コードを cp932 にするための設定として、以下の設定も前述のinit.elに追加します(ここの設定例をほぼそのままコピペしています)。なおCygwinは使用していないため、Cygwin関連の設定は行いませんでした。

(require ‘cl-lib)

(setenv “LANG” “ja_JP.UTF-8”)

(set-file-name-coding-system ‘cp932)
(setq locale-coding-system ‘utf-8-unix)

;; プロセスが出力する文字コードを判定して、process-coding-system の DECODING の設定値を決定する
(setq default-process-coding-system ‘(undecided-dos . utf-8-unix))

;; サブプロセスに渡すパラメータの文字コードを cp932 にする
(cl-loop for (func args-pos) in ‘((call-process 4)
(call-process-region 6)
(start-process 3))
do (eval `(advice-add ‘,func
:around (lambda (orig-fun &rest args)
(setf (nthcdr ,args-pos args)
(mapcar (lambda (arg)
(if (multibyte-string-p arg)
(encode-coding-string arg ‘cp932)
arg))
(nthcdr ,args-pos args)))
(apply orig-fun args))
‘((depth . 99)))))

 

rgrepの動作確認。

ここで、Emacsを起動してrgrepの動作を確認してみます。

下図の赤矢印のディレクトリ(srcディレクトリ)の下にある拡張子が”scala”のファイルを再帰的に検索し、日本語の文字列を含む行を表示させてみます。

検索は以下の手順で実行することができます。

  1. M-x rgrepと入力し、Enterキーを押します。
  2. Emacsのミニバッファ(以下、単に「ミニバッファ」と書きます。)に”Search for:”と表示されますので、日本語の文字列を入力します。ここでは「その他」と入力し(下図の赤矢印)、Enterキーを押します。
  3. ミニバッファに以下のように表示されますので、”*.scala”と入力し(下図の赤矢印)、Enterキーを押します。

  4. スポンサーリンク

  5. 検索を開始するディレクトリの入力を要求するメッセージ(下図の赤矢印)がミニバッファに表示されますので、必要に応じて修正し、Enterキーを押します。
  6. すると、検索が実行されてその結果が2つに分割されたバッファの片側に表示されます。バッファの最初の方はEmacsから起動されたコマンドが表示されますが、スクロールすると検索の結果が表示されます(下図の赤矢印)。
  7. 検索の結果として表示されるファイル名の部分(上図の赤矢印)をクリックすると、もとのバッファにそのファイルの中身が表示され、検索語として指定した文字列と一致する行が表示されます(下図の赤矢印)。

ここまでの手順で、rgrepの動作を確認することができます。

スポンサーリンク

まとめ

ScalaはJavaよりも簡潔にコードを記述できますが、それでもコードの量が増えてくると、どこに何か書いてあったのかが次第にわかりにくくなることが予想されます。

そんなときに、rgrepによる日本語の検索が可能であることがわかっていれば、Scalaのコード中に日本語のコメントを書いておくことで、日本語によるコメントの検索を介して目的とするコードに容易に到達できるようになりますので、コードの捜索によるコーディング作業の低下を防ぐことができそうです。

これで、Emacsの使い勝手を統合開発環境のそれに少しだけ近づけることができたと思います。

この記事は以上です。

References / 参考文献