You may not need Vim relativenumber option after all

Notice

Vim relativenumber option is very popular and admittedly very seducing. So I believe this post may be controversial although this is absolutely not its intent. So please approach it with an open mind, thank you.

What is Vim relativenumber option

According to Vim's help, relativenumber option:

Show the line number relative to the line with the cursor in front of each line. Relative line numbers help you use the |count| you can precede some vertical motion commands (e.g. j, k, +, -) with, without having to calculate it yourself. Especially useful in combination with other commands (e.g. y, d, c, <, >, gq, gw, =).

As I before told, this sounds very seducing!

Drawback

So where is the bitter in this sweet nifty feature you would ask?

Firstly, looking at the margin, i.e in front of each line, to get a number to inform your vertical movements may be a form of distraction almost as big as grabbing your mouse to move the cursor.

Secondly, vertical motion commands used in combination with the relativenumber do not qualifies as Vim jumps and therefore do not feed the Vim jump list.

According to Vim's help, a jump is:

A command that normally moves the cursor several lines away.
If you make the cursor "jump", the position of the cursor before the jump is remembered. You can return to that position with the '' and `` commands, unless the line containing that position was changed or deleted.

'' and `` commands only let you move back and forth between last and current position, but to navigate beyond these 2 positions in the jump list the Ctrl + o and Ctrl + i commands exists to navigate respectively backward and forward through the list. Convenient isn't it?

Once this convenience mapped into your muscle memory you are up to some very efficient Vim editing experience. I though agree this requires practice, but as most of things in Vim.

Using relativenumber option, you miss the opportunity to benefit from this Vim convenience and key feature.

Finally, if you happen to do some pair-programming, relativenumber can reveal super disorienting for your pair when the line numbers in the margin keep updating as you are moving the cursor vertically.
You may end up turning off the option, but you are then left with absolute line number and feel hindered because you mapped your brain and muscle memory to use relative line number.

What should you do/learn doing instead?

Populate and navigate the jump list

At this point you may have understood that you should favour using Vim vertical motion commands that qualifies as jumps and therefore populate the jump list.
Remember this has the added benefit that you can navigate these jumps with Ctrl + o and Ctrl + i motion commands that respectively jump backward and forward the jump list.

Now you may be asking what are these qualifying commands?

Here is the list, with some attempt to provide a useful description of what they do:

Note that there are mentions of Vim marks below and that we will expand on these in the next section.

  • 'x: Jumps to line of Vim mark x; x being any character to be used as marks
  • `x: Jumps to position (line and column) of Vim mark x; x being any character to be used as marks
  • G: Jumps to the last line of the current buffer
  • nG: Jumps to the nth line of the current buffer
  • /foo: Jumps to first forward match of "foo" pattern
  • ?foo: Jumps to first backward match of "foo" pattern
  • n and N: Jumps to next and previous match of the work under the cursor
  • %: Jumps to pairing item of a pair (i.e. {}, ()...)
  • ( and ): Jumps backward and forward through sentences
  • { and }: Jumps backward and forward through paragraphs
  • :s: Jumps to the last location of a substitute command
  • :tag myTag: Jump to the definition of "myTag" tag
  • H: Jumps to the Highest (i.e first) line of the window's visible text
  • nH: Jumps to the nth line from the top of the window's visible text
  • M: Jumps to the line in the Middle of the window's visible text
  • L: Jumps to the Last (i.e bottom) line of the window's visible text
  • nL: Jumps to the nth line from the bottom of the window's visible text
  • [[: Jumps to the previous section (i.e previous opening curly brace in the first columns)
  • ]]: Jumps to the next section (i.e next opening curly brace in the first columns)

Note: Beware, ]] and [[ keymaps can be overridden by plugins and not count as jumps (e.g. with nvim-markdown plugin, and therefore in Markdown files).

Another field of possibilities offers to you if you consider Vim plugins. Indeed, there are some kind enough to maintain the jump list for you.

For instance telescope.nvim's builtin.current_buffer_fuzzy_find function, that you can use to fuzzy search terms within a Vim buffer.
Indeed, if you jump to the match, it updates the jump list accordingly, and therefore if you use '', `` or Ctrl + o, motion commands, it jumps back to the position the cursor was prior to the search. Nifty!

Use the change list commands

According to Vim's help:

When making a change the cursor position is remembered. Two commands can be used to jump to positions of changes...

  • g;: Jumps to position of last change
  • g,: Jumps to position of next change

This is yet another convenient feature to learn to master.

Use Vim marks commands

If you are not familiar to Vim marks I would highly recommend to have a read through Vim Fandom's "Using marks" entry.

Assuming you are now familiar to these, let's dig in and see what is in this for you to move away from using Vim relativenumber option.

It is possible to navigate between lowercase marks, a.k.a local (to current buffer) marks:

  • ]': Jumps to next line with a lowercase mark
  • [': Jumps to previous line with a lowercase mark
  • ]`: Jumps to next lowercase mark position (line and column)
  • [`: Jumps to previous lowercase mark position (line and column)

The above commands take a count. For example, 5]` jumps to the fifth mark after the cursor. This may be mentally taxing, so use this only if you are well equipped to carry this overhead.

Some more useful Vim marks commands:

  • `.: Jumps to position where last change occurred in current buffer
  • '': Jumps back (to line in current buffer where jumped from)
  • ``: Jumps back (to position in current buffer where jumped from)
  • `[: Jumps to the beginning of previously changed or yanked text
  • `]: Jumps to the end of previously changed or yanked text
  • `<: Jumps to the beginning of last visual selection
  • `>: Jumps to the end of last visual selection

Practical use of Vim marks

Here are 2 valuable hints I distilled from this great "Practical uses of marks" blog post that you may also find supportive.

  1. Marking important sections (e.g. configuration section, reference links section, key sections of code to jump back and forth from/to)
  2. Copying between distant parts of a file by setting a mark at the source (e.g. ms), then moving to the destination and yanking from the mark (e.g. y`s).

Capitalise on your learnings by combining marks and jumps beyond the edges of your current buffer

Once again distilled from the great "Practical uses of marks" blog post and applicable beyond the scope of your current buffer, here are 3 nifty tips:

  1. Set marks at key points in your workflow, then use jumps to navigate between these points and other parts of your file or project.
  2. Use uppercase marks to jump between files, and then use Ctrl + o to return to your previous position.
  3. Create a "breadcrumb trail" through your code by setting sequential marks (e.g., ma, mb, mc) and then use jumps to move along this trail.

Conclusion

Diving myself into the research to alternative options to using Vim's relativenumber option I came across a myriad of options and opportunities to forge, I think, a more efficient Vim editing experience.

I am at the starting point of this learning journey and very excited by the field of possibilities.

I hope this excitement and opportunity to become more efficient propagates to you, or that you at least pick up a few Vim tricks you did not know about along the way.

Resources