Emacs and Python

Currently at Manchester we’re debating whether to try and use more open source software like Python within our research. I’d never used Python before but whilst learning it I wanted to configure it for use in Emacs.

Unfortunately I couldn’t find a guide to setting up Emacs for scientific computing. However there is a lot of information out there (references at the end). This post will hopefully bring together the basic information needed to get a working Python setup in Emacs for computational scientists.

Downloading packages

The first step is installing some packages from the Emacs package manager. If you’re using Emacs 24+ then package.el is included, otherwise you’ll need to download it. Once it’s working add the following repositories to your .emacs file:


(setq package-archives '(("gnu" . "http://elpa.gnu.org/packages/")
                         ("marmalade" . "http://marmalade-repo.org/packages/")
                         ("melpa" . "http://melpa.milkbox.net/packages/")))

Now from Emacs type M-x list-packages to open the package manager. There is lots of great stuff here but you’ll need the following.

  • auto-complete
  • autopair
  • ipython
  • jedi
  • python-mode
  • python-pep8
  • python-pylint
  • ropemode
  • pymacs

These will give you access to lots of great code analysis, refactoring and auto completion tools from within the Emacs interface.

Once you find the packages press ‘i’ to mark them for installation and then ‘x’ to install them all.

The .emacs setup

Now all the necessary packages are there, we’ll add them to the Emacs load path before customizing them a little. Add this to .emacs:


(let ((default-directory "~/.emacs.d/elpa/"))
        (normal-top-level-add-subdirs-to-load-path))

Now I’ll go through the rest of my .emacs setup where the comments explain what each section does.


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; PYTHON
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Start autocomplete and jedi for refactoring
(add-hook 'python-mode-hook 'auto-complete-mode)
(add-hook 'python-mode-hook 'jedi:ac-setup)

;; Hook up flymake to use the PEP8 style
(add-hook 'python-mode-hook
        (lambda ()
                (unless (eq buffer-file-name nil) (flymake-mode 1))
                (local-set-key [f2] 'flymake-goto-prev-error)
                (local-set-key [f3] 'flymake-goto-next-error)
        ))
(when (load "flymake" t)
        (defun flymake-pylint-init ()
                (let* ((temp-file (flymake-init-create-temp-buffer-copy
                        'flymake-create-temp-inplace))
                (local-file (file-relative-name
                        temp-file
                        (file-name-directory buffer-file-name))))
                (list "pep8" (list "–repeat" local-file))))
        (add-to-list 'flymake-allowed-file-name-masks
                '("\\.py\\'" flymake-pylint-init)))
(defun my-flymake-show-help ()
        (when (get-char-property (point) 'flymake-overlay)
                (let ((help (get-char-property (point) 'help-echo)))
                        (if help (message "%s" help)))))
(add-hook 'post-command-hook 'my-flymake-show-help)

;; Start autopair to complete brackets and quotes
(add-hook 'python-mode-hook 'autopair-mode)

;; Start pylint and PEP8
(require 'tramp)
(require 'compile)
(autoload 'python-pylint "python-pylint")
(autoload 'pylint "python-pylint")
(load "python-pylint")
(autoload 'python-pep8 "python-pep8")
(autoload 'pep8 "python-pep8")
(load "python-pep8")

;; Delete trailing whitespace when saving (compliance with PEP8)
(add-hook 'before-save-hook 'delete-trailing-whitespace)

;; Start pymacs
(require 'pymacs)
(pymacs-load "ropemacs" "rope-")

;; Make IPython the default shell
(require 'ipython)
(defvar py-mode-map python-mode-map)
(setq
        python-shell-interpreter "ipython"
        python-shell-interpreter-args ""
        python-shell-prompt-regexp "In \: "
        python-shell-prompt-output-regexp "Out\: "
        python-shell-completion-setup-code
                "from IPython.core.completerlib import module_completion"
        python-shell-completion-module-string-code
                "';'.join(module_completion('''%s'''))"
        python-shell-completion-string-code
                "';'.join(get_ipython().Completer.all_completions('''%s'''))")

;; Custom Keybinds
(add-hook 'python-mode-hook
        (lambda ()
                (local-set-key (kbd "C-c p") 'pylint)
                (local-set-key (kbd "C-c o") 'pep8)
                (local-set-key (kbd "C-c i") 'ipython)
        ))

;; IPython command line args
;; use –colors=LightBG if you have a white background
;; –pylab automatically imports all pylab functions
(add-hook 'python-mode-hook
          (lambda ()
                 (setq py-python-command-args (quote ("–colors=Linux" "-i" "–pylab")))))

;; Pylint options
;; Defaults don't allow single letter variable names like
;; A for a matrix or x for a vector
(setq pylint-options "–function-rgx='[a-z_][A-Za-z0-9_]{2,30}' –argument-rgx='[A-Za-z_[A-Za-z0-9_]{1,30}' –output-format=parseable")

This will give you some useful keyboard shortcuts.

  • F2: Go to previous error
  • F3: Go to next error
  • C-c p: Start pylint analysis
  • C-c o: Start PEP8 analysis
  • C-c i: Start IPython shell

More information

There’s a lot of information available on using Python and Emacs together, a lot of it is duplicated which made it hard for me to track down the original source of these modifications. However some pages I found particularly useful pages were:

Have I missed any major packages? Do you have any other useful tips? Please let me know in the comments!

Advertisements

2 thoughts on “Emacs and Python

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s