12

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?

  • 2
    If you're interested in Vim, do checkout Vi and Vim! – muru Aug 22 '15 at 12:44
14

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\ %=%(%l,%c%V\ %=\ %P%)

The main difference is the positioning of the line and column numbers. 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.

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%)
7

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
  • What does the dot symbol (.) after the width (14) mean in %-14.(%l,%c%V%)? – Shamaoke Jan 26 '18 at 12:21
1

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%)

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.