summaryrefslogtreecommitdiffstats
path: root/content/python-ide.rst
diff options
context:
space:
mode:
Diffstat (limited to 'content/python-ide.rst')
-rw-r--r--content/python-ide.rst292
1 files changed, 292 insertions, 0 deletions
diff --git a/content/python-ide.rst b/content/python-ide.rst
new file mode 100644
index 0000000..b69544c
--- /dev/null
+++ b/content/python-ide.rst
@@ -0,0 +1,292 @@
+Using Vim as a Python IDE
+=========================
+
+:date: 2013-04-15T17:53:00
+
+About one year ago, I have switched to using Vim as my main text and code
+editor. Before that, I was using Emacs, but never really mastered it to the
+point where I could consider myself proficient. After having heard a lot about
+the *steep learning curve* of Vim, I was surprised to find myself picking it up
+rather quickly: I like the fact that shortcuts are structured similarly to
+natural languages: people often mention how combining action and motion
+instructions in Vim is similar to constructing a sentence in a natural
+language.
+
+Vim really shines when it comes to quickly editing a few files from the command
+line, but even though I am not a heavy coder, I found the default configuration
+a bit insufficient for bigger projects involving editing multiple related
+files. Here is how I gradually tweaked my Vim configuration to copy some
+behaviors commonly found in IDEs. While some of these tweaks are general and
+can be applied to any language, others are specific to Python, the language
+I use most of the time.
+
+This article assumes that you already have a basic knowledge of Vim and its
+configuration. If you do not want to read my comments and stick to the bare
+configuration steps, you can go straight to the Conclusion_.
+
+Forewords
+---------
+
+First and foremost, you should make sure that you have Pathogen_ installed. This
+amazing script allows you to handle your Vim plugins separately: each plugin
+becomes a subdirectory of the ``.vim/bundle`` folder (this can be changed to
+somewhere else) in which you put all the plugin files instead of spreading them
+over the default directory structure. Most of the plugins I will recommend here
+are available on GitHub, so cloning their repositories inside your
+``.vim/bundle`` folder is all you need to install them.
+
+.. _Pathogen: https://github.com/tpope/vim-pathogen
+
+This is particularly useful if you use Git to handle your Vim configuration
+(and more generally your dotfiles), because you can treat each Vim plugin as
+a submodule of your main repository, allowing for easy updates.
+
+Installing_ Pathogen is as easy running:
+
+.. code-block:: bash
+
+ mkdir -p ~/.vim/bundle ~/.vim/autoload
+ curl -Sso ~/.vim/autoload/pathogen.vim \
+ https://raw.github.com/tpope/vim-pathogen/master/autoload/pathogen.vim
+
+.. _Installing: https://github.com/tpope/vim-pathogen#installation
+
+and adding the following line at the top of your ``.vimrc``:
+
+.. code-block:: vimrc
+
+ execute pathogen#infect()
+
+Also, as a general recommendation, make sure that you have a color theme that
+match your tastes. Because I find dark themes more easy on the eyes, I went for
+Molokai_. Solarized_ is a common choice among light themes lovers.
+
+.. _Molokai: https://github.com/tomasr/molokai
+.. _Solarized: https://github.com/altercation/vim-colors-solarized
+
+File and project management
+---------------------------
+
+When working on a project involving more than one file, being able to quickly
+navigate through its files is key. NERDTree_ is a nice plugin which replaces
+the default Vim file browser and adds a file-tree drawer on the left of Vim's
+interface. I bind the ``<F1>`` key to the ``NERDTreeToogle`` function to
+quickly toggle the drawer on and off:
+
+.. _NERDTree: https://github.com/scrooloose/nerdtree
+
+.. code-block:: vim
+
+ nnoremap <F1> :NERDTreeToggle<cr>
+
+I find the NERDTree plugin very useful when discovering a project, to quickly
+grasp how the files are organized. However, to quickly open new files and
+switch to open buffers, there is a much more powerful solution, I name the
+CtrlP_ plugin. This plugin adds commands to search through files, buffers,
+tags, etc. in a fuzzy way. Let's say you want to open a file, pressing
+``<Ctrl-p>`` followed by a few letters of this file's path (they don't need to
+be contiguous) will give you a list of all the files matching these letters.
+The list gets further filtered as you keep typing. When the file you are
+looking for reaches the bottom of the list, you simply press ``<Enter>`` to open
+it.
+
+.. _Ctrlp: https://github.com/kien/ctrlp.vim
+
+In addition to the default ``<Ctrl-p>`` shortcut to open new files, I like to
+have a shortcut to launch the buffer finding command to search through open
+buffers. Here I bind it to ``<Ctrl-b>``:
+
+.. code-block:: vim
+
+ nnoremap <c-b> :CtrlPBuffer<cr>
+
+|
+
+Vim has a very nice built-in `session feature`_: you can save the current state
+of your Vim instance (open buffers, windows layout, cursor positions, paste
+registers, jumps, macros, etc.) in a session file. The sessionman_ plugin is
+a simple wrapper around this feature, and takes care of storing all your
+session files in the same directory. This is achieved by using the
+``SessionSave`` command which asks you for a simple name to identify the
+session. Call the ``SessionOpen`` command with the same name to re-open the
+session. Also, if you are working inside a previously saved session, the plugin
+automatically saves the current state in the same session file when quitting
+Vim.
+
+.. _session feature: http://vimdoc.sourceforge.net/htmldoc/usr_21.html#21.4
+.. _sessionman: https://github.com/vim-scripts/sessionman.vim
+
+Finally, I would also recommend reading the `buffers and windows sections`_ of
+Vim's help. Having a good understanding of buffers and windows, splits, etc.
+can help you being more productive when working on multiple files.
+
+.. _buffers and windows sections: http://vimdoc.sourceforge.net/htmldoc/windows.html#buffers
+
+Code writing
+------------
+
+There are many plugins to help you writing code more efficiently. Here are some
+that I find particularly helpful.
+
+* TagBar_: to display a list of the current file's tags (when programming,
+ these are the functions, classes, global variables defined in the file) in
+ a drawer on the right of Vim's interface. This allows you to have a clear
+ view of the file content and to quickly jump to another location. I bind the
+ ``<F2>`` key to the ``TagbarToggle`` command to toggle the drawer:
+
+ .. code-block:: vim
+
+ nnoremap <F3> :RainbowParenthesesToggleAll<cr>
+
+ note that this plugin requires that you have a ``ctags`` implementation
+ installed on your computer.
+
+* Surround_: gives you new motion commands to manipulate surrounding
+ parentheses, brackets and html tags. For example, let's say you are currently
+ editing some HTML code, you are inside a ``<span>`` tag and realize that you
+ want to turn it into a ``<div>`` tag. With this plugin this can be achieved
+ by typing ``csttdiv``, where ``cst`` means *change surrounding tag*, the
+ second ``t`` means *replace it with another tag*, and ``div`` is simple the
+ name of the replacing tag.
+
+* RainbowParentheses_: to color parentheses, brackets, etc. according to their
+ nesting level. This is quite helpful to quickly check the well-balancedness
+ of a complex expression. I bind the ``<F3>`` key to toggle the rainbow colors
+ on and off:
+
+ .. code-block:: vim
+
+ nnoremap <F3> :RainbowParenthesesToggleAll<cr>
+
+.. _RainbowParentheses: https://github.com/kien/rainbow_parentheses.vim
+.. _Surround: https://github.com/tpope/vim-surround
+.. _TagBar: https://github.com/majutsushi/tagbar
+
+Other plugins worth mentioning: NERDCommenter_, Easymotion_.
+
+.. _NERDCommenter: https://github.com/scrooloose/nerdcommenter
+.. _Easymotion: https://github.com/Lokaltog/vim-easymotion
+
+Python specific configuration
+-----------------------------
+
+Python being a very popular language, there is a large ecosystem of tools to
+help Python developers checking, formatting, refactoring and doing static
+analysis of their code. If you do not want to spend too much time understanding
+and installing all these tools, a coherent sample of them has been bundled into
+the python-mode_ plugin.
+
+.. _python-mode: https://github.com/klen/python-mode
+
+I find the default configuration very reasonable. Here is a selected list of
+the features you will get by installing this plugin:
+
+* python-aware motions: ``M`` for the current method, ``C`` for the current
+ class. For example, ``daM`` will delete the current method.
+
+* python-aware code folding. I don't like to have all my code folded when
+ I open a file so I set the ``foldlevelstart`` to 99. I also set simpler
+ shortcuts to toggle code-folding. Here is the related section of my
+ ``.vimrc``:
+
+ .. code-block:: vim
+
+ set foldlevelstart=99
+ nnoremap <Space> za
+ nnoremap <S-Space> zA
+ vnoremap <S-Space> zA
+
+* code completion/analysis/refactoring with Rope. The most useful shortcuts are
+ described here_. See ``:help ropevim.txt`` for more advanced commands.
+
+* pylint_ checking of your code. By default, pylint is run on your files
+ every time you save them. I find this quite cumbersome so I disabled it with:
+
+ .. code-block:: vim
+
+ let g:pymode_lint_write = 0
+
+ and prefer to run it manually with the ``PyLint`` command.
+
+Also, note that Python being a dynamic and weakly-typed language, it is hard to
+get good auto-completion. I have read some good things about jedi-vim_
+auto-completion. If you want to try it out, you simply need to install this
+plugin after disabling rope's auto-completion:
+
+.. code-block:: vim
+
+ let g:pymode_rope_vim_completion = 0
+
+.. _jedi-vim: https://github.com/davidhalter/jedi-vim
+.. _pylint: http://www.logilab.org/857
+.. _here: https://github.com/klen/python-mode#id21
+
+|
+
+A nice thing about Python being an interpreted language is that it allows you
+to quickly test a snippet, update the definition of a function into an already
+loaded environment, etc. The python-mode plugin gives you the ``<Leader>r``
+shortcut to run the current file through Python, but if you want something more
+fine-grained, I recommend the vim-ipython_ plugin. This plugin is still very
+rudimentary, but it already gives you the ability to send Python code to
+a running IPython kernel. Here is how I use it:
+
+* launch a terminal window and put it side-to-side with my Vim window
+
+* launch an IPython console in the terminal window with the ``ipython console``
+ command (this will also launch an IPython kernel)
+
+* run the ``:IPython`` command inside my Vim window to connect to the running
+ IPython kernel
+
+* whenever I want to send some code (e.g. a function) and make it available to
+ the IPython instance, I select it (e.g with ``vaM``) and use the ``<Ctrl-s>``
+ shortcut.
+
+One thing which is crucially missing is getting feedback from IPython back to
+Vim: for example, displaying error messages if the sent code is faulty or
+displaying python's output on the code execution.
+
+.. _vim-ipython: https://github.com/ivanov/vim-ipython
+
+Conclusion
+----------
+
+Here are the commands to install all the plugins mentioned in this article:
+
+.. code-block:: bash
+
+ # if using Pathogen, run these commands in ~/.vim/bundle
+
+ git clone https://github.com/scrooloose/nerdtree.git
+ git clone https://github.com/klen/python-mode.git
+ git clone https://github.com/kien/ctrlp.vim.git
+ git clone https://github.com/kien/rainbow_parentheses.vim.git
+ git clone https://github.com/majutsushi/tagbar.git
+ git clone https://github.com/vim-scripts/sessionman.vim.git
+ git clone https://github.com/tpope/vim-surround.git
+ git clone https://github.com/ivanov/vim-ipython.git
+ git clone https://github.com/tomasr/molokai.git
+
+And the options to put in your ``.vimrc``:
+
+.. code-block:: vim
+
+ execute pathogen#infect()
+ filetype plugin indent on
+ syntax on
+
+ " you probably want more options here, see for example this excellent article
+ " http://stevelosh.com/blog/2010/09/coming-home-to-vim/
+
+ set foldlevelstart=99
+ nnoremap <Space> za
+ nnoremap <S-Space> zA
+ vnoremap <S-Space> zA
+
+ nnoremap <F1> :NERDTreeToggle<cr>
+ nnoremap <c-b> :CtrlPBuffer<cr>
+ nnoremap <F3> :RainbowParenthesesToggleAll<cr>
+ nnoremap <F3> :RainbowParenthesesToggleAll<cr>
+
+ let g:pymode_lint_write = 0