Friday, September 28, 2007

Swap parameters script for Vim

I have published a script for Vim. The script is written in python. The job of the script is to swap parameters. A user can swap a parameter under the cursor with the next one (gs) or with the previous one (gS). One can also use this command preceded with count. If I wanted to swap first parameter of a function with the third, I would type 2gs.

The possibility of writing scripts for vim in python not only made it very easy for me to write that script, but also allowed for easy testing. I used py.test framework and made a suite of quite literate tests. Below is a beautified set of use/test cases generated from the tests.

Left column contains the line before typing gs, the right shows the result. Position of the cursor is depicted with green background.

fun(parm1, parm2) fun(parm2, parm1)
fun(parm1(), parm2) fun(parm2, parm1())
fun(parm1(), parm2) fun(parm2, parm1())
fun(parm1(arg,arg2), parm2) fun(parm2, parm1(arg,arg2))
fun(parm1(arg,arg2), parm2) fun(parm2, parm1(arg,arg2))
fun(parm1(arg,arg2), parm2) fun(parm2, parm1(arg,arg2))
fun(parm1(arg, arg2), parm2) fun(parm2, parm1(arg, arg2))
fun(arg1, arg2, arg3) fun(arg1, arg3, arg2)
array[arg1, arg2] array[arg2, arg1]
fun(parm1[], parm2) fun(parm2, parm1[])
fun(parm1[], parm2) fun(parm2, parm1[])
fun(parm1, array[]) fun(array[], parm1)
fun(a,b) fun(b,a)
[(p1, p2), p3] [p3, (p1, p2)]

Test cases for gS -- swap backwards.

fun(parm2, parm1) fun(parm1, parm2)
fun(parm2, parm1()) fun(parm1(), parm2)
fun(parm2, parm1()) fun(parm1(), parm2)
fun(parm2, parm1(arg,arg2)) fun(parm1(arg,arg2), parm2)
fun(parm2, parm1(arg,arg2)) fun(parm1(arg,arg2), parm2)
fun(parm2, parm1(arg,arg2)) fun(parm1(arg,arg2), parm2)
fun(parm2, parm1(arg, arg2)) fun(parm1(arg, arg2), parm2)
fun(arg1, arg2, arg3) fun(arg2, arg1, arg3)
fun(arg1, arg2, arg3) fun(arg1, arg3, arg2)
array[arg2, arg1] array[arg1, arg2]
fun(parm2, parm1[]) fun(parm1[], parm2)
fun(parm2, parm1[]) fun(parm1[], parm2)
fun(array[], parm1) fun(parm1, array[])
fun(b,a) fun(a,b)

In the tests I mark the position of the cursor by enclosing a character with || symbols. Here is the first test.

  5     def test_simple_case(self):
  6         self.assertSwaps("fun(par|m|1, parm2)",
  7                             "fun(parm2, parm|1|)")