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 103. Navigate Keyword Definitions with Vim's Tag Navigation Commands

Tip 103. Navigate Keyword Definitions with Vim's Tag Navigation Commands

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

Navigate Keyword Definitions with Vim’s Tag Navigation Commands


Buffer Contents


require './speaker.rb'

class Anglophone < Speaker

def speak

puts "Hello, my name is #{@name}"



class Speaker

def initialize(name)

@name = name


def speak

puts "#{name}"



• 255

As we navigate our codebase in this fashion, Vim maintains a history of the

tags we’ve visited. The command acts as the back button for our tag

history. If we pressed it now, we would jump from the Speaker definition back

to the Francophone definition, and if we pressed it a second time, it would take

us back to where we started. For more information on interacting with the

tag jump list, look up :h tag-stack .

Specify Where to Jump to When a Keyword Has Multiple Matches

Our previous example was straightforward because the demo codebase contains only one definition for the Speaker and Anglophone keywords. But suppose

that our cursor was positioned on an invocation of the speak method, like this:'Jack').speak

The Speaker, Francophone, and Anglophone classes all define a function called speak,

so which one will Vim jump to if we invoke the command now? Try it


If a tag in the current buffer matches the keyword, it gets the highest priority.

So in this case, we would jump to the definition of the speak function in the

Anglophone class. Look up :h tag-priority

if you want to know more about how

Vim ranks matching tags.

Instead of , we could use the g command. Both of these commands

behave identically in the case when the current keyword has only a single

match. But if it has multiple matches, then the g command presents us

with a list of choices from the tag match list:

report erratum • discuss

Chapter 16. Index and Navigate Source Code with ctags

• 256

# pri kind tag


1 F C f




def speak

2 F





def speak

3 F





def speak

Type number and (empty cancels):

As the prompt indicates, we can choose which destination we want to jump

to by typing its number and pressing .

Suppose that we invoked and found ourselves on the wrong definition.

We could use the :tselect command to retrospectively pull up the menu of the

tag match list. Or we could use the :tnext command to jump to the next

matching tag without showing a prompt. As you might expect, this command

is complemented with :tprev, :tfirst, and :tlast. Refer to Create Mappings to

Quickly Traverse Vim's Lists, on page 79, for a suggested set of mappings for

these commands.

Use Ex Commands

We don’t have to move the cursor on top of a keyword to jump to its tag. We

could just as well call an Ex command. For example, :tag {keyword} and :tjump

{keyword} behave like the and g commands, respectively (see :h :tag

and :h :tjump ).

At times, typing these commands can be quicker than maneuvering the cursor

onto a keyword in the document—especially since Vim provides tab-completion

for all keywords in the tags file. For example, we could type :tag Fran, and

Vim would expand our fragment to Francophone.

Also, these Ex commands can accept a regular expression when used in the

form :tag /{pattern} or :tjump /{pattern} (note the leading / before {pattern}). For

example, to navigate between any definitions whose keywords end with phone,

we could invoke the following:

:tjump /phone$

# pri kind tag

1 F C c



class Anglophone < Speaker

2 F




class Francophone < Speaker

Type number and (empty cancels):

report erratum • discuss

Navigate Keyword Definitions with Vim’s Tag Navigation Commands

• 257

This table summarizes the commands that we can use to navigate our codebase using tags:



Jump to the first tag that matches the word under the cursor


Prompt user to select from multiple matches for the word

under the cursor. If only one match exists, jump to it without


:tag {keyword}

Jump to the first tag that matches {keyword}

:tjump {keyword}

Prompt user to select from multiple matches for {keyword}. If

only one match exists, jump to it without prompting.

:pop or

Reverse through tag history


Advance through tag history


Jump to next matching tag


Jump to previous matching tag


Jump to first matching tag


Jump to last matching tag


Prompt user to choose an item from the tag match list

report erratum • discuss


Compile Code and Navigate Errors

with the Quickfix List

Vim’s quickfix list is a core feature that allows us to integrate external tools

into our workflow. At its simplest, it maintains a sequence of annotated

addresses comprising the filename, line number, column number (optional),

and a message. Traditionally, these addresses would be a list of error messages

generated by a compiler, but they could just as well be warnings from a syntax

checker, linter, or any other tool that emits such output.

We’ll start off by looking at an example workflow: running make in an external

shell and navigating to error messages by hand. Then we’ll introduce the :make

command, seeing how it can streamline our workflow by parsing error messages from the compiler and making them navigable in the form of the

quickfix list.

Tip 105, on page 262, provides a tour of the most useful commands for navigating the results of running :make. Then in Tip 106, on page 265, we’ll learn

that the quickfix feature has its own form of the undo command.

In Tip 107, on page 265, we’ll walk through the steps required to configure

Vim so that calling :make puts the contents of a JavaScript file through JSLint,

generating a navigable quickfix list from the output.

report erratum • discuss

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

• 260

Tip 104

Compile Code Without Leaving Vim

Calling an external compiler from Vim saves us from having to leave our editor—and if the compiler reports any errors, Vim provides the means for us to

jump between them quickly.


We’ll use a small C program to demonstrate. The source files are distributed

with this book (for more details, refer to Section 3, Downloading the Examples,

on page xxii). In the shell, change to the code/quickfix/wakeup directory:

$ cd code/quickfix/wakeup

You’ll need gcc to build this program, but don’t feel that you need to install a

compiler just to follow this tip. The workflow here demonstrates the task for

which the quickfix list was originally conceived (and from which it takes its

name). As we’ll soon see, this feature has many other uses.

Compile the Project in the Shell

The wakeup program provided consists of three files: Makefile, wakeup.c, and

wakeup.h. From the shell, we could compile it by running make:

$ make


-c -o wakeup.o wakeup.c

wakeup.c:68: error: conflicting types for ‘generatePacket’

wakeup.h:3: error: previous declaration of ‘generatePacket’ was here

make: *** [wakeup.o] Error 1

The compiler helpfully reports a couple of errors. It’s all very well having this

information printed in the terminal, but now we need to navigate to each of

the errors so that we can fix them in Vim.

Compile the Project from Inside Vim

Instead of running make in the shell, let’s try building the project from inside

Vim. Make sure that you’re in the code/quickfix/wakeup directory and that it

includes a Makefile file, and then launch Vim like this:

$ pwd; ls


Makefile wakeup.c wakeup.h

$ vim -u NONE -N wakeup.c

report erratum • discuss

Compile Code Without Leaving Vim

• 261

From inside Vim, we can now run the :make command:



-c -o wakeup.o wakeup.c

wakeup.c:68: error: conflicting types for ‘generatePacket’

wakeup.h:3: error: previous declaration of ‘generatePacket’ was here

make: *** [wakeup.o] Error 1

Press ENTER or type command to continue

We get the same result as when we ran make in the shell—except that Vim

does something smart with the output. Instead of just echoing the output

from make, Vim parses each line, extracting the filename, line number, and

error message. For each warning, Vim creates a record in the quickfix list.

We can navigate backward and forward through these records, and Vim jumps

to the exact line corresponding to the error message. As Vim’s documentation

on quickfix says (:h quickfix ), it allows us to “speed up the edit-compile-edit


Vim jumps to the first record in the quickfix list when we run :make. In our

case, we should find ourselves in the file wakeup.c at the top of this function:

void generatePacket(uint8_t *mac, uint8_t *packet)


int i, j, k;

k = 6;

for (i = 0; i <= 15; i++)


for (j = 0; j <= 5; j++, k++)


packet[k] = mac[j];




The error message reports “conflicting types for ‘generatePacket’.” We can skip to the

next location in the quickfix list by running the command :cnext. In this case,

we jump to the file wakeup.h and find ourselves on this line:

void generatePacket(char *, char *);

That explains why the compiler was complaining: the signature for this

function in the header file doesn’t match the one used in the implementation.

Let’s change the line in the header file to use the uint8_t type. Make it so:

void generatePacket(uint8_t *, uint8_t *);

Save the changes to the file, and then we’ll call :make again:

report erratum • discuss

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

Tip 103. Navigate Keyword Definitions with Vim's Tag Navigation Commands

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