プロジェクトディレクトリ以下のファイルをanythingで検索する

anything-find-project-resources

kiwanamiさんの作られているanything-find-project-resources*1というのがあって、これがとても便利なのだけど、ぼくはほかのanything-sourcesとまぜて使いたかったので、以下のようにsource部分を抜き出して、anything-sourcesに追加してみた。

(defvar anything-c-source-find-resource-project
  '((name . "find resource project")
    (init . (lambda ()
              (let* ((current-user-dir
                      (or (and buffer-file-name (file-name-directory (buffer-file-name)))
                          (expand-file-name default-directory)
                          (expand-file-name "~")))
                     (project-root-dir 
                      (anything-find-resource--find-project-root-dir current-user-dir))
                     (target-buffer (anything-candidate-buffer 'local)))
                (setq anything-c-resource-directory project-root-dir)
                (if project-root-dir
                    (anything-find-resource--collect-files-project-directory
                     anything-c-resource-directory target-buffer)
                  (setq anything-c-resource-directory (file-name-directory current-user-dir))
                  (anything-find-resource--collect-files-nonproject-directory
                   anything-c-resource-directory target-buffer))
                )))
    (candidates-in-buffer)
    (candidate-number-limit . 20)
    (delayed)))

しかし、init部分で時間がかかっているのか、anythingの起動がもっさりするようになってしまった。
そこで別の方法を試してみることにした。

あらかじめ検索対象のファイルリストを作ってファイルに保存しておき、その内容をanythingで検索する

まず検索対象のファイルのパスが一行にひとつずつ入っているファイルを作成して、projectのrootディレクトリにおいておく。
で、以下のようなanything-c-source-project-directoryというsourceを用意してこれをanything-sourcesに追加する。

;;; anything-find-resourceから抜き出したprojectのrootディレクトリを取得する関数
(defun project-root-dir ()
  (anything-find-resource--find-project-root-dir
		  (file-name-directory (buffer-file-name))))

(defvar anything-c-source-project-directory
  '((name . "Project directory")
    (init . (lambda () (setq project-dir (my-project-root-dir))))
    (candidates . (lambda ()
                    (split-string
                     (shell-command-to-string
                      (concat "cat " project-dir "/project.filelist"))
                     "\n")))
    (type . file)))

project-root-dirはanything-find-resourceからprojectのrootディレクトリを取得するためのコードを抜き出して関数にした。これ単体でも結構使える。
candidatesの部分で、ファイルの各行をリストに詰めるやりかたがわからなかったので、shell-command-to-stringでcatとかしてる。。

*1:http://trac.codecheck.in/share/browser/lang/elisp/anything-find-project-resources/trunk/anything-find-project-resources.el