2018-12-21

Windows上のEmacsでhelm-locateを使う(Windows Searchで)

helm-locateはWindowsではes.exe(Everything)を使うようになっています。

しかしWindowsでは標準でWindows Searchという検索エンジンが入っています。これが使えればわざわざ機能が被る別アプリ(サービス)を入れる必要は無くなります。Windows Searchは重いというのでOFFにしている人もいると思いますが一応標準で入っているものですし一時的にインデックスを停止することも出来るのでそれほど嫌がるものでもないと思います。

先日、helmからWindows Searchでファイル検索できるhelm-windows-searchを作成したのですが、helm-locateはhelm-find-filesから呼び出せるようになっている(C-x C-fで開いた後もう一回C-x C-fで開く)のでhelm-locate自体もEverythingではなくWindows Searchで動くようになっていれば便利そうだなと思いました。

方針としては、Emacs Lispとadoquery.exeで可能な限りlocateコマンドをエミュレートすることにします。

helm-locateでlocateコマンド(またはes.exe)を起動しているのはhelm-locate-init関数です。 この関数はコマンドラインの作成とプロセスの起動をまとめて行っています。 コマンドラインの作成部分だけ差し替えることは出来ないので、関数を丸丸置き換えることにします。

というわけで、先日のHelm Windows Searchhelm-locate-windows-search.elを追加しました。これをロードパスの通ったところに置き、adoquery.exeを同じディレクトリかまたはパスが通ったところに置き、次の設定をするとhelm-locate-initが置き換わります。

(autoload 'helm-locate-windows-search-setup "helm-locate-windows-search")
(with-eval-after-load "helm-locate" (helm-locate-windows-search-setup))

<helm prefix> l やC-x C-f C-x C-f でhelm-locateが開き、そこでWindows Searchを使った検索が出来ます。ただしlocateをエミュレートしているため、Windows Searchの複雑なクエリは書けません。 -bオプションでファイル名だけのマッチが出来るくらいでしょうか。

別にlocateコマンドにこだわる必要も無さそうなのでhelm-locate全体をhelm-windows-searchで置き換えてしまっても良いかもしれません。その場合は次のようにしてhelm-locate-1関数をhelm-windows-search-1関数へ置き換えてしまえばOKです。

(with-eval-after-load "helm-locate"
  (fset 'helm-locate-1
        (lambda (&optional localdb init from-ff default)
          (require 'helm-windows-search)
          (helm-windows-search-1 init default)))

locateコマンドではローカルDBが使えますがWindows Search(やEverything)ではできません。その代わりWindows Searchでは検索するディレクトリを限定する機能(SCOPEやDIRECTORY)があるのでうまく使いたいところですがどうにもうまくハマらなかったので実現出来ていません。