3

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

Shuzheng
  • 1,235
  • 8
  • 21

3 Answers3

5

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".

Matt
  • 20,685
  • 1
  • 11
  • 24
4

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?'\ !!':''}
Andrew Ho-Lee
  • 1,210
  • 5
  • 11
  • How often is that conditional evaluated? I mean after which actions will the statusline be updated to reflect the current state? – Shuzheng Feb 05 '21 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. – Andrew Ho-Lee Feb 05 '21 at 23:33
4

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]%)...
D. Ben Knoble
  • 26,070
  • 3
  • 29
  • 65
  • 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 05 '21 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 05 '21 at 19:35