Consider the following statusline that makes use of %r to display [RO], when readonly has been set.

The problem is that when readonly is not set, two spaces occur between %f (file path) and %y (file type). The problem is even worse, if I have several items, that may sometimes not be shown, separated by spaces.

Is there a way to completely remove an item from the statusline, when it's not shown, so that associated whitespace isn't shown?

set laststatus=2
set showcmd
set showmode

set statusline=%f
set statusline+=\ %r
set statusline+=\ %y

Yes, it's parentheses (aka "item group"). Sort of

let &statusline = '%f%( %r%)%( %y%)'

Some time ago I also wrote a plugin (actually a function) to assist in building status line expression from simple "blocks".


An alternative is to wrap more things in square-brackets, obviating the need for spaces (a modified version of what I start with):

let &statusline = '%([%f]%)%(%m%r%w%h%)%(%y%)'

Not all of the grouping is necessary, but I actually break my statusline out over multiple lines in my vimrc, so I just group everything. And there's this from :help statusline:

    When all items in a group becomes an empty string (i.e. flags that are
    not set) and a minwid is not set for the group, the whole group will
    become empty.  This will make a group like the following disappear
    completely from the statusline when none of the flags are set. >
        :set statusline=...%(\ [%M%R%H]%)...
  • I see. What are the square brackets used for? @Matt talks about item groups without the use of square brackets. And why does your example use %(\ ... for creating a space, when @Matt’s example doesn’t?
    – Shuzheng
    Feb 5 at 18:31
  • I use the square brackets literally for separating things visually (I also use colors, but that’s a separate deal). We both use parentheses for item groups. There is a difference between set and let; set requires spaces to be escaped, which I find annoying (hence let).
    – D. Ben Knoble
    Feb 5 at 19:35

Another option is to use a conditional:

set statusline+=%{&readonly?'\ [RO]':''}

This allows you to also change what is shown. For example, I have:

set statusline+=%{&readonly?'\ !!':''}
  • How often is that conditional evaluated? I mean after which actions will the statusline be updated to reflect the current state?
    – Shuzheng
    Feb 5 at 18:23
  • I believe it’s after every key press. It’s certainly often enough for this use case. For example, I also have the current mode and line / column number displayed in mine which updates in real time. Feb 5 at 23:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.