Geeks making the world a bit better.

Running Python from within Emacs

Emacs python mode supports running scripts in an inferior python process that is running in an emacs buffer. I really like this idea but have never been able to reliably use it because so much of my work depends on external libraries that may not do a complete job of cleaning up their state. Attempting to reuse them in the same process is, in my experience, a recipe for confusion. Also, emacs seems to be hung waiting on the python subprocess while my GUI app is running. As a result, I always edit in emacs and then switch to a command prompt to run.

It occurred to me that if I my program doesn’t need input (almost all mine have a GUI) I can run them using the emacs compile command. The compile command in emacs is intended for running make and other command-line build tools. The command runs in a separate process and its output is directed to an emacs buffer. I tried it out and it works great!

In my .emacs file I defined this function

(defun my-compile ()
  "Use compile to run python programs"
  (interactive)
  (compile (concat "python " (buffer-name))))
(setq compilation-scroll-output t)

This function invokes compile with python foo.py when I’m editing a buffer named foo.py. The setq makes the compilation buffer scroll to follow the output.

And then in my python-mode hook function I added:

  (local-set-key "\C-c\C-c" 'my-compile)

This binds Ctrl-C Ctrl-C to compile instead of the usual eval-buffer which I never use anyway.

Now I can edit and type Ctrl-C Ctrl-C to run. If my program raises an exception, I get a traceback in the emacs buffer. emacs parses the buffer looking for error messages. It notices the File lines in the trace back and sets them up so I can click on a filename to visit the file and line associated with the traceback.

I’m loving this! No more directing my program output into a file when I’m printing tons of debug messages. No more constant Alt-Tab to switch between emacs and the command prompt.

I’m using it on Ubuntu, but a quick test indicates this works on Windows also.

5 comments

#1 Thomas Heller on 03.18.08 at 2:52 pm

But you know about C-u C-c C-c, don’t you?

#2 Tom Ritchford on 04.19.08 at 9:48 am

“But you know about C-u C-c C-c, don’t you?”

I don’t know it – and neither does

GNU Emacs 21.2.1 (powerpc-apple-darwin8.0) of 2008-03-27 on tritchford-mac.local

which I have on this machine. (C-c C-c isn’t actually bound to anything). I spend most of my time on Linux machines, and I’m too lazy to boot one up but I’m 95% sure there’s no C-c C-c there…

It’s probably something in your local installation of emacs.

#3 Tom Ritchford on 04.19.08 at 9:49 am

And in general, a comment like “you know about C-u C-c C-c, don’t you?” seems to be more a brag than real help, even if the command existed.

#4 gb on 04.19.08 at 12:55 pm

I believe that in python-mode, C-c C-c is bound to execute the code in the “inferior” buffer running python. C-u conditions it to run asynchronously, which is almost what I wanted but not quite. I still prefer my compile hack.

#5 ndanger.organism :: blog :: nose.runmodule() on 08.05.08 at 10:25 pm

[...] useful for running a bunch of tests, but rumodule() allows for the snappy (ultra-snappy, thanks to Gary Bishop) C-c C-c in [...]

Leave a Comment