function tabline#global() abort return s:labels() . s:fill() endfunction function s:labels() abort let labels = map(range(1, tabpagenr('$')), 's:label(v:val)') return join(labels, '') endfunction function s:label(tabnr) abort let activity = a:tabnr == tabpagenr() ? 'active' : 'inactive' return s:label_{activity}(a:tabnr) endfunction let s:padding_0 = ' ' let s:padding_1 = ' @ ' let s:minwidth = 16 let s:maxwidth = 16 function s:label_active(tabnr) abort let bufnr = s:currentbufnr(a:tabnr) let l = '' let l .= '%#TabLineSel#' let l .= '%' . a:tabnr . 'T' let l .= s:padding_0 let l .= s:bufname(bufnr) ->s:center(s:minwidth) ->s:truncate(s:maxwidth) ->s:escape() let l .= '%#TabLineSelMod#' let l .= s:padding_{getbufvar(bufnr, '&modified')} return l endfunction function s:label_inactive(tabnr) abort let l = '' let l .= '%#TabLine#' let l .= '%' . a:tabnr . 'T' let l .= s:padding_0 let l .= s:bufname(s:currentbufnr(a:tabnr)) ->s:center(s:minwidth) ->s:truncate(s:maxwidth) ->s:escape() let l .= s:padding_0 return l endfunction function s:fill() abort let f = '' let f .= '%#TabLineFill#' let f .= '%T' let f .= '%=' let f .= ' ' let f .= s:gitinfo() ->s:escape() let f .= ' ' return f endfunction function s:currentbufnr(tabnr) abort return tabpagebuflist(a:tabnr)[tabpagewinnr(a:tabnr) - 1] endfunction function s:bufname(bufnr) abort let bufinfo = getbufinfo(a:bufnr)[0] if !empty(bufinfo.name) let trimmed = trim(bufinfo.name, '/', 2) return empty(trimmed) ? bufinfo.name : fnamemodify(trimmed, ':t') endif let wininfo = getwininfo(bufinfo.windows[0])[0] if wininfo.quickfix return wininfo.loclist ? '[Location List]' : '[Quickfix List]' endif let buftype = getbufvar(a:bufnr, '&buftype') if index(['nofile', 'acwrite', 'terminal'], buftype) >= 0 return '[Scratch]' elseif buftype is# 'prompt' return '[Prompt]' elseif buftype is# 'popup' return '[Popup]' endif return '[No Name]' endfunction function s:gitinfo() abort let info = [ \ 'gina#component#repo#preset()', \ 'gina#component#status#preset()', \ 'gina#component#traffic#preset()', \] call map(info, 'trim(s:safe(v:val))') call filter(info, '!empty(v:val)') return join(info, ' ') endfunction function s:safe(expr) abort try return eval(a:expr) catch return 'error' endtry endfunction function s:center(string, minwidth) let strwidth = strwidth(a:string) if a:minwidth <= strwidth return a:string endif let left = (a:minwidth - strwidth) / 2 let right = a:minwidth - (left + strwidth) return repeat(' ', left) . a:string . repeat(' ', right) endfunction function s:truncate(string, maxwidth, symbol = '>') if strwidth(a:string) <= a:maxwidth return a:string endif return printf('%.*S%s', a:maxwidth - strwidth(a:symbol), a:string, a:symbol) endfunction function s:escape(string) abort return substitute(a:string, '%', '%%', 'g') endfunction