配置Emacs下的Python开发环境

特性

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

  • 自动完成同一个文件内的变量、函数
  • 自动完成python库中的名称
  • 代码重构
  • 模板展开功能
  • 在线帮助系统
  • 即时语法检测

其他特性还包括自动缩进,括号匹配,语法高亮,代码折叠等等。其中最有用的莫过于自动完成了,貌似很少有python编辑器可以做到这一点。而即时语法检测让emacs下的python代码书写变得像Eclipse一样,一旦有错误立刻就会高亮标记出来。

如何安装

首先你得在home目录下有一个.emacs配置文件,并且有一个用来放插件的文件夹(比如说~/.emacs.d/)

  1. 下载auto-completion.el到.emacs.d,并且在.emacs中添加如下几行: 
    (require ‘auto-complete)
    (global-auto-complete-mode t)
  2. 下载yasnippet到.emacs.d并且编辑.emacs:
    (require ‘yasnippet) (yas/initialize) (yas/load-directory “~/.emacs.d/snippets”)
  3. 下载python-mode.el并且放到.emacs.d中。我们会在之后的配置中用到它
  4. 设置Rope, Ropemacs

    我们需要使用最新的development版的rope和ropemacs,否则在emacs中不能找到rope-completion函数。通过如下步骤安装:

    sudo apt-get install mercurial python-setuptools
    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. 到 http://pymacs.progiciels-bpi.ca/archives/ 下载 pymacs并安装
    mkdir -p ~/.emacs.d/vendor && cd ~/.emacs.d/vendor tar zxvf pinard-Pymacs-v0.25-0-g5989046.tar.gz 
    sudo easy_install . 
    
  6. 添加.emacs Pymacs的路径                                                                                                                                                                               (add-to-list 'load-path "~/.emacs.d/vendor")
    (progn (cd "~/.emacs.d/vendor")
    (normal-top-level-add-subdirs-to-load-path))
  7. 安装pyflacks以进行自动语法检查:
    sudo apt-get install pyflakes
  8. 把所有东西放到一块儿

    在你的.emacs.d中创建一个init_python.el,并且加入以下内容:

    (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)
  9. 在你的.emacs文件中添加:(load-library “init_python”)

使用说明

  1. 代码自动展开。比如说在编辑C/C++头文件的时候键入once然后按tab,则会自动展开#ifndef__FILE_H__这样的宏。这个功能是YASnippet提供的,在emacs的菜单中可以看到它的所有宏。展开以后再按tab键可以在已展开的代码之间切换位置。
  2. 自动完成代码。函数名输入到一半按tab键会调用Rope和Ropemacs的功能自动完成库文件中的函数、变量名
  3. C-c d 显示python的doc string
  4. C-c C-c 运行当前的文件
  5. C-c ! 打开python shell

事实上init_python.el做的事情是通过使用auto_complete.el中的功能,把YASnippet和Rope的功能结合到了一块儿,实现了类似TexMate的自动完成等功能。其中YASnippet可以自定义模板,很是实用。Rope的功能还在研究中。



你可能感兴趣的:(配置Emacs下的Python开发环境)