The website of Lei Chen

Sunshine and rain of a developer

Setup Perfect Python Environment In Emacs

Posted by hide1713 on January 30, 2009

This tutorial will show you how to setup a very convenient python IDE in Emacs. Many ideas in this tutorial came from emacs python wiki and Ryan McGuire Homepage . Many people on #emacs channel of freenode.net provided invaluable help. Freenode is one of the best communities I’ve ever known. It really takes time to combine all kinds of modes together and make them work. so I hope this tutorial could save you some time.

Requirments:

==========================

Software Version:Ubuntu 8.04 Emacs 22.1

Package required: python-mode.el , pymacs0.24 , auto-complete.el,  yasnippet.el, rope and  ropemacs

From my experience, many emacs packages in Ubuntu repository are out of data. So you’d better download emacs packages directly from Emacs wiki or the homepage of that mode. It not only keeps you from compatibility issues but also gives you extra portability when you move to another machine.   Let’s see some details of the final results. Hopefully,  these will give you enough anticipation to finish this tutorial.

Features

==========================

screenshot-emacs22-gtkhide1713-laptop2

Auto completion by auto-complete.el

1. Auto complete variable/ function names within a file. It’s really fast!

screenshot-emacs22-gtkhide1713-laptop-1

Code completion by Rope

2. Complete names in other files or python libraries.

3. code refectoring for more detail

screenshot-emacs22-gtkhide1713-laptop-2

Code expansion by yasnippets

4. templates  expansion including class, function, file header and almost anything you want. I use it to generate stander file header and if __name__==”__main__”  staff.

screenshot-emacs22-gtkhide1713-laptop-4

Display docstring by rope

5. Online help system.

6. Syntax checking on the fly

Other features are:

Smart Indent, Outdent, and Pair matching, additional to syntactic and semantic highlighting, code folding, instant rename refactoring, mark occurrences

Interactive Python Console

Smart math operator, Add space around operator such as =.+,-,*./ for better readability

How to install:

==========================

I assume that you have a .emacs file and .emacs.d directory in your home directory. If you don’t, create them and put this in your .emacs

(add-to-list ‘load-path “~/.emacs.d/”)

Dotemacs is a very good site for newbies. If you dont’ have .emacs, you want to go there and look for some basic settings

==========================

1.Download auto-completion.el to .emacs.d and put the following line in .emacs

(require ‘auto-complete)
(global-auto-complete-mode t)

2. Download yasnippet to .emacs.d and edit .emacs

(require ‘yasnippet)
(yas/initialize)
(yas/load-directory “~/.emacs.d/snippets”)

3. Download python-mode.el and put it in .emacs.d,  we will use it later.

4. Setup Rope, Ropemacs and Pymacs.

We need the latest development version of Rope and Ropemacs. Otherwise, emacs can not find the rope-completions function.
I just copy’n paste from Ryan’s website. You can find the original post here

sudo apt-get install mercurial
mkdir /tmp/rope && cd /tmp/rope
hg clone http://bitbucket.org/agr/rope
hg clone http://bitbucket.org/agr/ropemacs
hg clone http://bitbucket.org/agr/ropemode
sudo easy_install rope
ln -s ../ropemode/ropemode ropemacs/
sudo easy_install ropemacs

5. Install pyflakes for auto syntax check

sudo apt-get install pyflakes

6. Put everything together

Create init_python.el in your .emacs.d. Add following content

(autoload 'python-mode "python-mode" "Python Mode." t)
(add-to-list 'auto-mode-alist '("\\.py\\'" . python-mode))
(add-to-list 'interpreter-mode-alist '("python" . python-mode))
(require 'python-mode)
(add-hook 'python-mode-hook
      (lambda ()
	(set-variable 'py-indent-offset 4)
	;(set-variable 'py-smart-indentation nil)
	(set-variable 'indent-tabs-mode nil)
	(define-key py-mode-map (kbd "RET") 'newline-and-indent)
	;(define-key py-mode-map [tab] 'yas/expand)
	;(setq yas/after-exit-snippet-hook 'indent-according-to-mode)
	(smart-operator-mode-on)
	))
;; pymacs
(autoload 'pymacs-apply "pymacs")
(autoload 'pymacs-call "pymacs")
(autoload 'pymacs-eval "pymacs" nil t)
(autoload 'pymacs-exec "pymacs" nil t)
(autoload 'pymacs-load "pymacs" nil t)
;;(eval-after-load "pymacs"
;;  '(add-to-list 'pymacs-load-path YOUR-PYMACS-DIRECTORY"))
(pymacs-load "ropemacs" "rope-")
(setq ropemacs-enable-autoimport t)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Auto-completion
;;;  Integrates:
;;;   1) Rope
;;;   2) Yasnippet
;;;   all with AutoComplete.el
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun prefix-list-elements (list prefix)
  (let (value)
    (nreverse
     (dolist (element list value)
      (setq value (cons (format "%s%s" prefix element) value))))))
(defvar ac-source-rope
  '((candidates
     . (lambda ()
         (prefix-list-elements (rope-completions) ac-target))))
  "Source for Rope")
(defun ac-python-find ()
  "Python `ac-find-function'."
  (require 'thingatpt)
  (let ((symbol (car-safe (bounds-of-thing-at-point 'symbol))))
    (if (null symbol)
        (if (string= "." (buffer-substring (- (point) 1) (point)))
            (point)
          nil)
      symbol)))
(defun ac-python-candidate ()
  "Python `ac-candidates-function'"
  (let (candidates)
    (dolist (source ac-sources)
      (if (symbolp source)
          (setq source (symbol-value source)))
      (let* ((ac-limit (or (cdr-safe (assq 'limit source)) ac-limit))
             (requires (cdr-safe (assq 'requires source)))
             cand)
        (if (or (null requires)
                (>= (length ac-target) requires))
            (setq cand
                  (delq nil
                        (mapcar (lambda (candidate)
                                  (propertize candidate 'source source))
                                (funcall (cdr (assq 'candidates source)))))))
        (if (and (> ac-limit 1)
                 (> (length cand) ac-limit))
            (setcdr (nthcdr (1- ac-limit) cand) nil))
        (setq candidates (append candidates cand))))
    (delete-dups candidates)))
(add-hook 'python-mode-hook
          (lambda ()
                 (auto-complete-mode 1)
                 (set (make-local-variable 'ac-sources)
                      (append ac-sources '(ac-source-rope) '(ac-source-yasnippet)))
                 (set (make-local-variable 'ac-find-function) 'ac-python-find)
                 (set (make-local-variable 'ac-candidate-function) 'ac-python-candidate)
                 (set (make-local-variable 'ac-auto-start) nil)))
;;Ryan's python specific tab completion
(defun ryan-python-tab ()
  ; Try the following:
  ; 1) Do a yasnippet expansion
  ; 2) Do a Rope code completion
  ; 3) Do an indent
  (interactive)
  (if (eql (ac-start) 0)
      (indent-for-tab-command)))
(defadvice ac-start (before advice-turn-on-auto-start activate)
  (set (make-local-variable 'ac-auto-start) t))
(defadvice ac-cleanup (after advice-turn-off-auto-start activate)
  (set (make-local-variable 'ac-auto-start) nil))
(define-key py-mode-map "\t" 'ryan-python-tab)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; End Auto Completion
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Auto Syntax Error Hightlight
(when (load "flymake" t)
  (defun flymake-pyflakes-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 "pyflakes" (list local-file))))
  (add-to-list 'flymake-allowed-file-name-masks
	       '("\\.py\\'" flymake-pyflakes-init)))
(add-hook 'find-file-hook 'flymake-find-file-hook)
(provide 'init_python)

7.Add (load-library “init_python”) in your .emacs file.

How to use it?

==========================

Use Tab when you want

1. Expand the code. ex.  tab after “class” would triger class expansion

2. Complete code.

3. Tab

C-c d Display doc string

C-c c Run file in python

C-h m Show more key binding

17 Responses to “Setup Perfect Python Environment In Emacs”

  1. Thanks for posting this. It took me forever, but I finally got it setup. Here are some tips:

    1. Rob C’s reply to comment #4 was required.

    2. (smart-operator-mode-on) needed this file:
    http://xwl.appspot.com/ref/smart-operator.el
    and then (require ’smart-operator) near the top in .emacs

  2. michellejw said

    Thanks – I used the heck out of this tutorial. It was very helpful!

  3. [...] font.  Now to make it do Python stuff.  I’m following a tutorial that can be found here.  I’m starting off by downloading several packages: python-mode.el , pymacs0.24 , [...]

  4. [...] 在Linux论坛上总有人问Python用什么IDE比较好,然后总会有人回答说Emacs。最近开始学Python,也花了点时间研究怎么配置Emacs,发现没有想象中的那么麻烦。这篇文章大致上来自于Lei Chen博客文章的翻译,完成以后的Emacs具有以下特性: [...]

  5. Rutku said

    Hi, thank you for article,
    I don’t work Tab . This output :
    Symbol’s value as variable is void: ac-source-yasnippet

  6. Joey Liu said

    it works for me, but only one question

    (if (eql (ac-start) 0)
    (indent-for-tab-command))

    it seems that ac-start will never equal to 0, so indent-for-tab-command will never run.

    i’m using auto-complete.el 0.2.0

  7. Walt said

    This might be a stupid question, but I don´t know elisp:
    On line 41, where it says “Source for Rope”, are we supposed to fill in the path to Rope, or is it just a comment? Seems to be working quite well for me right now at least. Thansk for a good post.

  8. catonano said

    Sorry ro bother: it worked

    I just mis-copied the snippet, look:

    (require ‘auto-complete)
    (global-auto-complete-mode t)

    ;;(require ‘auto-complete)
    ;;(global-auto-complete-mode t)

    ‘ and ‘ are different !

    Bye
    Cato

  9. catonano said

    Hi,

    I’m a total Emacs newbie, I’m on Ubuntu 8.10.

    I copied

    (require ‘auto-complete)
    (global-auto-complete-mode t)

    in my .emacs file and got a message on the *Messages* buffer:

    An error has occurred while loading `/home/catonano/.emacs’:

    Symbol’s value as variable is void: ‘auto-complete

    Thanks

  10. ap said

    A comment from http://www.enigmacurry.com/2009/01/21/autocompleteel-python-code-completion-in-emacs/ says that setting robe project root folder might be the problem.what does robe root folder exactly mean.Any advice on that. Also how do i set emacs to point to my python path. i am a newbie with emacs

    • hide1713 said

      I am not sure about the problem. I didn’t set the rope project root folder variable because I have projects in different location. Emacs will ask you for root folder name the first time when you try to complete a name.

      how do i set emacs to point to my python path.

      I don’t see any reason for doing that.

  11. ap said

    everything is working but when i do something like import os.path the screen freezes for long period.any suggestion

    • hide1713 said

      I am not sure what is happening on your machine. You need provide me more information. Maybe you should try compile those .el file to byte code.

  12. kakarotoBR said

    Hello, i’m using emacs-snapshot on ubuntu 8.10 and everything is working except C-c C-c Ret gives the following error:
    Symbol’s function definition is void: smart-operator-mode-on
    But smart-operator.el is in my load path and (require ’smart-operator) in my .emacs. Any help would be much appreciated

    • hide1713 said

      Your emacs can not find smart-operator-mode-on because this function is not exists. I didn’t find smart-operator-mode-on function in my smart-operator.el. You can toggle the smart-operator by calling smart-operator-mode function.

Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <pre> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>