While emacs might be the preferred editor for erlang code, I'm avim junkie to the core and couldn't imagine changing my editor for a single language. If you're using vim to develop for erlang as well then these steps will help you smoothen the process of using vim for test driven development with erlang. In case you need anything from my vim configuration I hostmy personal vim setup on github so I can access it everywhere, and I encourage you to do the same!
I'm going to assume you already have your own vim setup, including a way to manage plugins such aspathogen and preferably a version controlled .vim directory so that you can use git submodules along with pathogen. If for some reason you don't then I recommend setting one up before continuing, there is a great screencast onSynchronizing plugins with git submodules and pathogen over at vimcasts.org. Its less than 10 minutes long and if you're a vim user you'll be happy you did it!
This article is not an introduction to EUnit. If you require an introduction to EUnit I will refer you toEUnited Nations Council from Learn You Some Erlang andErlang Manual Chapter on EUnit. Both of those resources are free and will get you on your feet when it comes to writing unit tests for erlang. Now lets get vim setup...
The vimerl Plugin
The first thing we'll want is some erlang specific vim functionality. Thankfully there is a fantastic plugin calledvimerl that encapsulates all of the erlang functionality we need. If you've followed the vimcasts.org screencast above you can install this plugin by typing the following command when in your .vim directory:
git submodule add https://github.com/jimenezrick/vimerl.git bundle/vimerl git submodule init
This plugin enables several useful features including syntax highlighting, code folding, code completion, auto-indent, quickfix, and wrangler support.
Autocomplete
There is a gotcha with auto complete, you need to set the location of the erlang man pages in your .vimrc file. The issue is that the vimerl site lists this option as g:erlangManPath but in reality the variable has changed in vimerl to be named g:erlang_man_path. I used the command locate erlang
at the command line to determine that my man pages were located at/usr/local/share/man/man3/
turns out that the plugin looks for the man3 directory so to set your vimrc up just add this line:
let g:erlang_man_path='/usr/local/share/man'
Keep in mind that the path will be different on your machine! This is for a machine running Mac OS X Lion and I usedhomebrew to install erlang. Once you have this setup you should be able to activate library autocompletion using Ctrl+X Ctrl+O.
Code Folding
You can setup vim to toggle folds with the spacebar by adding the following two lines to your .vimrc
nnoremap @=(foldlevel('.')?'za':'l') vnoremap zf
Now just place the cursor on the body of a multi-line erlang function and hit the space bar. Vim will fold it all into one line.
Refactoring
There are a few refactoring commands that come with this package, and they really come in handy for the refactor part of red-green-refactor. They can extract a new function, rename a variable/function/module, and convert a function's arguments into a tuple. The trick to remembering the keys is that all the refactorings start with followed by a letter representing the change. See the list below:
- Extract to a new function: Highlight code and press Alt-r e
- Rename a variable: Put the cursor on it and press Alt-r v
- Rename a function: Put the cursor on it and press Alt-r f
- Rename a module: Press Alt-r m anywhere in the module
- Convert arguments to tuples: Highlight arguments and press Alt-r t
As it turns out the refactoring support was removed from the latest, and currently maintained version of vimerl. Perhaps that could be a little project for someone (maybe me?) to learn how to write vim plugins at some point and re-add refactoring support to vimerl.
EUnit Snippets
When you're doing TDD its handy to have some snippets to help you get all your boilerplate testing code into the file quickly. So with that in mind head over to thesnipMate Vim plugin page. Remember to add it properly if you're using git submodules to manage your vim plugins.
Now regardless of whether or not you installed snipMate as a submodule you will need to edit these snippets in the ~/.vim/snippets/erlang.snippets file. The neat part is that even though a bundle/snipMate/snippets/erlang.snippets file exists if you included snipMate as a submodule, it will still read snippets from all locations. This allows you to store your own changes without messing with the submodule. Let's add the following snippets for now:
# Include EUnit snippet ince -include_lib("eunit/include/eunit.hrl"). # Assert snippet ? ?assert(${1:expression}) # Assert Not snippet ?not ?assertNot(${1:expression}) # Assert Equal snippet ?equal ?assertEqual(${1:expected}, ${2:actual}) # Assert Match snippet ?match ?assertMatch(${1:pattern}, ${2:expression}) # Assert Error snippet ?error ?assertError(${1:pattern}, ${2:expression}) # Assert Generator snippet ?_ ?_assert(${1:expression}) # Assert Not Generator snippet ?_not ?_assertNot(${1:expression}) # Assert Equal Generator snippet ?_equal ?_assertEqual(${2:expected}, ${3:actual}) # Assert Match Generator snippet ?_match ?_assertMatch(${1:pattern}, ${2:expression}) # Assert Error Generator snippet ?_error ?_assertError(${1:pattern}, ${2:expression}) # Test Method Template snippet test ${1:unit}_${2:scenario}_${3:expectedResult}_test() -> ?assert${4:assertion}(${5:expected}, ${6:actual}). # Test Fixture snippet fixture {${1:setup}, ${2:Where}, ${3:Setup}, ${4:Cleanup}, ${5:Instantiator}}
Wrap Up
Thats it, we now have a vim environment that supports autocomplete, code folding and refactoring for our language of choice. On top of that we have some snippets to help us write test cases with less keystrokes. Next Sunday we'll write a test runner and test out an existing Project Euler solution. Later on we'll take a look at using TDD to solve more Project Euler problems. Until then Happy Coding.
安装了vimerl,还diy了一把vimer的源码。最后利用rebar搭建起来了TDD的编程环境。收获颇丰