Subscribe for free with iTunes, Twitter, or RSS (Ogg or Quicktime).

Vimcasts

Evaluating scripts with Vim's expression register

#57

In the previous lesson we learned how use the expression register to evaluate simple calculations. We can also call built-in and user-defined Vimscript functions, and thanks to the system() function, we can also fetch output from external scripts.

Download

OGG 5.3 MB

Quicktime 9.5 MB

Calling functions from Vimscript standard library

In the last lesson, we saw how the expression register can be used for evaluating simple calculations, such as 2*21. We can also use functions from the Vimscript standard library. For example, we could use the sqrt() function to calculate the square root of a number:

:put =sqrt(81)

We can execute any Vimscript code at the expression register. So long as the expression returns a string (or something that can be converted to a string), then we can use the result. For a complete reference of the functions defined in Vim’s standard library, look up :h function-list.

Calling user-defined functions

We’re not limited to using functions defined in the Vimscript standard library. We can also evalute user-defined functions. For example, Vimscript has no simple way of generating a random number. We could hand-roll our own Random() function (this example is copied from StackOverflow):

function! Random()
  return str2nr(matchstr(reltimestr(reltime()), '\v\.@<=\d+')[1:])
endfunction

We could use this function at the expression register:

:put =Random()

Calling external scripts

The system() function allows us to get the output from some external script. For example, if we’re running Vim inside the Bash shell, we could use the built-in bash function $RANDOM to fetch a random number:

:put =system('echo $RANDOM')

If we wanted some more complex behaviour, we could write a script using a language of our choice. For example, here’s a tiny script written in Ruby, which uses the faker library to generate fake credentials:

require 'faker'
name = [Faker::Name.first_name, Faker::Name.first_name].join(" ")
print [name, Faker::Internet.email(name)].join(",")

We could run this script at the Bash shell like this:

$ ruby fake-credentials.rb
Lottie Walton,lottie.walton@hartmannsipes.name

Inside of Vim, we could use the expression register to insert the results from this external script into the document:

:put =system('ruby fake-credentials.rb')

Ex commands

We can invoke the expression register using the :put Ex command. For example, this command would insert a new line containing the text ‘9.0’:

:put =sqrt(81)

When we invoke the expression register from Insert mode (via <C-r>=), the result is inserted at the current cursor location. Whereas the :put Ex command always inserts the result on a new line.

We could use this same technique to insert fake credentials from our simple ruby script:

:put =system('ruby fake-credentials.rb')

If you’re only using the expression register to get output from an external script, then there’s an even quicker way of doing it: using the :read! “read-bang” Ex command.

:read !ruby fake-credentials.rb

This executes the specified command in the shell and outputs the results directly into the document below the cursor position.

Further reading