スポンサーリンク

2016年12月2日金曜日

続・ howm + ripgrep のちょっとした問題

前回 howm + ripgrep を使う上で発生する問題を考えました。
http://extra-vision.blogspot.jp/2016/11/howm-ripgrep.html

要約すると、ripgrep はマルチスレッドで並列検索を行なうため、howm-menu の「最近のメモ」の順番が狂ってしまう。-j1オプションを付けるととりあえずは回避できるが、シングルスレッド検索になるので、ripgrep の高速性を活かせない、というものでした。

まあ致命的な問題でもないし、それ以外の検索では ripgrep は十分速いので、最初は無視していたのですが、しかしどうにも気持ち悪いので何とかしてみました。


根本的な対策ではありませんが、howm-menu の時だけ、-j1 オプションを使うようにしてみます。

その前に、howm-menu の動作について少し説明しておきます。今回この問題を調べるために howm の動きをトレースして色々分かりました。

howm-menu は「最近のメモ」を検索するためにまず、タイムスタンプの新しい順にメモファイルN個を選び出します。ここでN個は howm-menu-recent-num に設定されている値です(デフォルトは20)。この選び出されたファイルを一気に grep に渡し、一回の grep 呼び出しで検索します。

その後で「ランダムセレクト」のための検索を行ないますが、この時は一ファイルにつき一 grep 呼び出しで検索しています。

なので、-j1 オプションで影響を受ける(つまりマルチスレッド性が活かせない)のは前半の「最近のメモ」の部分だけです。この位であればまあ許容範囲かなという気がします。

本題を外れますが、後半のランダムセレクトの検索の方こそ ripgrep の並列性を使いたい所です。こちらは順番が狂おうが一行に構わないので。

さて最終的に辿り付いたコードは以下の通りです。Emacs の advice 機能を使って、関数の実行前、実行後に変数 howm-view-grep-option を強制的に設定します。howm-menu 関数に設定するとメニュー更新時に有効にならないので、howm-menu-refresh 関数に設定しているところがポイントです。

(setq howm-view-use-grep t)
(setq howm-view-grep-command "rg")
(setq howm-view-grep-option "-nH --no-heading --color never")
(setq howm-view-grep-extended-option nil)
(setq howm-view-grep-fixed-option "-F")
(setq howm-view-grep-expr-option nil)
(setq howm-view-grep-file-stdin-option nil)

;; howm-menu で -j1 オプションを使う
(defun howm-menu-with-j1 (orig-fun &rest args)
  (setq howm-view-grep-option "-nH --no-heading -j1 --color never")
  (apply orig-fun args)
  (setq howm-view-grep-option "-nH --no-heading --color never"))

(advice-add 'howm-menu-refresh :around #'howm-menu-with-j1)

0 件のコメント :

コメントを投稿