Vim tips: Moving around using marks and jumps

24547

Author: Joe 'Zonker' Brockmeier

Editing in Vim can be a breeze, if you know how to make use of its more advanced features. Moving around files can feel like a slog if you’re stuck with the basic movement keys, but editing is effortless when you have command of marks and jumps.

Basically, a mark is a bookmark or placeholder that allows you to return to a spot in the file where you were editing. This can be handy when you’re working on longer projects, whether you’re writing a long paper, making changes to your Apache configuration, or writing code.

Jumps are movements within a file. For example, when you use G to move to the last line of a file from your current position, that’s a jump. Vim not only makes it easy to move from one point in the file to another, it also makes it easy to retrace your steps.

m marks the spot

Let’s take a look at Vim marks. All you need to do to set a mark is to enter normal mode, then type mx, where x is the letter you want to assign to the mark.

For example, if you’re typing and decide that you need to set a mark so you can return to a sentence or line of code you’re not entirely happy with, press Esc to leave insert mode, then type ma to set a mark at the spot your cursor was on.

You can use any letter in the alphabet, upper or lower case. However, capital letters are global marks, so you should use them only in special circumstances, which I’ll explain in just a bit. It’s not necessary to use them in alphabetical order; you can set mark z right after setting mark a if you like, or skip a altogether and start with z.

To return to the mark you’ve set, enter normal mode (if you’re not in normal mode already) and type `x where x is the letter associated with the mark you want to revisit. The backtick (`) will return you to the exact spot where the mark was set. You can also use the single quote ('), which will return you to the beginning of the line you were at, but not the exact cursor position.

Marks set with lowercase letters are specific to the file that they’re set in. That is to say, if you are using a Vim session to edit two files in a split viewport, then you can set mark a in both files. When you’re editing file 1, using `a would take you to mark a in file 1. When in file 2, `a would take you to the spot in file 2 marked a — which is probably what you’d expect.

However, if you’re using Vim to edit two files and you’ve set mark A, it will be specific to that file. So, if you’re editing file 2, and have mark A set in file 1 and use `A, Vim will close the current file and take you to mark A in file 1. If file 2 has unsaved changes, Vim will complain that you haven’t written the file since the last change, and refuse to open the new file.

While global bookmarks are useful on occasion, it’s usually best to stick to lower-case marks unless you have a specific need for global bookmarks.

Now where did I leave that?

After spending an hour or two editing a file, you might forget exactly where you’ve set marks in a file. If you’d like to see where they are, you can enter command mode and use the :marks command. Vim will display the name of each mark, the line and column number where it is set, and part of the text from that line. Note that Vim won’t start the display on the column where the mark begins — instead, you’ll see the beginning of the line where the mark is set. So, if you’ve set marks for a, b, and c, you will see where those marks are set, but you’ll also see a few other marks that you might not recognize. Here’s a shortish example:

mark line  col file/text
 '    112    0
 a     11    3 <p>For example, if you're typing and decide that you
 b    103    0 <p>By default, when you exit Vim, the marks that you've
 D     26    0 ~/src/gaim-2.0.0beta2/src/Makefile
 0     61   60 <p>The " mark is set to the last position of the cursor
 1    103    0 <p>By default, when you exit Vim, the marks that you've
 "     35    0 <p><strong><code style="background-color: yellow;">'"</code>
 [     52    0
 ]     54    0
 ^     54    0
 .     73  115 <p>The . mark will take you to the last position a change
Press ENTER or type command to continue

Vim mark quick reference

mx tells Vim to add a mark called x.

`x tells Vim to return to the line and column for mark x.

'x tells Vim to return to the beginning of the line where mark x is set.

`. moves the cursor to the line and column where the last edit was made.

'. moves the cursor to the line where the last edit was made.

'" moves the cursor to the last position of the cursor when you exited the previous session.

:marks shows all marks set.

:marks x shows the mark named x.

:jumps shows the jumplist.

Ctrl-o moves the cursor to the last jump.

Ctrl-i moves the cursor to the previous jump.

H moves the cursor to the top of the screen or viewport.

M moves the cursor to the middle of the screen or viewport.

L moves the cursor to the bottom of the screen or viewport.

Specifically, you’ll see marks for ., [, ], “, ‘, and a few others. Those marks are present whether you’ve set any marks manually or not. The [ and ] marks indicate the last changed or copied (“yanked”) text. The [ mark is the first character of the text that’s been changed or yanked, the ] is the last character of that text. Note that these marks don’t work until you actually make a change in the file.

The . mark will take you to the last position a change was made. So, '. will take you to the line where the last change was made in your file, and `. will take you to the cursor position where the last change was made.

If you make a jump within a file — that is, if you use a movement or search command to move within the file — the ` character will return you to the position you started from. For example, using the G movement command you can jump to the bottom of the file. If you want to return to the last cursor position, use `` and you’ll be moved back to the last location of the cursor before using G. We’ll discuss jumps in more detail a bit later.

The ” mark is set to the last position of the cursor when you exited the previous Vim session, if you have Vim configured to save your session information using a viminfo file. We’ll cover that in just a bit too.

Finally, if your session information is being saved, you can also use numbered marks to return to the last position the cursor was at when you closed a file. Using numbered marks, `0 will move the cursor to the last position it was at when you closed a file. `1 will move the cursor to the last position it was at when you closed the file the time before last, and so forth.

If you just want to know where a specific mark is in the file, you can use :marks markname to display just those marks. To see marks a and B, for instance, you’d just use :marks aB. This is pretty useful when you have 10 or 20 marks set.

Advanced marking

Marks are useful for more than just moving about a file — though that feature alone is very useful. Marks can also be used to specify a range for commands. Normally, if you want to delete a few lines, you can use line numbers to specify the line, like so:

:22,55 d

That will delete lines 22 through 55. But it’s much easier to remember marks than line names most of the time. If you have line 22 marked as g and 55 marked as k, you could substitute :'g,'k d and remove those lines without having to go back and confirm the line numbers. This works with other commands too, so you could just as easily write those lines to a file using :'g,'k w filename or use the range for a substitution command like this:

:'g,'k s/foo/bar/g

The jumplist

Vim stores a list of your movements throughout a file, whether they’re associated with marks or not. To see a full list of jumps within a file, use :jumps. Here’s a short sample:

:jumps
 jump line  col file/text
    3     1    0 /**
    2   608    0 }
    1    33    0 #include "log.h"
>
Press ENTER or type command to continue

Vim lists the jump number, line number, and column of the last location of the cursor for each jump, as well as a bit of text to help provide context. You can cycle between jump locations using the Ctrl-o and Ctrl-i keybindings. Ctrl-o will move you to the last jump, then the next-to-last, and so forth. In this instance, if you use Ctrl-o, you’d be taken to line 33, then line 608, then 1. To move forwards through the jump history, use Ctrl-i — which would take you from line 1 (jump 3) to line 608, then line 33.

Though they’re not jumps, since we’re discussing moving around a file easily, you might want to familiarize yourself with the movement commands G, gg, H, M, and L. G, as we’ve already discussed, will take you to the bottom of the file. The gg command will move you to the top of the file. The H, M, and L commands will move you to the top, middle, and bottom of the screen, respectively.

Saving marks and jumps

By default, when you exit Vim, the marks and jumps that you’ve created are lost. Luckily, there’s an easy way to save the marks you’ve created by making use of the viminfo file, which saves state information between Vim sessions.

To make sure this feature is enabled, open your .vimrc and look for a line that begins with set viminfo=. If you don’t have that line, insert it. It should look something like this:

set viminfo='100,f1

If you have viminfo set, it will save local marks (a-z) by default. The ‘100 tells Vim to save marks and other information for up to 100 files. The f1 directive tells Vim to also save global marks (A-Z) when it exits. If you don’t want Vim to do this, set it to f0 instead.

You can use the viminfo file for a lot more than saving marks and jumps, but we’ll have to cover that in a future installment.