Setting up VIM for Erlang TDD

时间:2021-08-27 23:32:03

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的编程环境。收获颇丰