Vim Tip #34: Status Line

2022-11-05(Sat)

tags: Vim

Vim Tips

The original vi used to open (I think) without a status line. And I think vim still defaults to that, but nearly every vim user on the face of the planet (based on screenshots and screencasts available on the Internet) runs set laststatus=2 in their ~/.vimrc (or for nvim users like myself, in ~/.config/init.vim). If you don't see a status line in your Vim (and I assume you want to or you wouldn't be reading this), just open Vim and type :set laststatus=2. The laststatus variable can be set to "0" - which means never show the status line, "1" - show the status line if there are at least two windows, and "2" always show the status line.

If you already have a specialty status line in place (I've been using Airline), you can either turn it off with something like :AirlineToggle or similar (most bundle-installed packages have a switch like this), or if that's not working, exit Vim and restart it with vim -u NONE which means "start with no configuration at all."

This is Vim. That means that it's an incredibly complex tool - and you've just found your way into one of the corners that's only been documented by the developers. There are no books for this, and precious few websites. (I'm trying to help with that by writing this, but I'm not all that dedicated: remember the upcoming tip because you'll need it.) If you want to read about status line configuration, take a look at :help statusline and realize you'll be referring to it a lot.

Let's start with a really basic status line (this is considerably less useful than the ugly default status line, but you have to start somewhere): :set statusline=%<%f. Let's break that down: %< means "truncate here if there's too much text on the status line," and %f means "display the current filename" (not the path, just the filename). If you try to use this you'll rapidly find that it's pretty limited. There are a lot of things missing, but the one that bothers me the most immediately is an indicator of whether or not the file is modified. So let's make this look somewhat more similar to the default status line: :set statusline=%<%f%m%=%l,%c%=%p%%. This starts the same, with the filename (potentially truncated), but we add a modified flag (%m) and divide the space into three equally spaced sections with two occurrences of %=. The next section is just %l,%c which is the line and column numbers. The final section is the percentage you've moved through the file (%p) and a percentage sign after it (%%). It looks approximately like this:

tmp.txt[+]                         3,1                          75%

One of the more popular questions seems to be how to change the colour of the status line (or part of it, which is trickier) on entering and leaving INSERT mode. Try this (again, starting from no configuration at all):

set statusline=%<%f%m%=%l,%c%=%p%%`
au InsertEnter * hi StatusLine term=reverse ctermfg=51 ctermbg=16
au InsertLeave * hi StatusLine term=reverse ctermfg=226 ctermbg=16

(This code can be found many, many places on the Internet: the colours above were my choice - similar to Airline - but the code is ... everywhere.) This will turn the status bar cyan when you enter INSERT mode, and turn it yellow when you return to NORMAL mode. (Caveat: I'm only setting ctermfg and ctermbg which work fine in command line Vim - but almost certainly won't work in a GUI version of Vim ... investigate guifg and guibg).

This is only the beginning of what can be done with the status line: it can display different colours in different sections, and the ability to show the contents of variables or the output of functions makes the possibilities infinite.

Warning

My first suggestion as someone who is just starting on this journey myself: remember that if you're loading the output of a function into the status line ... that function is called every time the cursor moves. Imagine scrolling the screen: the function you put in the status line is being called 20-50 times a second. Slow-responding functions can make Vim itself sluggish.