Context: I tend to use tabs to contain splits of files that are grouped around some purpose (e.g. in a typical MVC framework, I'll have the model/view/controller files for a given part of the app open in splits under the same tab). Since these groups tend to use the same filenames across different parts of my codebases (like views.py, or main.yml), the tab names are useless - I have to switch through the tabs and examine the file contents or full paths to see what they actually contain.

Is there a way I could either make the tab titles more useful in these situations automatically, or a way to manually change the tab title? I'm flexible in how exactly this would be done since I imagine it's an esoteric need.

  • 1
    I know that you could write your own custom function for the tab line, but maybe you will find useful using vim-ctrlspace plugin for that?
    – grodzik
    Oct 10, 2016 at 15:06
  • 1
    :help setting-tabline should help
    – Wolfie
    Oct 10, 2016 at 15:46
  • 4
    Actually this is an exact duplicate of superuser.com/questions/715928/… - that question has an answer pointing to a plugin that does exact what you want.
    – Wolfie
    Oct 10, 2016 at 15:47

1 Answer 1


You can use the 'tabline' setting for this. Here's an example adapted from :help setting-tabline:

set tabline=%!MyTabLine()

" Set the entire tabline
function! MyTabLine()
    let s = ''
    for i in range(tabpagenr('$'))
        " select the highlighting
        if i + 1 == tabpagenr()
            let s .= '%#TabLineSel#'
            let s .= '%#TabLine#'

        " set the tab page number (for mouse clicks)
        let s .= '%' . (i + 1) . 'T'

        " the label is made by MyTabLabel()
        let s .= ' %{MyTabLabel(' . (i + 1) . ')} '

    " after the last tab fill with TabLineFill and reset tab page nr
    let s .= '%#TabLineFill#%T'

    " right-align the label to close the current tab page
    if tabpagenr('$') > 1
        let s .= '%=%#TabLine#%999Xclose'

    return s

" Set the label for a single tab
function! MyTabLabel(n)

    " This is run in the scope of the active tab, so t:name
    " won't work.
    let l:tabname = gettabvar(a:n, 'name', '')

    " This variable exists!
    if l:tabname != ''
        return l:tabname

    " If it's not found fall back to the buffer name
    let buflist = tabpagebuflist(a:n)
    let winnr = tabpagewinnr(a:n)
    let l:bname = bufname(buflist[winnr - 1])

    " Unnamed buffer, scratch buffer, etc. Could be more detailed.
    if l:bname == ''
        let l:bname = '[No Name]'

    return l:bname

The key is in the MyTabLabel() function. If the tab-local t:name variable exists, we use that. Otherwise we default back to the currently active buffer name.

To name the tab label, simple set the t:name variable for that tab. For the currently active tab:

:let t:name = 'Session one'

or for a specific tab nr:

:call settabvar(3, 'name', 'Session four')

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.