Vim’s absolute, relative and hybrid line numbers

Vim doesn’t show line numbers by default, but they can be turned on in your configuration. Besides regular absolute line numbers, Vim has relative and “hybrid” modes to help navigate around files. With the vim-numbertoggle plugin, it can even toggle between line number modes automatically when you switch files or enter insert mode.

Absolute line numbers

Using the number option, Vim sets up absolute line numbers to show the line number for each line in the file you’re working on.

" turn absolute line numbers on
:set number
:set nu

" turn absolute line numbers off
:set nonumber
:set nonu

" toggle absolute line numbers
:set number!
:set nu!

Besides being useful for finding a line from a stack trace or a test result, you can use line numbers to help you jump around the file. For example, if you want to go to the tenth line in your file, you’d type esc while in insert mode and then :10 to move to the correct line.

Relative line numbers

With the relativenumber option, each line in your file is numbered relative to the cursor’s current position to show the distance to that line. The current line is marked 0, the ones above and below it are marked 1, and so on.

" turn relative line numbers on
:set relativenumber
:set rnu

" turn relative line numbers off
:set norelativenumber
:set nornu

" toggle relative line numbers
:set relativenumber!
:set rnu!

Like most commands in Vim, the j and k (or and ) keys can be prefixed with a number. Typing 5j will move the cursor five lines down, for example. If you want to remove seven lines, you can use d7d without having to switch to visual mode to select the lines first.

It can be difficult to see how far you need to jump to get to where you want to be, rendering this method useless for any jumps over ten lines. Also, absolute line numbers become less useful when working in lengthy files.

With relative line numbers, you can glance at the number of the line you want to jump to. If it’s thirteen lines up, you press 13k to get there. To get back to where you came from, you use 13j.

“Hybrid” line numbers

Since Vim 7.4, enabling number and relativenumber at the same time produces hybrid line number mode. All lines will show their relative number, except for current line, which will show its absolute line number.

" turn hybrid line numbers on
:set number relativenumber
:set nu rnu

" turn hybrid line numbers off
:set nonumber norelativenumber
:set nonu nornu

" toggle hybrid line numbers
:set number! relativenumber!
:set nu! rnu!

Hybrid line numbers are what relative line numbers should have been. Instead of having a useless zero on the current line, it uses that space to give you an idea of where you are in the file1.

Automatic toggling between line number modes

Relative line numbers are helpful when moving around in normal mode, but absolute line numbers are more suited for insert mode. When the buffer doesn’t have focus, it’d also be more useful to show absolute line numbers. For example, when running tests from a separate terminal split, it’d make more sense to be able to see which test is on which absolute line number.

Using some autocommands, Vim can switch between line number modes automatically.

:set number

:augroup numbertoggle
:  autocmd!
:  autocmd BufEnter,FocusGained,InsertLeave,WinEnter * if &nu && mode() != "i" | set rnu   | endif
:  autocmd BufLeave,FocusLost,InsertEnter,WinLeave   * if &nu                  | set nornu | endif
:augroup END

In this example, both absolute and relative line numbers are enabled by default, which produces “hybrid” line numbers. When entering insert mode, relative line numbers are turned off, leaving absolute line numbers turned on. This also happens when the buffer loses focus, so you can glance back at it to see which absolute line you were working on if you need to.

I’ve been using this way of automatically switching line number modes for years. You can set it up yourself by putting the snippet above in your ~/.vimrc, or use the vim-numbertoggle plugin, which does the same thing.

  1. Another way to see which line you’re currently on is Vim’s ruler option, which shows the current line and column. You can see it in action in the screenshots above, in the bottom right. It’s turned on by default in NeoVim and vim-sensible, but you can also turn it on yourself using :set ruler.