Emacsからrakeを呼び出してみた
最近「プログラミングしてないなぁ……」とか思っちゃったので, 試しにTwitterのUser Streamsを使ったプログラムを書こうとしたのですが, ErlangからUser Streamsが使えなかったので*1別のプログラムに逃避した次第です, こんにちは. id:siritoriごめん.
で, 何作ろうかと考えてたら, 「そういえばEmacsからrake呼び出したいなぁ. あるのかなぁ. ありそうだよねぇ」とふと思い立った. 調べると, testタスクを実行するのはあっても, その他タスクを実行するのがなかったので, ちょっとだけ作ってみた.
(defvar rake:output-buffer "*rake output*") (defun rake:invoke () (interactive) (let ((task-suggestions (rake:task-suggestions))) (if task-suggestions (rake:run (completing-read "rake " task-suggestions)) (message "Not found target")))) (defmacro rake:deftask (task) (list 'defun (prog1 (intern (concat "rake:run-" task))) '() '(interactive) (list 'rake:run task))) (defmacro rake:task (task) (list 'lambda '() '(interactive) (list 'rake:run task))) (defun rake:task-suggestions () (reverse (reduce #'(lambda (suggestions line) (if (string-match "rake \\([^ ]+\\)" line) (cons (match-string 1 line) suggestions) suggestions)) (split-string (shell-command-to-string "rake -T") "[\r\n]+") :initial-value nil))) (defun rake:run (task) (call-process-shell-command (format "rake %s" task) nil rake:output-buffer))
使い方は.emacsとかに:
(require 'rake) (global-set-key "\C-cr" 'rake:invoke) (global-set-key "\C-cRd" (rake:task "default")) ;; C-c R dでdefaultタスクを実行する (rake:deftask "test") ;; testタスクを実行する関数rake:run-testを定義し, (global-set-key "\C-cRt" 'rake:run-test) ;; C-c R tでrake:run-testを呼び出す
な感じで. 一応タスク名を補完するようにしてあるけども, それをちょっとがんばったくらいで他がガタガタ. 後々ちゃんとさせる.
Lispは不慣れなので, 「この書き方よりもこっちの方がいいよ」とかあったら突っ込んでいただけると嬉しいです.
自分用メモ
- タスク名の一覧をキャッシュさせる(rake -Tの呼び出しに微妙に時間がかかるため). Rakefile(*.rake)のパスと更新時刻, タスク名一覧を持っておけばよさげ
- となると, Rakefile(*.rake)の探索をrakeと合わせておかなければならない
- *rake output*バッファにどんどん書き込まれるので, rake:runするたびにクリア
- キーバインドの設定を簡潔に記述できるようにする
- 直前に実行したタスクを記憶しておく. コレはRakefile(*.rake)ごとに記憶した方がいい気がする
あとなんかあるかなぁ……
*1:「使えたよ」という方がいたら教えていただけると嬉しいです