Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to write `tabline` function in vim?

Tags:

vim

I would like tabs in Vim (not the gVim) look as follows:

enter image description here

Explanation:

  1. Sequence number of tab (1, 2, 3, 4 etc)
  2. Name of file (no path, no shortened path)
  3. If there are more than one file opened, list them in a tab.
  4. If there are duplicate tabs (hence the same file opened in several tabs) they should be highlighted.
  5. If buffer is modified add + at the end of filename.

Could anybody help? I want to have something like this within my .vimrc:

set tabline=%!MyTabLine()
function! MyTabLine()
  ...
endfunction
like image 710
Timur Fayzrakhmanov Avatar asked Aug 25 '26 05:08

Timur Fayzrakhmanov


1 Answers

I've already wrote my desired tabline function. The behaviour is almost the same, except:

  1. the + sign appears after tab number if any of buffer inside the tab is modified
  2. tab contains only modifiable buffers (it don't clog the line with buffers of netrw file browser, help and read-only ones), but you can change this, just uncomment the desired lines

enter image description here

Here is the code:

set tabline=%!MyTabLine()  " custom tab pages line
function! MyTabLine()
  let s = ''
  " loop through each tab page
  for i in range(tabpagenr('$'))
    if i + 1 == tabpagenr()
      let s .= '%#TabLineSel#'
    else
      let s .= '%#TabLine#'
    endif
    if i + 1 == tabpagenr()
      let s .= '%#TabLineSel#' " WildMenu
    else
      let s .= '%#Title#'
    endif
    " set the tab page number (for mouse clicks)
    let s .= '%' . (i + 1) . 'T '
    " set page number string
    let s .= i + 1 . ''
    " get buffer names and statuses
    let n = ''  " temp str for buf names
    let m = 0   " &modified counter
    let buflist = tabpagebuflist(i + 1)
    " loop through each buffer in a tab
    for b in buflist
      if getbufvar(b, "&buftype") == 'help'
        " let n .= '[H]' . fnamemodify(bufname(b), ':t:s/.txt$//')
      elseif getbufvar(b, "&buftype") == 'quickfix'
        " let n .= '[Q]'
      elseif getbufvar(b, "&modifiable")
        let n .= fnamemodify(bufname(b), ':t') . ', ' " pathshorten(bufname(b))
      endif
      if getbufvar(b, "&modified")
        let m += 1
      endif
    endfor
    " let n .= fnamemodify(bufname(buflist[tabpagewinnr(i + 1) - 1]), ':t')
    let n = substitute(n, ', $', '', '')
    " add modified label
    if m > 0
      let s .= '+'
      " let s .= '[' . m . '+]'
    endif
    if i + 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
    let s .= ' '
  endfor
  let s .= '%#TabLineFill#%T'
  " right-aligned close button
  " if tabpagenr('$') > 1
  "   let s .= '%=%#TabLineFill#%999Xclose'
  " endif
  return s
endfunction
like image 88
Timur Fayzrakhmanov Avatar answered Aug 26 '26 23:08

Timur Fayzrakhmanov



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!