13

Lets say I opened file1.txt, file2.txt, file3a.txt and file3b.txt such that the tabline (the thing on the top) looks like this:

file1.txt  file2.txt  2 file3a.txt

(Note how file3b.txt. is missing because it is shown in a split, in the same tab as file3a.txt)

To move more quickly between tabs (with <Number>gt), I would like each tab to display its index, along the filename. Like so:

1:<file1.txt>  2:<file2.txt>  3:<2 file3a.txt>

The formatting (the angle braces in particular) are optional; I just want the index to appear there (the 1:, 2: and so on).

No clues on :h tab-page-commands or google whatsoever.

1
  • 1
    Update: This plugin might be helpful. I think it was created much after this question was answered so it does not appear in any of the answers. Aug 31, 2015 at 20:53

5 Answers 5

1

You need to look at:

:help 'tabline'
:help setting-tabline

And if you have "e" in your 'guioptions' setting:

:help 'guitablabel'
5
  • That got me on the right track. Thanks a lot!
    – bitmask
    Sep 3, 2011 at 1:22
  • 16
    @bitmask could your perhaps provide your solution? Heptite, could you amend your answer?
    – wmarbut
    Sep 10, 2012 at 18:33
  • @wmarbut use this plugin, it's wonderful.
    – ospider
    Dec 16, 2018 at 14:21
  • 2
    Agreed. Extremely disappointing when solution is apparently "found" but not provided and everyone has to spend the same amount of time digging through docs and writing the same configs.
    – Alex
    Feb 28, 2019 at 1:42
  • Everybody for himslef!
    – 71GA
    Jan 28, 2021 at 10:37
13

put this in your vimrc

" Rename tabs to show tab number.
" (Based on http://stackoverflow.com/questions/5927952/whats-implementation-of-vims-default-tabline-function)
if exists("+showtabline")
    function! MyTabLine()
        let s = ''
        let wn = ''
        let t = tabpagenr()
        let i = 1
        while i <= tabpagenr('$')
            let buflist = tabpagebuflist(i)
            let winnr = tabpagewinnr(i)
            let s .= '%' . i . 'T'
            let s .= (i == t ? '%1*' : '%2*')
            let s .= ' '
            let wn = tabpagewinnr(i,'$')

            let s .= '%#TabNum#'
            let s .= i
            " let s .= '%*'
            let s .= (i == t ? '%#TabLineSel#' : '%#TabLine#')
            let bufnr = buflist[winnr - 1]
            let file = bufname(bufnr)
            let buftype = getbufvar(bufnr, 'buftype')
            if buftype == 'nofile'
                if file =~ '\/.'
                    let file = substitute(file, '.*\/\ze.', '', '')
                endif
            else
                let file = fnamemodify(file, ':p:t')
            endif
            if file == ''
                let file = '[No Name]'
            endif
            let s .= ' ' . file . ' '
            let i = i + 1
        endwhile
        let s .= '%T%#TabLineFill#%='
        let s .= (tabpagenr('$') > 1 ? '%999XX' : 'X')
        return s
    endfunction
    set stal=2
    set tabline=%!MyTabLine()
    set showtabline=1
    highlight link TabNum Special
endif
2
  • 3
    Do you know what '%999XX' means here?
    – Bach
    Apr 16, 2014 at 13:25
  • 1
    Since this one works for both terminal and gvim, I think its the best solution. Take my upvote, sir.
    – imolit
    Feb 13, 2015 at 15:39
7

On the wikia page you may find at least two (the ones I tested) which give you the tab indices, and one of them produces the number of windows inside each buffer which have edits.

Here is the result of my modifications on the one that produces the count of edited buffers, the change I made was to make the highlight value of the count consistent with the rest of the tab:

enter image description here

set showtabline=1  " 1 to show tabline only when more than one tab is present
set tabline=%!MyTabLine()  " custom tab pages line
function! MyTabLine() " acclamation to avoid conflict
    let s = '' " complete tabline goes here
    " loop through each tab page
    for t in range(tabpagenr('$'))
        " set highlight
        if t + 1 == tabpagenr()
            let s .= '%#TabLineSel#'
        else
            let s .= '%#TabLine#'
        endif
        " set the tab page number (for mouse clicks)
        let s .= '%' . (t + 1) . 'T'
        let s .= ' '
        " set page number string
        let s .= t + 1 . ' '
        " get buffer names and statuses
        let n = ''      " temp string for buffer names while we loop and check buftype
        let m = 0       " &modified counter
        let bc = len(tabpagebuflist(t + 1))     " counter to avoid last ' '
        " loop through each buffer in a tab
        for b in tabpagebuflist(t + 1)
            " buffer types: quickfix gets a [Q], help gets [H]{base fname}
            " others get 1dir/2dir/3dir/fname shortened to 1/2/3/fname
            if getbufvar( b, "&buftype"  ) == 'help'
                let n .= '[H]' . fnamemodify( bufname(b), ':t:s/.txt$//'  )
            elseif getbufvar( b, "&buftype"  ) == 'quickfix'
                let n .= '[Q]'
            else
                let n .= pathshorten(bufname(b))
            endif
            " check and ++ tab's &modified count
            if getbufvar( b, "&modified"  )
                let m += 1
            endif
            " no final ' ' added...formatting looks better done later
            if bc > 1
                let n .= ' '
            endif
            let bc -= 1
        endfor
        " add modified label [n+] where n pages in tab are modified
        if m > 0
            let s .= '[' . m . '+]'
        endif
        " select the highlighting for the buffer names
        " my default highlighting only underlines the active tab
        " buffer names.
        if t + 1 == tabpagenr()
            let s .= '%#TabLineSel#'
        else
            let s .= '%#TabLine#'
        endif
        " add buffer names
        if n == ''
            let s.= '[New]'
        else
            let s .= n
        endif
        " switch to no underlining and add final space to buffer list
        let s .= ' '
    endfor
    " 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 .= '%=%#TabLineFill#%999Xclose'
    endif
    return s
endfunction"
2
  • Your script is better than the other one since it retains the part where the tab shows if the file has been edited. Thanks! Jan 29, 2015 at 11:01
  • Yeah, I've been using the tabline from the airline plugin, but to be honest, this old tabline that I came up with is a lot more functional...
    – Steven Lu
    Jan 29, 2015 at 17:14
6

The tabline plugin is a vim plugin that implements requested functionality and won't blow out your vimrc. Simply install, and restart vim.

To install:

cd /usr/share/vim/vimfiles/plugin/
wget https://raw.githubusercontent.com/mkitt/tabline.vim/master/plugin/tabline.vim

or use a plugin manager.

1
  • 1
    Welcome to Super User! Please read How to recommend software for minimum required information and suggestions on how to recommend software on Super User. To keep your answer useful even if the provided link(s) breaks these details should be edited into your answer. Apr 26, 2017 at 11:25
1

For GUI-based Vim (Gvim on Linux, MacVim on Mac, etc), put this in your .gvimrc:

set guitablabel=%N:%M%t " Show tab numbers

Some tips on actually using the displayed numbers:

  • Ngt will switch to tab N. For example, 3gt goes to tab 3.
  • :tabm2 moves the current tab to appear after tab 2.
    • To move this tab to the first position, use :tabm0
    • To move this tab to the last position, just use :tabm

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .