Subscribed unsubscribe Subscribe Subscribe

Emacsで"*.t"ファイルに対してproveを実行する関数を書いてみた

Emacs Perl

unwind-protect: Emacs の中から prove
*.tのときはmode-compileでperlじゃなくてproveを実行したい - (ひ)メモ
のように設定すれば良いのだけど、せっかくなので少しくらいelisp分かるようになりたいし、ということでanything-projectのソースを参考にしつつ自分で書いてみた。
GitHub - imakado/anything-project: finding any resource of a project

(defvar root-files '("Makefile.PL"))
(defun current-directory ()
  (file-name-directory (expand-file-name (or (buffer-file-name)
                                             default-directory))))
(defun perl-get-root-directory ()
  (loop with i = 0
        with cur-dir = (current-directory)
        while (< i 10)
        do (if (some 
                (lambda (file) (find file (directory-files cur-dir) :test 'string=))
                root-files)
               (return cur-dir))
        (setq cur-dir (expand-file-name (concat cur-dir "../")))
        (incf i)
        finally return nil))
(defun perl-run-test ()
  (interactive)
  (let ((compile-command 
         (cond ((string-match "\\.t$" (buffer-file-name))
                (let ((root-dir (perl-get-root-directory)))
                  (concat (if root-dir
                              (concat "cd " root-dir "; "))
                          "prove --nocolor -l \"" (expand-file-name (buffer-file-name)) "\"")))
               (t (concat "perl -c " (buffer-file-name))))))
    (call-interactively 'compile)))

(current-directory)で現在のバッファのあるパスを取得、(perl-get-root-directory)でそこからディレクトリを遡って"Makefile.PL"などroot-filesに設定したファイルがあるディレクトリ(プロジェクトのルートディレクトリ)を見つける。
(perl-run-test)は"*.t"ファイルであれば前述のルートディレクトリを起点として"prove -l"をcompile-commandとして実行。そうでないファイルは普通に"perl -c"でコンパイルを試みる。
compile-commandを使うと、結果がCompilation bufferに表示されてエラー箇所が簡単に分かるし追いかけやすいので便利。
まだ色々と不具合あると思うけどとりあえずこれを使ってやってみる。
elisp詳しい人にツッコミとかいただけると嬉しいです…!