Learn Vim at your own pace with my self-study Core Vim Course.

Learn more

Learn Vim at your own pace with my self-study Core Vim Course.

Evaluating scripts with Vim's expression register

#57

Run time:

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.

Shownotes

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

Comments

Level-up your Vim

Training

Boost your productivity with a Vim training class. Join a public class, or book a private session for your team.

Drew hosted a private Vim session for the shopify team that was one of the best workshops I have ever attended.

John Duff, Director of Engineering at Shopify

Publications

Make yourself a faster and more efficient developer with the help of these publications, including Practical Vim (Pragmatic Bookshelf 2012), which has over 50 five-star reviews on Amazon.

After reading it, I've switched to vim as my default editor on a daily basis with no regrets. ★★★★★

Javier Collado

Learn to use Vim efficiently in your Ruby projects

In association with thoughtbot, one of the most well respected Rails consultancies in the world, I've produced a series of screencasts on how to make navigating your Ruby projects with Vim ultra-efficient. Along the way, you’ll also learn how to make Ruby blocks a first-class text object in Vim. This lets you edit Ruby code at a higher level of abstraction. Available to buy from thoughtbot..