I do some Python coding on my own, and so I have a few python customizations. Python-mode now comes with GNU Emacs, and so these work pretty much out-of-the-box. However, this does not get autoloaded, so you have to put the following before modifying python-mode-map or python-mode-hook.
Before you start modifying python-mode-hook or python-mode-map or you get void-variable errors. Python-mode-hook is a collection of functions that gets run whenever python is entered, and python-mode-map is the list of keybindings that python-mode provides. Anyway, on to the customizations:
(add-hook 'python-mode-hook '(lambda () (eldoc-mode 1)) t)
I’ve talked about eldoc-mode before here. It is still one of my favourite minor modes, and I am greatly saddened whenever I realize a programming mode doesn’t have it. Fortunately, Python does, so I always know the arguments to my functions.
(defun my-insert-self () "Insert self. at the beginning of the current expression." (interactive) (save-excursion (search-backward-regexp "[ \n\t,(-]\\|^") (if (not (looking-at "^")) (forward-char)) (insert "self."))) (define-key python-mode-map (kbd "C-;") 'my-insert-self)
I forget to type ’self.’ in front of my variables a lot. If this happens, I can use this function to insert it at the beginning of the variable name I’m currently typing. This ends up saving me a ton of keypresses; I no longer have to navigate to the start of the name and back. This is even more efficient then typing ’self.’ in front of variable names; Two key presses instead of five, if you include the Control.
(defun python-self-insert-command () "appends __ to the string if it should" (interactive) (save-excursion (let ((cur (point))) (search-backward-regexp "[\n\t .(-]\\|^" 0 t) (if (not (looking-at "^")) (forward-char 1)) (if (looking-at "\\s\__") (setq my-temp-var t) (setq my-temp-var nil)))) (save-excursion (when (> (point) 2 ) (backward-char 2) (if (looking-at "__") (setq my-temp-var nil)))) (if my-temp-var (insert "__")) (self-insert-command 1)) (define-key python-mode-map (kbd ".") 'python-self-insert-command) (define-key python-mode-map " " 'python-self-insert-command) (define-key python-mode-map (kbd "(") 'python-self-insert-command)
This function similarly helps when I forget to append ‘__’ to private variables. I usually remember to put them at the beginning of a variable or function name, but often forgot the end. This function will check to see if the current function/variable starts with __, and if so append __ to it. This only occurs, of course, if __ is not already appended to the variable. I bind this function to space, period, and paren, so that I don’t have to actively think about this for it to happen. This function is more complicated than it seems it should be, but I haven’t quite figured out how to simplify it.
I haven’t investigated python-mode very much, since I’ve recently been using Python only lightly. Looking over it’s documentation, it looks like there are a few commands that could be quite useful, and the next time I write a significant project in Python I’ll definitely look through the manual, but these functions should tide me over until then. If you know of any cool commands in python-mode, don’t hesitate to let me know.
One final thing I was playing with that sounded very useful was ropemacs, an emacs integration of a python refactoring library. This provides refactoring and intellisense, but I could never get it to work. Ropemacs requires pymacs in order to run. Pymacs is a package for Emacs that attempts to enable you to use Python to modify Emacs instead of elisp, which I’d certainly be on board with. However, loading it into my emacs ended up installing a lot of hooks that didn’t work, making it difficult to even quit. I tried getting it to work, but never managed to. I also had a few philosophical problems with it, in that it used python’s egg system and did not allow me to specify where I wanted everything installed; this makes it hard to keep under version control so all of my computers can easily obtain it. If you know an easy way of getting it configured and working, please let me know; I’d love to be able to play around with it.