Rakefileを再帰的に探してrake testするelisp(TB)
http://d.hatena.ne.jp/modka/20090820/1250759260
書いてみました。*1
(require 'cl) ;; (defvar raketest-old-color (frame-parameter (selected-frame) 'background-color)) (defvar raketest-output-buffer "*rake test output*") (defvar raketest-success-color "honeydew") (defvar raketest-fail-color "LavenderBlush") ;;util (defsubst raketest-parent-dir (path) "return parent directory path of argument." (substring-no-properties (file-name-directory path) 0 -1)) (defsubst raketest-find-target-file-dir (path target) (let* ((src (nreverse (split-string (raketest-parent-dir path) "/"))) (paths (maplist #'(lambda (l) (string-join (reverse l) "/")) src))) (loop for path in paths if (file-exists-p (concat path "/" target)) return path))) (defun raketest-find-rakefile-dir (path) "find Rakefile upward" (raketest-find-target-file-dir path "Rakefile")) (defun raketest-color-alert/hook (color reply &optional hook) (set-background-color color) (message reply) (run-at-time "1 sec" nil '(lambda () (set-background-color raketest-old-color))) (when hook (funcall hook))) (defsubst raketest-clean-up () (when (get-buffer raketest-output-buffer) (with-current-buffer raketest-output-buffer (erase-buffer)))) ;;interactive functioin (defun raketest-run () "find Rakefile upward and run `rake test`." (interactive) (raketest-clean-up) (let* ((rake-dir (and (buffer-file-name) (raketest-find-rakefile-dir (buffer-file-name)))) (cmd (format "cd %s && rake test" rake-dir)) (status (call-process-shell-command cmd nil raketest-output-buffer))) (case status ((0) (raketest-color-alert/hook raketest-success-color "test passed")) (otherwise (raketest-color-alert/hook raketest-fail-color "test failed" (lambda () (display-buffer raketest-output-buffer))) ))))
追記
string-joinは自分が定義した関数でした。
(defun string-join (sequence separator) (mapconcat #'identity sequence separator))
こちらの環境*2では、call-process-shell-commandは成功時に0,失敗時に1または127を返しています。