Tag | emacs
I have a new job and it’s quite probable that I will be doing Python for a lot of it. Which suites me just fine.
. . . except that I’ve been out of the loop in a while. Sure, I have written some Python in the past five years and some of it has been substantial but I feel out of the loop. Most of my simple scripts have been done in good ol’ Emacs and bigger projects have been done in Intellij IDEA with their amazing Python plugin.
As I started at the new digs, I installed Intellij on my shiny MacBook Pro, turned on Emacs mode . . . and was underwhelmed. I forgot that Emacs mode in Intellij on Mac leaves a lot to be desired —
C-Del for Cut,
Alt-P for paste? Ugh. A quick search shows that I’m not the only one complaining, but it’s not fixable.
I thought about Emacs and what I would miss about running things in Intellij IDEA. The biggies were:
- Syntax checking
- Running unit tests
- Auto-refactoring (Extract Variable, Method, etc)
These are things that are supposed to separate an IDE from a text editor. However, Emacs is an elegant weapon from a more civilized age. So the hunt is on to see what others have did while I was on my hibernation from Python.
I’ve tried to use the Rope library in the past and found it hard to setup. But I did note that it’s still actively developed and so I tried find to some example configs to
steal borrow from. That’s when I found Gabriele Lanaro’s excellent emacs-for-python collection. It included Rope, YA Snippet, and other goodies, all configured to work together in harmony.
I forked it, cloned it, and had a few problems, so I fixed them and Gabriele merged them back in. It still didn’t have unit test support, but I found nosemacs, which runs Nose on the Python unit tests.
In searching for something else, I stumbled into virtualenvwrapper, which are some helpers around the most excellent virtualenv utility, which creates a clean environment for Python development. These are used in emacs-for-python, so I put it in as well. I then stumbled into this post, which explains how to use the hooks in virtualenvwrapper to control Emacs. Woot!
So now my workflow is like this:
- type ‘workon something’, which will put my prompt in my “clean room” Python environment for the
project. My Emacs has also switched to that environment, including using that version of the Python interpreter.
- In Emacs, type
C-c m, which will run and report on all my unit tests in my current module
- In Emacs, type ‘C-c r ` to extract a new variable. Other commands exist for class, method, etc.
deactivateand my prompt moves away from my clean room, and my Emacs leaves too.
- when I go back to work on
somethingEmacs will remember the last buffers it worked on.
I put all these changes into my branch of emacs-for-python, and Gabriele has already pulled them in. They are available in HEAD on emacs-for-python
I love the FireFox plugin It’s All Text – it lets me edit wiki pages, webmail, etc. in my beloved editor of Emacs and automatically refreshes the text field in FF with my new text. But I recently moved from using NTEmacs to Cygwin’s version, and things simply stopped working. And it made sense — Cygwin is just a layer on top of Windows, but it uses Unix-like paths, while It’s All Text would, naturally, use Windows-style paths.
I put up with this for a few months, mostly because I didn’t want to spend the cycles on figuring this out. I did spend a few, and they were all pretty much worthless. I’m not sure why — the idea wasn’t hard, but it seemed to be.
A while back I decided to put some dedicated cycles to this. I found this comment from the It’s All Text developer on his blog — it didn’t work , but it was a start. I took his work and built my own version. I was trying to do it with a one-script solution but seeing his I knew I needed two: one batch file and then one shell script. After some experimenting,
The following batch script should be left alone. It sets up the Cygwin environment, and then uses Cygwin’s “run” command to start a bash shell, when then runs our shell script. The “%~f1″ is actually the most important component here. It is a batch file command that says to give the full path of the first argument. Of course, that assumes that the first argument is a file but considering we are using this with It’s All Text, we are safe with that assumption.
@echo off SET DISPLAY=127.0.0.1:0.0 SET CYGWIN_ROOT=c:\cygwin SET RUN=%CYGWIN_ROOT%\bin\run -p /usr/X11R6/bin SET PATH=.;%CYGWIN_ROOT%\bin;%CYGWIN_ROOT%\usr\X11R6\bin;%PATH% SET XAPPLRESDIR=/usr/X11R6/lib/X11/app-defaults SET XCMSDB=/usr/X11R6/lib/X11/Xcms.txt SET XKEYSYMDB=/usr/X11R6/lib/X11/XKeysymDB SET XNLSPATH=/usr/X11R6/lib/X11/locale rem the %~f1 is the full path name of the argument given to the script. %CYGWIN_ROOT%/bin/run.exe c:/cygwin/bin/bash.exe /cygdrive/h/bin/text.sh %~f1
The following is our shell script, which we referenced as “text.sh” above. It’s much simpler — it converts the Windows path it was given to a Unix path and then calls our editor (“emacsclient” in my case, which will load up the file in the current Emacs instance). You maybe thinking that I could have just was well as done this in the batch file above — and, you are right, I could have ran the editor but I had to also convert the file’s path first. That is really why we need two scripts — using a shell script is the only way I could find that would let me use the cygpath command in a reliable way. Note that I used “$*” at the path name — that will give all the arguments, which I need because there are spaces in the full path name (“$~f1″ above).
#!/bin/sh /usr/bin/emacsclient "`cygpath "$*"`"
So not easy, but it’s possible. Of course, I made it a lot easier now for everyone else!