The Vim text editor provides built-in support for parsing compiler output. It has quite a broad understanding of the concept of a compiler though: You can call just any command and let the editor parse its output. For this to work correctly, format strings need to be specified, matching the expected format of compiler warnings and errors. This article is meant as a challenge for you, the reader. Does that sound interesting? Read on!

In the first part of the article, we will see how to compile a simple C program via Vim – which is kind of a standard use case. After that we will use the same approach for something that you wouldn’t normally consider a compiler. Finally, in the last part it’s your job to create a custom errorformat expression that enables Vim to parse the output of our custom ‘compiler’ introduced before.

The :make command

To get started, let’s take a look at a gcc-based workflow. We will see how to call the compiler through the editor and get the interpreted output into our quickfix list.

Consider the following Makefile along with an example C program that has some obvious issues:

# Makefile
test: test.c
	gcc -Wall -o test test.c
/* test.c */
int main(void) {
  int a = 0;
  int b = 5
  return 0;
}

As a preparation, we enable the gcc compiler which is usually shipped with Vim already. In command mode (reachable via :), enter:

compiler gcc

This enables the corresponding plugin, which in turn sets the errorformat option so it contains patterns for parsing the gcc compiler output.

In contrast to other compiler plugins, the gcc plugin does not set the makeprg option. So we will do this ourselves:

:set makeprg=make

After these configuration steps you can call the make command through the Vim command line:

:make test

Now here comes the interesting part: The parsed output of the compiler run will be fed into the quickfix list automatically. We can verify that by opening up the quickfix window via :copen, as shown in the screenshot below.

As you can see, there are three lines in the quickfix window that show the error and warnings generated by gcc. The error is highlighted – matching the cursor position (line 4) in the upper window. You can now jump to the remaining warnings using the :cnext command.

Another use case for :make

As stated in the introduction above, Vim’s make command is agnostic towards the actual command it is supposed to call. That’s why we might use it for totally different tasks – text processing for example.

As an exercise, we will create a script query_match.py that can find all occurrences of a particular pattern inside of a text file and output a row/column pair for each match.

Consider the following input file:

# haystack.txt
bar baz foo bar baz baz bar foo
baz foo bar baz baz bar foo bar
foo bar baz baz bar foo bar baz
bar baz baz bar foo bar baz foo
baz baz bar foo bar baz foo bar
baz bar foo bar baz foo bar baz
bar foo bar baz foo bar baz baz
foo bar baz foo bar baz baz bar
bar baz foo bar baz baz bar foo
baz foo bar baz baz bar foo bar

In order to issue a query from within Vim, we set the makeprg option accordingly and call make:

:set makeprg=./query_match.py
:make haystack.txt foo

This will find all occurrences of the string ‘foo’, resulting in the following output:

haystack.txt:1:9
haystack.txt:1:29
haystack.txt:2:5
haystack.txt:2:25
haystack.txt:3:1
haystack.txt:3:21
haystack.txt:4:17
haystack.txt:4:29
haystack.txt:5:13
haystack.txt:5:25
haystack.txt:6:9
haystack.txt:6:21
haystack.txt:7:5
haystack.txt:7:17
haystack.txt:8:1
haystack.txt:8:13
haystack.txt:9:9
haystack.txt:9:29
haystack.txt:10:5
haystack.txt:10:25

That looks pretty good so far. Unfortunately though, the editor is not yet able to parse the output of the query_match script. If we open up the quickfix list, we will see the original output, but without any mapping to the actual line and column numbers.

The challenge

That’s where the errorformat option comes in. We need to create a pattern that matches the output format of query_match.py. It probably will take some trials until we get the pattern right. This is a very basic example of course, so it won’t be too hard.

The example script simulates a database query that takes about ten seconds. In this case, or if the input file were some gigabytes in size, we will need a little trick to keep the edit-test cycle short: the cfile command. It tells Vim to read a text file and parse it as if it was the output of a command called via :make.

That way we need to process the input file only once. We can easily store the result in another file and inject its content into Vim as often as we desire:

./query_match.py haystack.txt foo > output.txt

Then, from within Vim:

:cfile output.txt

Now the quickfix list is populated – and we can repeat that until we find an errorformat setting that fulfills our needs.

I will leave this as an exercise for you. A solution will published together with the next blog article. Feel free to send me a message if you have any comments or ideas!

Sample code & References

You can find the demo project at github. It contains everything you need to reproduce the example from this article.

Vim has a very good internal help system. You can get information on any option or command by entering help <option> on the command line.

These are some help sections related to this article: