Practical Vim< /a> vit Practical Vim< /a> Note that the styling for a Visual selection is the... development I thought I knew Vim, but Practical" name="description"/>
Tải bản đầy đủ - 0 (trang)
Tip 107. Customize the External Compiler

Tip 107. Customize the External Compiler

Tải bản đầy đủ - 0trang

Chapter 17. Compile Code and Navigate Errors with the Quickfix List

• 266

First, we’ll configure Vim so that running :make calls nodelint,1 a commandline interface to JSLint.2 It depends on Node.js and can be installed using

NPM simply by running this:3

$ npm install nodelint -g

As a test case, we’ll use this JavaScript implementation of FizzBuzz:


var i;

for (i=1; i <= 100; i++) {

if(i % 15 == 0) {


} else if(i % 5 == 0) {


} else if(i % 3 == 0) {


} else {




Configure ‘:make’ to Invoke Nodelint

The ‘makeprg’ setting allows us to specify the program that will be called when

we run :make (see :h 'makeprg' ). We can instruct Vim to run nodelint as follows:

:setlocal makeprg=NODE_DISABLE_COLORS=1\ nodelint\ %

The % symbol is expanded to the path for the current file. So if we were editing

a file called ~/quickfix/fizzbuzz.js, then running :make inside Vim would be equivalent to running this in the shell:


$ nodelint ~/quickfix/fizzbuzz.js

~/quickfix/fizzbuzz.js, line 2, character 22:

for (i=1; i <= 100; i++) {

~/quickfix/fizzbuzz.js, line 3, character 15:

if(i % 15 == 0) {

~/quickfix/fizzbuzz.js, line 5, character 21:

} else if(i % 5 == 0) {

~/quickfix/fizzbuzz.js, line 7, character 21:

} else if(i % 3 == 0) {

~/quickfix/fizzbuzz.js, line 12, character 2:


5 errors




Unexpected '++'.

Expected '===' ...

Expected '===' ...

Expected '===' ...

Unexpected ';'. and, respectively.

report erratum • discuss

Customize the External Compiler

• 267

By default, nodelint highlights errors in red using ANSI color codes. Setting

NODE_DISABLE_COLORS=1 mutes the colors, which makes it easier to parse the

error messages.

Next, we have to make Vim parse the output from nodelint so that it can build

a quickfix list from the results. We can approach this problem in two ways:

we could configure nodelint so that its output resembled the error messages

generated by make, which Vim already understands, or we could teach Vim

how to parse the default output from nodelint. We’ll use the latter technique.

Populate the Quickfix List Using Nodelint’s Output

The ‘errorformat’ setting allows us to teach Vim how to parse the output generated by running :make (see :h 'errorformat' ). We can inspect the default value

by running the following:

:setglobal errorformat?

errorformat=%*[^"]"%f"%*\D%l: %m,"%f"%*\D%l: %m, ...[abridged]...

If you’re familiar with scanf (in C), then you’ll recognize the concept. Each of

the characters preceded by a percent sign has a special meaning: %f stands

for the filename, %l for the line number, and %m for the error message. For

the complete list, look up :h errorformat .

To parse the output from nodelint, we could set the error format as follows:

:setlocal efm=%A%f\,\ line\ %l\,\ character\ %c:%m,%Z%.%#,%-G%.%#

Now when we run :make, Vim will use this error format to parse the output

from nodelint. For each warning it will extract the filename, line number, and

column number to generate an address, which becomes a record in the

quickfix list. That means we can jump between warnings using all of the

commands discussed in Tip 105, on page 262.

Set Up ‘makeprg’ and ‘errorformat’ with a Single Command

This ‘errorformat’ string is not something we would want to commit to memory.

Instead, we can save it to a file and then activate it with the :compiler command,

which is a convenient shortcut for setting both ‘makeprg’ and ‘errorformat’ options

(see :h :compiler ):

:compiler nodelint

The :compiler command activates a compiler plugin, which sets the ‘makeprg’ and

‘errorformat’ options to run and parse nodelint. It’s roughly equivalent to

sourcing these lines of configuration:

report erratum • discuss

Chapter 17. Compile Code and Navigate Errors with the Quickfix List

• 268


setlocal makeprg=NODE_DISABLE_COLORS=1\ nodelint\ %









&l:efm.='%f\, '

&l:efm.='line %l\, '

&l:efm.='character %c:'

&l:efm.='%m' . ','

&l:efm.='%Z%.%#' . ','


The internals of a compiler plugin are more elaborate, but this is a fair

approximation of what goes on. You can familiarize yourself with the compiler

plugins that are distributed with Vim by running this command:

:args $VIMRUNTIME/compiler/*.vim

Note that Vim doesn’t ship with a nodelint compiler plugin, but we can easily

install one.4 If we wanted to always use nodelint as the compiler for JavaScript

files, we could either use an autocommand or a file-type plugin to make it so.

To find out how, see Section A1.3, Apply Customizations to Certain Types of

Files, on page 298.

‘:compiler’ and ‘:make’ Are Not Just for Compiled Languages

The words make and compile have particular meanings in the context of a compiled

programming language. But in Vim, the corresponding :make and :compile commands

have more flexible definitions, making them just as applicable for interpreted languages

and markup formats.

For example, when working on a LaTeX document, we can configure Vim so that the

:make command compiles our .tex file into a PDF. Or if we’re working with an interpreted language such as JavaScript, we can have :make run our source code through

JSLint or some other (less opinionated) syntax checker. Alternatively, we could set

up :make so that it runs the test suite.

In Vim’s terminology, a compiler is any external program that does something with

our document and produces a list of errors or warnings. The :make command simply

invokes the external compiler and then parses the output to construct a navigable

quickfix list from them.


report erratum • discuss


Search Project-Wide

with grep, vimgrep, and Others

Vim’s search command is great for finding all occurrences of a pattern within

a file. But what if we want to find matches across an entire project? Then we

have to scan many files. Traditionally, this has been the domain of grep, a

dedicated Unix tool.

In this chapter, we’ll discover Vim’s :grep command, which allows us to call

an external program without leaving our editor. While this command calls

grep by default (when available), we’ll see that it can easily be customized to

outsource the task to other dedicated programs, such as ack.

One down side to using external programs is that their regex syntax may be

incompatible with the one we use for most Vim searches. We’ll see that the

:vimgrep command allows us to use Vim’s native search engine to find patterns

in multiple files. This convenience comes at a cost: vimgrep isn’t nearly as fast

as dedicated programs.

Tip 108

Call grep Without Leaving Vim

Vim’s :grep command acts as a wrapper to an external grep (or grep-like) program.

Using this wrapper, we can have grep search for a pattern across multiple files

without leaving Vim, and then we can navigate the results using the quickfix


report erratum • discuss

Chapter 18. Search Project-Wide with grep, vimgrep, and Others

• 270

First we’ll step through a workflow where grep and Vim run independently

without talking to each other. We’ll examine the weaknesses with this

approach before considering an integrated solution that solves these problems.

Using grep from the Command Line

Suppose that we’re working on something in Vim and we need to find every

occurrence of the word “Waldo” in all files in the current directory. Leaving

Vim, we run the following in the shell:

$ grep -n Waldo *

department-store.txt:1:Waldo is beside the boot counter.

goldrush.txt:6:Waldo is studying his clipboard.

goldrush.txt:9:The penny farthing is 10 paces ahead of Waldo.

By default, grep prints one line of output for each match, displaying the contents of the matching line and the name of the file. The -n flag tells grep to

include the line number in the printed output.

So what can we do with this output? Well, we could just treat it as a table of

contents. For each line in the result list, we could open the file and specify

the line number. For example, to open goldrush.txt at line 9, we could run this

from the shell:

$ vim goldrush.txt +9

Surely our tools can integrate better than this.

Calling grep from Inside Vim

Vim’s :grep command is a wrapper for the external grep program (see :h :grep ).

Instead of running grep in the shell, we could execute this directly from Vim:

:grep Waldo *

Behind the scenes, Vim executes grep -n Waldo * in the shell for us. Rather than

printing grep’s output, Vim does something much more useful. It parses the

results and builds a quickfix list from them. We can navigate through the

results using the :cnext/:cprev commands and all of the other techniques that

we explored in Chapter 17, Compile Code and Navigate Errors with the

Quickfix List, on page 259.

Even though we simply called :grep Waldo *, Vim automatically included the -n

flag, telling grep to include line numbers in the output. That’s why when we

navigate through the quickfix list, it takes us directly to each matching line.

Suppose we want to run a case-insensitive grep. We supply grep with the -i flag:

:grep -i Waldo *

report erratum • discuss

Tài liệu bạn tìm kiếm đã sẵn sàng tải về

Tip 107. Customize the External Compiler

Tải bản đầy đủ ngay(0 tr)