What is the right highlight group to use for a custom tabline?

14 views
Skip to first unread message

Nickolai Belakovski

unread,
Feb 7, 2024, 11:43:36 AM2/7/24
to vim_dev
Hello, and apologies if this isn't the right place to post this question but if it isn't I hope you'll help me out and point me in the right direction.

I'm trying to make a custom tabline. I want the tabline to display "M", "A", etc when a file's git status is modified, added, etc., but that part isn't the focus of my question.

I'm trying to replicate the existing tabline functionality and I notice that if a tab has 3 windows, the number 3 will be displayed before the name of the file in the active window. I've nearly got that replicated But I'm using the "#Title#" highlight group and it's not quite working. The background color doesn't change correctly as compared to the original. Should I make a custom highlight group here? I might publish this and I'd like to find a solution that works with multiple color schemes instead of just hardcoding my own thing.

Below is the relevant section of my vimrc. You can replicate the issue as follows:
1. Copy the below code into a custom .vimrc
2. Run vim with vim -u .vimrc
3. Make a new tab with :tabnew
4. Split the tab with :vs
5. Move back and forth between the tabs with gt in command mode
6. Use \t and \y to use the default tabline and the custom tabline respectively, and after setting this cycle through the tabs again and the issue will be clear.

Thanks for your time and attention,
Nickolai
Reproducible .vimrc:
vim9script
runtime defaults.vim  # Maintain the default behavior of remembering cursor position


def g:MyTabLabel(n: number): string
        var buflist = tabpagebuflist(n)
        var winnr = tabpagewinnr(n)
        var buffer_name = bufname(buflist[winnr - 1])
        var name = "[No Name]"
        if buffer_name != ""
          name = fnamemodify(buffer_name, ':~:.')
        endif
        var gst = split(system('git status --porcelain=v1 ' .. name))
        if len(gst) == 2
                if gst[0] == '??'
                        gst[0] = 'U'
                endif
          return name .. ' ' .. gst[0]
        endif
        return name
enddef


def g:MyTabLine(): string
   var s = ''
        for i in range(tabpagenr('$'))
                # select the highlighting
                var highlight_g = '%#TabLine#'
                if i + 1 == tabpagenr()
                        highlight_g = '%#TabLineSel#'
                endif
                s ..= highlight_g
                # set the tab page number (for mouse clicks)
                s ..= '%' .. (i + 1) .. 'T'

                # Put the number of windows in this tab
                var num_windows = tabpagewinnr(i + 1, '$')
                if num_windows > 1
                        s ..= '%#Title# ' .. num_windows .. '' .. highlight_g
                endif

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

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

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

        return s
enddef


set tabline=%!MyTabLine()

map <leader>t :set tabline=<CR>
map <leader>y :set tabline=%!MyTabLine()<CR>
map <leader>r :source .vimrc<CR>
Reply all
Reply to author
Forward
0 new messages