現在のバッファのスクリプトを実行(をvirtualenvにも対応させてみた)

環境変数のWORKON_HOMEに依存しているので、virtualenvwrapper向けかも。

発端

compile関数を通じてコマンドを実行すると、エラー発生時に発生源に飛べるのでうれしい。発生したエラー箇所から利用しているライブラリの中に飛ぶ際、既存のpythonを使う(/usr/bin/pythonなど)場合には、書き換え権限の無いファイルに飛ぶことになる。本当は、ちょこっとファイルの中身を変えて動かしてみたい。そんな時、sudoを付けて修正とかしたくない。

そこでvirtualenv。virtualenvなら、ローカルな環境にライブラリを持つことになるので書き換え自由自在*1emacsからも使えるとうれしい。

でも、利用する環境を逐一設定してから実行するのは面倒くさすぎる。実行時にどの環境で実行するか振り分けてくれるとうれしい。

code

コメントは依存しているマクロの定義

;; (require 'cl)

;; (defmacro and-let*
;;   (bindings &rest body)
;;   "imported from srfi-2"
;;   (reduce (function
;;            (lambda (binding r)
;;              (let ((head (car binding)))
;;                (cond ((and (atom head) (symbolp head))
;;                       (\` (let ((\, binding)) (when (\, head) (\, r)))))
;;                      ((listp head)
;;                       (\` (when (\, head) (\, r))))
;;                      (t (error "and-let*: invalid head %s" head))))))
;;           bindings
;;           :from-end
;;           t
;;           :initial-value
;;           (\` (progn (\,@ body)))))
;; (put 'and-let* 'lisp-indent-function 1)

(defun python-call-python-current-buffer () (interactive)
  (or
   ;; virtualenv's python
   (and-let* ((workon-path (getenv "WORKON_HOME"))
              ((string-match (format "%s/\\([^/]+\\)" (expand-file-name workon-path)) default-directory))
              (env (match-string 1 default-directory))
              (file (buffer-file-name))
              (rcfile (format "~/.%src" (file-name-nondirectory (getenv "SHELL")))))
     (compile (format "(source %s && workon %s && python %s)" rcfile env file)))
   ;; default python
   (and-let* ((file (buffer-file-name)))
     (compile (format "%s %s" python-command file)))))

毎回、.zshrc、.bashrcなどを読んでからworkonしているのでちょっと実行がもたつく。

*1:後で戻しておきましょう