Using Command-Line Tools on Vim Buffers

23 Apr, 2020 · 3 min read · #vim #command-line #tips #linux

Vim offers many ways to use the command-line tools available on your system when editing. You can:

  1. insert the output of a command into the current buffer - e.g., insert the current date.
  2. process lines of the current buffer through a command - e.g., sum up a list of numbers in the file.
  3. manipulate lines of the current buffer using a command - e.g., sort a list of names in the file.

Inserting Output of a Command #

The read (:r) command in Vim, reads the contents of a file and inserts it into the current buffer after the current line. It can also read and insert the output of a command, instead of a file. If the argument begins with !, it is interpreted as a system command to be executed.

Say you want to insert the current date into the buffer. If the contents of the current buffer is,

Date:

Executing the following command in Vim’s command-line,

:r !date --iso

will result in

Date:
2020-04-23

You can then place the cursor back on the first line and type J to combine the lines and get,

Date: 2020-04-23

Send Buffer as Input #

The write (:w) command is usually used to write contents of the current buffer to a file. Similar to read, write can write to the standard input of a command instead of a file.

Say you have the following list of numbers in your buffer and you want to find their sum.

577
858
863
867
764

awk is a handy tool to process a set of lines and print some aggregate information at the end of all lines. You can execute the below command in Vim’s command-line,

:w !awk '{sum+=$1} END {print sum}'

and the sum will be printed as below.

:w !awk '{sum+=$1} END {print sum}'
3929

Press ENTER or type command to continue

Manipulating the Buffer #

Vim allows you to combine the above abilities and edit contents of a buffer using tools available on your system. You can also manipulate a subset of lines, instead of the entire buffer, using external tools. The selected lines are written to the standard input of the command and are subsequently replaced with the output of the command.

Say you have a markdown file with a list of names that you’d like to sort alphabetically.

The core members of this project are:

1. Harry
1. Christine
1. Mary
1. William
1. Daniel

Select the list of names in visual mode. Type : and you’ll see that the command-line automatically starts with '<,'>, representing the range of lines selected. Complete the command as below to sort the list of names in-place, using your system’s sort command.

:'<,'> !sort

You can also place the cursor on the first item in the list and use a line range instead of selecting the lines in visual mode.

:.,+4 !sort

What if you want to insert the output of a command after a list of items, without replacing the list itself? For example, in the previous example where we computed the sum using awk, what if we want to insert the sum after the list of numbers?

Select the lines containing numbers, visually, and execute,

:'<,'> !awk '{print; sum+=$1} END {print "Sum: " sum}'

This works exactly like the sorting example, and replaces the list of numbers with the output of awk. We just got awk to print each original line back to its output, thus retaining the original lines in buffer.

If you liked what you read, consider subscribing to the RSS feed in your favourite feed reader.