25

I read about how to update the vim statusline here. And I am able to update it successfully.

But, I would like to retain the format of default vim statusline and just add some more info to it e.g. file-size, file-type, etc.

Vim default status line is:

 <file-name> line_num,col_num %file 

How could I do the following?

  1. I would like to add info after the file-name
  2. Display the current format of statusline (:set statusline displays nothing)

I tried:

set statusline+=%y 

But this overwrites the entire statusline and just displays the file-type (%y).

Any hints?

1
  • 2
    If you're interested in Vim, do checkout Vi and Vim! Commented Aug 22, 2015 at 12:44

3 Answers 3

21

Like @muru said, it doesn't seem to possible to exactly simulate the default status line when statusline is set as the code for rendering it does things that can't be specified in the statusline setting. It is possible to get pretty close, however. Here is a reasonable approximation of the way the default status line looks when ruler is enabled:

:set statusline=%<%f\ %h%w%m%r%=%-14.(%l,%c%V%)\ %P 

The main difference is the positioning of the line and column numbers. This also displays [-] in unmodifiable buffers. If it's possible to simulate the default spacing logic, I haven't been able to figure out a way to do it. Perhaps this will be close enough for your purposes.

This is very similar to an attempt to emulate the default statusline in :help statusline, though the version there is missing the preview flag.

I use a split version of this in my own .vimrc to place Syntastic status line info in the middle of what looks like a normal vim status line with ruler:

" start of default statusline set statusline=%f\ %h%w%m%r\ " NOTE: preceding line has a trailing space character " Syntastic statusline set statusline+=%#warningmsg# set statusline+=%{SyntasticStatuslineFlag()} set statusline+=%* " end of default statusline (with ruler) set statusline+=%=%(%l,%c%V\ %=\ %P%) 
11

tl;dr

:set statusline=%f\ %h%w%m%r%=%-14.(%l,%c%V%)\ %P 

Although my suggested solution doesn't differ much from that of the other answers, I'd like to share a more detailed explanation.

original behavior

First, let's figure out how vim draws the status line. The functions responsible are win_redr_status() and win_redr_ruler().

vim takes the buffer name, adds a space if there are any flags to follow (like [Help], [Preview], [+], [RO]). Then it adds the flags.

Normally it allocates 18 character cells for the ruler. If the buffer name part doesn't fit the rest of the available space vim truncates it from the left and adds < at the beginning.

If there's room for keymap, it adds it at the end (right aligned).

Now, the ruler. It consists of <row>,<col>-<virtcol> part and relative position (right aligned).

There's also a restriction that the part with the buffer name must take at least half of the width.

solution

Now let's take the value suggested by the docs:

:set statusline=%<%f\ %h%m%r%=%-14.(%l,%c%V%)\ %P 

where

%< - where to truncate the line if too long %f - buffer name (path to a file, or something) %h - help flag %m - modified flag %r - readonly flag %= - separater between the left (buffer name) and the right (ruler) parts %-14.(...%) - minimum field width == 14 %l - line %c - column %V - virtual column %P - percentage 

So, first %< can be omitted, since by default buffer name is truncated at the beginning. Then, it's missing the preview flag (%w). Also, when the window is less than 18 * 2 characters wide, the right part takes more than half of the status line.

So, at least we can omit %< and add %w:

:set statusline=%f\ %h%w%m%r%=%-14.(%l,%c%V%)\ %P 

We can go further and make sure the right part doesn't take more than half of the status line:

set statusline=%!MyStatusLine() function! MyStatusLine() let l:w = min([14,winwidth(0)/2-3]) return '%f %h%w%m%r%=%-' . l:w . '.(%l,%c%V%) %P' endfunction 

Then we can make it depend on the features vim was compiled with.

if has("quickfix") ... endif 

But I'd say that that is not practical, and the previous solution would suffice for most intents and purposes. However, if the last solution doesn't work for you, tell me what's wrong, and I'll try to come up with a better one.


The problem with the solution suggested by Laurence Gonsalves is that if there are no flags, there are two spaces between the left and the right parts:

:set statusline=%f\ %h%w%m%r\ %=%(%l,%c%V\ %=\ %P%) 
9

The code doesn't set any value to an empty status string, but simply acts using some defaults. See src/screen.c, function win_redr_status(). The items shown are based on features compiled in, therefore to reconstruct the exact statusline one would need to look at the features compiled in. It might be simpler to use the example statusline given in :h statusline:

Examples: Emulate standard status line with 'ruler' set :set statusline=%<%f\ %h%m%r%=%-14.(%l,%c%V%)\ %P 
2
  • What does the dot symbol (.) after the width (14) mean in %-14.(%l,%c%V%)? Commented Jan 26, 2018 at 12:21
  • 1
    The help (:h statusline) says: Each status line item is of the form: %-0{minwid}.{maxwid}{item}. Commented Apr 22, 2022 at 12:08

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.