Monday, June 21, 2010

Extending vim with the Expression Register

If you press <C-r> (CTRL + r) in vim while in INSERT mode, you will have access to the expression register. This register allows you to execute some commands while in INSERT mode.

For example, if you press <C-r> and then " you will insert the text of the last delete (or yank) from the unnamed register. The following is a list of what you can insert:

"Unnamed register, containing the text of the last delete or yank
%Current filename
#Alternate file name
*Clipboard contents (X11: primary selection)
+Clipboard contents
/Last search pattern
:Last command-line
.Last inserted text
-Last small (less than a line) delete
=Explanation ahead

To view the contents of each of your registers, use :registers

The = sign

The = lets us to access vimscript functions. This means that by using a function like system, we are able to call external utilities and redirecting their output back to our text.

As an example, let's say we want a way to insert a random number between 0 and 100 in vim. The following is a very simple ruby script that generates this random number and prints it on stdout:

#!/usr/bin/ruby

print rand(100)

For the sake of this example, let's say this script is saved at ~/ruby/random.rb

We can now press <C-r> (while in INSERT mode) and when pressing =, we get a mini terminal at the bottom where we can type in the vimscript. Using the system function, we type the following to execute the ruby script, press Enter, and get its output:

=system('~/ruby/random.rb')

A random number should then be inserted in your text.

Now we are going to map a key combination that will let us access the script easier:

:imap <C-j>d <C-r>=system('~/ruby/random.rb')<CR>

imap allows you to map a key in INSERT mode and <CR> means Carriage Return, which basically simulates an 'Enter' press.

Now when we press <C-j>d (CTRL + j, d), we should get a random number inserted in our text from the ruby script.

The mini calculator

As a side note, with <C-r>= you also have a mini calculator in your hands! Try something like this:

<C-r>=5 * 3 + 4<CR>

Try it, and you'll see 19 in your text.