From 97a0dc4ef9192d2e833e24e19f780a80bee273a3 Mon Sep 17 00:00:00 2001 From: Thibaut Horel Date: Mon, 15 Apr 2013 18:14:39 +0200 Subject: Add python-ide article --- content/python-ide.rst | 292 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 292 insertions(+) create mode 100644 content/python-ide.rst (limited to 'content') 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 ```` key to the ``NERDTreeToogle`` function to +quickly toggle the drawer on and off: + +.. _NERDTree: https://github.com/scrooloose/nerdtree + +.. code-block:: vim + + nnoremap :NERDTreeToggle + +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 +```` 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 ```` to open +it. + +.. _Ctrlp: https://github.com/kien/ctrlp.vim + +In addition to the default ```` 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 ````: + +.. code-block:: vim + + nnoremap :CtrlPBuffer + +| + +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 + ```` key to the ``TagbarToggle`` command to toggle the drawer: + + .. code-block:: vim + + nnoremap :RainbowParenthesesToggleAll + + 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 ```` tag and realize that you + want to turn it into a ``
`` 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 ```` key to toggle the rainbow colors + on and off: + + .. code-block:: vim + + nnoremap :RainbowParenthesesToggleAll + +.. _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 za + nnoremap zA + vnoremap 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 ``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 ```` + 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 za + nnoremap zA + vnoremap zA + + nnoremap :NERDTreeToggle + nnoremap :CtrlPBuffer + nnoremap :RainbowParenthesesToggleAll + nnoremap :RainbowParenthesesToggleAll + + let g:pymode_lint_write = 0 -- cgit v1.2.3-70-g09d2