Vimを最強のPython IDEにする

Posted at 12月 7, 2011
2 comments are posted to this article

Tags

Vimは最強のエディタですがカスタマイズを行わないとプログラミングを行うという目的においては屑です。

今回はそんなVimを最強のPython IDEにするためにカスタマイズを行いたいと思います。Pythonに特化してるわけじゃない部分も 多々含まれますがご了承ください。

http://hashnote.net/storage/10/preview/

ちなみに全部設定するとこんな感じのIDEになります。

前提条件

前提とするVimの設定

いろいろな設定の説明を行う前に以下の設定がされていることを確認してください。

  1. filetype plugin indent on になっている

    Note

    下記 vundle はこの設定がONになっていると動きません。したがって vundle の設定が終わったあとに 明示的にこの設定をONにする必要があります

  2. vundle が正しく動作するよう設定されている

vundle に関しては Vim-users.jp - Hack #215: Vundle で plugin をモダンに管理する が詳しいのでそちらを参照して 有効にしてください。今後 vundle がインストール済みのことを前提として各種Vimプラグインの設定を行っていきます [1]

[1]pathogen を使用している場合や自分でプラグインの管理ができる方は自分の環境に読み替えて進めてくれても結構です

pythonbrewによるフレキシブルなPython環境の構築

Vimの設定とかはあまり関係ないですが最強を詠うために最強のPython環境が必要なので構築します。最強の環境とは

  1. インストールされているPythonのバージョンが違うことによって不可解なバグが発生しない
  2. インストールされているライブラリのバージョンが違うことに不可(ry
  3. インストールされているライブラリ同士が干渉して不可解な(ry

だと思っています。これらを解決するために pythonbrew という素晴らしいソフトを利用します。 ただこのソフトはシェルが前提となっているのでWindowsをお使いの方は代わりに virtualenv をインストールして先に進んでください。

Pythonには大きく分けて2.x系と3.x系の大きなバージョンがあり、この二つは相容れないものとなっています。 2.x系はずっと使われてきたもので外部ライブラリなどが豊富で現時点での最も有力な選択肢となっています。しかし3.xを まったく使わないわけではないのでそれらを簡単に切り替えることができる pythonbrew というツールを使います。

Note

Mac OS Xに標準でインストールされているPythonは俗にNarrow Pythonと呼ばれる不完全なものなので 絶対に2.x系しか使わないよという方も pythonbrew を用いてインストールし直すことをおすすめします。

なお pythonbrew はシステムのPythonを上書きするものではないためインストール後も問題なく既存ソフトウェア は動作します。

pythonbrew のインストールには curl などのコマンドが必須とされているので wget を利用する Ubuntu などのOS ではまず下記のコマンドによって必要なライブラリをインストールしてください:

$ sudo apt-get install curl python-all-dev python3-all-dev
$ sudo apt-get install libreadline6-dev libsqlite3-dev libgdbm-dev
$ sudo apt-get install libbz2-dev build-essential libxml2-dev libxslt1-dev

つぎに curl を用いて pythonbrew をインストールします。下記コマンドをターミナルで実行してください:

$ curl -kL http://xrl.us/pythonbrewinstall | bash

最後に pythonbrew を使用するために .bashrc.profile などのrcファイルに以下を記述してください:

# pythonbrew
if [ -s "$HOME/.pythonbrew/etc/bashrc" ]; then
    source "$HOME/.pythonbrew/etc/bashrc"
    # exec command like virtualenvwrapper
    alias mkvirtualenv="pythonbrew venv create"
    alias rmvirtualenv="pythonbrew venv delete"
    alias workon="pythonbrew venv use"
fi

if文の中で virtualenvwrapper 的に pythonbrew の仮想環境を 使用するためのエイリアスを張っています。以後仮想環境構築はこの書式に従います。

次に pythonbrew を用いてPythonの新規インストールを行いますが、この段階では pythonbrew コマンドは読み込まれていないと思います。 したがってまず下記コマンドにて pythonbrew のrcファイルを読み込んでください:

$ source "$HOME/.pythonbrew/etc/bashrc"

では早速Pythonのインストールを行いましょう。インストールするPythonのバージョンは執筆時点で最新の 2.7.2 です。ここは各自読み替えてください:

$ pythonbrew install --no-test --verbose --configure="--enable-unicode=ucs4" 2.7.2
$ pythonbrew switch 2.7.2

オプションとして --enable-unicode=ucs4 を与えています。これを与えることによってNarrow Pythonではなく完全なPythonをインストールすることができます。

最後に pythonbrew で仮想環境を利用するための準備を行います。以下コマンドを実行してpythonbrewに virtualenv パッケージをインストールしてください:

$ pythonbrew venv init

これで仮想環境の使用準備が整いました。以後なにかプロジェクトを開始する場合は以下のようにして仮想環境を作ってから行うことをおすすめします:

$ mkvirtualenv HelloWorld
$ workon HelloWorld
(HelloWorld)$ # 仮想環境に入っていることは左の()でわかる

Vim全般的な設定

The-NERD-Treeによるプロジェクト管理

Vimでプロジェクトを管理する方法として project という老舗のプラグインが ありますが、面倒くさくて僕は使ってません。興味がある場合は Project.vim - Vimでのプログラミングを猛烈に支援してくれるプラグイン というのが詳しいのでそちらをご覧ください。

さてVimのデフォルトのファイル管理は非常に面倒なので The NERD tree というプラグインを使います。これはもう見たほうが早いです。

http://hashnote.net/storage/7/preview/

左側のペインが The NERD tree。jkで移動できEnterでファイルが開きます。不可視ファイルの表示などにも対応しておりVimを使用する場合は必須のプラグインです。

これだけでも十分なのですがキーマップを設定すると一発でこのツリーが開いたり閉じたりするようになるので便利です。僕は以下のように設定しています:

nmap <Leader>n :NERDTreeToggle<CR>

The NERD treeの使い方はThe NERD treeのペインで?を押すと簡易ヘルプが表示されるのでそれで学んでください。僕の使い方としては

  1. zshでプロジェクトルートまで移動
  2. gvimをそこで起動
  3. The NERD treeにて編集したいファイルを開く
  4. The NERD tree上にて cd コマンドや C コマンドでプロジェクト間を移動

となってます、この辺は各自で好きに使ってください。

存在しないフォルダの自動作成

Vimでは新しいファイルを作成する場合に :o src/newfile などとすることが多いと思いますが、保存先のパスが 存在しない場合は一度ターミナルに戻って作成するなどをしないといけません。これは非常に面倒くさいので以下の設定を .vimrc に書き込み存在しないフォルダを自動的に作成するようにします:

" create directory automatically
augroup vimrc-auto-mkdir
    autocmd!
    autocmd BufWritePre * call s:auto_mkdir(expand('<afile>:p:h'), v:cmdbang)
    function! s:auto_mkdir(dir, force)
        if !isdirectory(a:dir) && (a:force ||
            \ input(printf('"%s" does not exist. Create? [y/N]', a:dir)) =~? '^y\%[es]$')
            call mkdir(iconv(a:dir, &encoding, &termencoding), 'p')
        endif
    endfunction
augroup END

これで保存時にそのパスが存在しないとフォルダを作成するかどうか聞かれ Y と答えると自動的に作成するようになります。

Pythonに特化したVimの設定

PEP8に準じたインデントルールの作成

PEP8についてはPythonプログラマならもちろんご存知かとは思いますが、PEP8はPythonを用いてコーディングを行う際の スタイル指標のことです。詳しい話は PEP 8 -- Style Guid for Python に書いてあるため読んだことない人は一読することをおすすめします。

先の「前提とするVimの設定」で filetype plugin indent on になっているため以下のファイルにPython専用の 設定を書きこんでいきます。なお設定ファイルパスなどに用いる VIM はVimの設定フォルダを示しています [2]

VIM/ftplugin/python.vim:

" PEP 8 Indent rule
setl tabstop=8
setl softtabstop=4
setl shiftwidth=4
setl smarttab
setl expandtab
setl autoindent
setl nosmartindent
setl cindent
setl textwidth=80
setl colorcolumn=80

" Folding
setl foldmethod=indent
setl foldlevel=99

とりあえず今のところはこれだけです。この後各プラグインに応じていくつかの設定を追加していきます。

[2]Unix系では $HOME/.vim がデフォルトです。Windowsはよくわかりませんがホームディレクトリにある vimfiles だそうです。

Vimで正しくPythonの仮想環境を扱う

Note

プラグイン化したので以下の vundle 設定を追加してください:

Bundle 'lambdalisue/vim-python-virtualenv'

ステータスラインは各自で追加するなりしてください

先に仮想環境を構築したと思いますが、そのままではVim上で正しく仮想環境が利用できません。これはVimが使用しようとするPythonが システムデフォルトの物だからです。したがって以下コードにより仮想環境をVim内でアクティベートしてやる必要があります。 VIM/ftplugin/python.vim に追記してください:

let g:pythonworkon = "System"
py << EOF
import sys, os.path
import vim
if 'VIRTUAL_ENV' in os.environ:
    project_base_dir = os.environ['VIRTUAL_ENV']
    sys.path.insert(0, project_base_dir)
    activate_this = os.path.join(project_base_dir, 'bin/activate_this.py')
    execfile(activate_this, dict(__file__=activate_this))
    # Save virtual environment name to VIM variable
    vim.command("let g:pythonworkon = '%s'" % os.path.basename(project_base_dir))
EOF

" Apply g:pythonworkon to statusline
let &statusline='%F%m%r%h%w [FORMAT=%{&ff}] [ENC=%{&fileencoding}] [TYPE=%Y] [ASCII=\%03.3b] [HEX=\%02.2B] [POS=%04l,%04v][%p%%] [LEN=%L] %= [WORKON=%{pythonworkon}]'

一番最後の行で現在居る仮想環境名をステータスラインに追加しています。ステータスラインのフォーマットなどは各自で変えてください

http://hashnote.net/storage/5/preview/

ステータスラインに現在の仮想環境名が表示されている

pyflakesによる構文の自動チェック

pyflakes というPythonの構文をチェックしてくれるソフトがあります。これをVim上から利用すると自動的に構文が間違っている部分が 下記図のように表示され非常に分かりやすいです。

http://hashnote.net/storage/6/preview/

ifの後ろに:が付いていないため構文エラーになっています。デフォルトでは赤背景になり見にくいので Gvimで波線表示にするために別途スタイルを記述してあります。

pyflakes はパッケージとしてPyPIに上がっているのですが、今回使用する pyflakes-pathogen は独自に持っているためインストールは不要です。 したがって以下の vundle 設定を必要な場所(多くの場合 .vimrc ファイル)に追記してください:

Bundle 'mitechie/pyflakes-pathogen'

これでVim上で BundleInstall コマンドを実行すると自動的にこのプラグインがインストールされます(以後 vundle の設定を更新した際は毎度インストールコマンドを走らせていると仮定します)。インストール後はインサートモードを 抜けたり文字を削除したときに自動的に pyflakes が走るようになるため特に意識する必要はありません。なお pyflakes-pathogen はデフォルトで QuickFixを利用するのですがこれが邪魔な場合は以下の設定を VIM/ftplugin/python.vim に追加すればいいです:

let pyflakes_use_quickfix = 0

Note

似たパッケージに pyflakes-vim という物があるのですが、これは pyflakes をサブモジュールとして持っているため pathogen や vundle などでの 利用には不向きなことに注意してください

vim-makegreenによるTDD開発

Test Driven Developmentを行うためには簡単にテストを実行できるかが鍵となります。いちいちターミナルに戻ってテストを行うなんて正直なところ面倒です。 これを解決するために vim-makegreen というプラグインを利用します。実行結果は以下のようになります

http://hashnote.net/storage/8/preview/

テストが成功した場合は緑のラインで教えてくれる(表示している画像はPythonではなくCoffeeScriptのものです)

http://hashnote.net/storage/9/preview/

テストが失敗した場合は赤のラインと一番上のエラーを教えてくれる。またQuickfixには失敗した部分がすべて乗っている

さて、このテストなんですが実際には nose を用いてテストを実行しています。また テスト結果の解析に --machine-out という追加オプションを使っているため nose-machineout プラグインも必要になります。これらは下記コマンドでインストールができます:

$ pythonbrew off    # システムのPythonにインストールする
$ sudo pip install nose
$ sudo pip install git+git://github.com/lambdalisue/nose-machineout.git#egg=nose_machineout

Note

ちなみに本家の nose-machineout では --with-doctest の結果をパースできないためフォークしたバージョンを使います

これでPython側の設定が終わったので次はVim側の設定を行います。以下の vundle 設定を必要な場所に追記してください(インストールも):

Bundle 'reinh/vim-makegreen'
Bundle 'lambdalisue/nose.vim'

次に VIM/ftplugin/python.vim でコンパイラの設定を行います。 vim-makegreen はその名のとおりテストにVim標準の make コマンドを 使用するためテスト起動用コンパイラを各ファイルに設定してやる必要があります [3]

compiler nose

これですべての設定が終わったのでユニットテストが書いてあるPythonファイルにて <Leader>t でユニットテストが走るはずです。うまくいかない場合は :make を実行してやると全文が表示されるのでデバッグに役立ちます。

[3]ここで言えば nose.vim がテスト起動用コンパイラになります。他にも Node.js のユニットテスト用に nodeunit.vim というものも作ったので興味のある人はそちらを参照してください

ropevimによるリファクタリング

多くのIDEにあって今までのVimになかったのがこのリファクタリング機能。しかし ropevim を使うとIDEもびっくりのリファクタリング環境が できてしまいます。ちなみにこの ropevim を使うと

  • 名前の変更
  • メソッド・ローカル変数の展開
  • クラス・関数・モジュール・パッケージ・メソッドの移動
  • ...

全部書こうかと思ったのですが面倒なので rope を参照してください。非常に強力です。正直なところ僕も使いこなせてはいません。

ropevimrope と ropemode というパッケージに依存しているためこれらをインストールする必要があります。いつも通りシステムのPythonに インストールしてください:

$ pythonbrew off
$ sudo pip install rope ropemode

次にVimに ropevim をインストールします。以下の vundle 設定を追記してください:

Bundle 'sontek/rope-vim'

これで準備が整いました。実際の使い方としては変数名の変更を例に説明すると

  1. 変更したい変数名にカーソルを合わせる
  2. :RopeRename を実行する(もしくは C-C rr
  3. プロジェクトのルートディレクトリについて聞かれるので入力する
  4. (おそらく)Ropeのファイルが見つかりませんがつくりますか?的なことが聞かれるので Y と答える
  5. 残りは支持に従えばプロジェクト内の変数名を自動的に書き換えてくれる

ropevim にはまだまだ強力な機能が沢山あるので各自(俺も含め)調べてみましょう

pysmellによる補完機能

Note

もう遅くて遅くて嫌になったのでpythoncompleteでdjangoの補完が出来るようになるvimプラグイン作りました。

https://github.com/lambdalisue/vim-django-support

pythoncompleteのほうが速度がいいので、おすすめです。

インストールする場合は vundle 設定に以下を追加してください:

Bundle 'lambdalisue/vim-django-support`

IDEと名乗るには補完は絶対必要ですね。ここではネオコンの通称で愛されている neocomplcache を利用することを前提としています。ネオコンについては Vim-users.jp - neocomplcache に詳しく書いてあるので知らなかった方はそちらを参照してください。

VimにおけるPythonの補完は pythoncomplete という老舗がありますが外部ライブラリの補完には弱いようで Djangoをうまく補完してくれません。僕はDjangoの開発がほとんどなので代わりに pysmell を利用しています。

Note

pythoncompleteでDjangoの補完がうまくいかない原因はDjangoのライブラリが DJANGO_SETTINGS_MODULE という環境変数を必要としているからです。なので以下のようにして起動すれば補完が効くようになります:

DJANGO_SETTINGS_MODULE=myapp.settings vim

でも毎度これをするのが面倒なので僕は pysmell による補完をおすすめしています。昔のバージョンでは pysmell も DJANGO_SETTINGS_MODULE の設定をしてからではないと django のタグファイルが作れなか ったのですが、今日確認したところそんな事しなくても作ってくれるみたいです。

追記:

上にも書きましたが今は pythoncompleteとvim-django-supportを使った方法をおすすめします pysmell重すぎる

さっそくですがインストールに入ります。pysmellはパッケージとして用意されているので以下コマンドでシステムPythonにインストールしてください:

$ pythonbrew off
$ sudo pip install pysmell

次にVim用のファイルをインストールします。vundleなどが使えると良かったのですが、使えないタイプなので VIM/plugin/https://raw.github.com/orestis/pysmell/master/pysmell.vim を直接突っ込んでください。その後以下の設定を VIM/ftplugin/python.vim に追記してください:

setl completeopt=menuone,preview,longest
setl omnifunc=pysmell#Complete

さて、これで使用準備は整ったのですが、まだ補完をしてくれません。pysmellはpythoncompleteと違い補完用のタグファイルという物を使って補完します。 したがってこの補完用のタグファイルというものをまず作成してやらねばなりません。このタグファイルは同じバージョンのライブラリならば使いまわせるので Dropboxなどに入れて共有しておくと便利です。

ではまず標準ライブラリの補完ファイルを作成します、例中の PYTHON はPythonのインストール先を表しています。pythonbrewを使用しているならば $HOME/.pythonbrew/pythons/Python-2.7.2/ になります:

$ pysmell PYTHON/lib -x site-packages test tests -o ~/PYSMELLTAGS.stdlib

標準ライブラリの補完ファイルの作成が終わったので次は django の補完ファイルを作成します。予め django をインストールしておいてください。 なお特定の仮想環境を作り、そこにインストールした場合は PYTHON$HOME/.pythonbrew/venvs/Python-2.7.2/<Name>/ になります:

$ pysmell PYTHON/lib/site-packages/django -o ~/PYSMELLTAGS.django

Note

もしかしたら django ディレクトリは Django-1.2.3.egg のようなフォルダ内にあるかもしれません

最後に現在のプロジェクトの補完ファイルを作成します。 プロジェクトルート にて以下コマンドで作成した標準ライブラリ・Djangoの補完タグファイル のコピーと現在のプロジェクトの補完タグファイル作成を行ってください:

$ cp ~/PYSMELLTAGS.stdlib ./
$ cp ~/PYSMELLTAGS.django ./
$ pysmell .

これで補完が効くようになりました。プロジェクトが進み新しい関数やファイルが追加されたら pysmell . コマンドを再度実行して PYSMELLTAGS ファイルを更新してください



hoge

画像のリンク切れ直るとうれしいです!

lambdalisue

直しました!読んでいただけて光栄です