vimtricks.wiki Concise Vim tricks, one at a time.

How do I add custom functions to Vim's statusline for dynamic information?

Answer

set statusline=%{MyCustomFunc()}

Explanation

How it works

Vim's statusline supports the %{expr} syntax which evaluates a Vimscript expression and displays the result. This lets you write custom functions that display dynamic information in your statusline.

The %{expression} item calls any Vimscript expression and inserts its return value. You can call built-in functions, your own custom functions, or even inline expressions.

Built-in expressions you can embed:

  • %{&filetype} - Current file type
  • %{&encoding} - File encoding
  • %{&fileformat} - File format (unix/dos/mac)
  • %{mode()} - Current mode (n, i, v, etc.)
  • %{wordcount().words} - Word count of the file
  • %{strftime('%H:%M')} - Current time

Custom functions let you compute anything:

function! GitBranch()
    let l:branch = system("git -C " . expand('%:p:h') . " rev-parse --abbrev-ref HEAD 2>/dev/null | tr -d '\n'")
    return strlen(l:branch) > 0 ? '[' . l:branch . ']' : ''
endfunction

function! ReadOnly()
    return &readonly ? '[RO]' : ''
endfunction

Note: Functions called from the statusline run frequently (on every screen update), so they should be fast. Avoid slow shell commands in the statusline function.

Example

Add to your ~/.vimrc:

function! CurrentMode()
    let l:modes = {'n': 'NORMAL', 'i': 'INSERT', 'v': 'VISUAL', 'V': 'V-LINE', "\<C-v>": 'V-BLOCK', 'R': 'REPLACE', 'c': 'COMMAND'}
    return get(l:modes, mode(), mode())
endfunction

set laststatus=2
set statusline=
set statusline+=\ %{CurrentMode()}
 set statusline+=\ %f
set statusline+=\ %m%r
set statusline+=%=
set statusline+=\ %{&filetype}
set statusline+=\ %l:%c
set statusline+=\ %p%%

This produces a statusline like: NORMAL main.py [+] python 42:10 65% with dynamic mode display, all without plugins.

Next

How do you yank a single word into a named register?