1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
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
|