-- See `:help stl-%!` vim.o.tabline = "%!v:lua.GetTabLine()" local function set_wincount_hl() -- `link = false` resolves link chains so `.fg`/`.bg` hold actual colors local title = vim.api.nvim_get_hl(0, { name = "Title", link = false }) local tabline = vim.api.nvim_get_hl(0, { name = "TabLine", link = false }) local tablinesel = vim.api.nvim_get_hl(0, { name = "TabLineSel", link = false }) vim.api.nvim_set_hl(0, "dotfiles.TabLineSelIcon", { fg = tabline.fg, bg = tablinesel.bg, bold = true }) vim.api.nvim_set_hl(0, "dotfiles.TabLineWinCount", { fg = title.fg, bg = tabline.bg, bold = true, italic = true }) vim.api.nvim_set_hl( 0, "dotfiles.TabLineSelWinCount", { fg = title.fg, bg = tablinesel.bg, bold = true, italic = true } ) end set_wincount_hl() vim.api.nvim_create_autocmd("ColorScheme", { desc = "Refresh tabline highlights", group = vim.g.dotfiles.augroup, callback = set_wincount_hl, }) -- Returns a string compatible with the 'tabline' option, used to set the tabline labels -- See `:help 'statusline'` function GetTabLine() local s = "" for _, id in pairs(vim.api.nvim_list_tabpages()) do local wins = vim.api.nvim_tabpage_list_wins(id) local is_modified = false for _, win in ipairs(wins) do if vim.bo[vim.api.nvim_win_get_buf(win)].modified then is_modified = true break end end local is_current = id == vim.api.nvim_get_current_tabpage() s = s .. "%" .. vim.api.nvim_tabpage_get_number(id) .. "T" local selected_label, modified_label = "▶ ", "[+] " local win_info = ( is_current and "%#dotfiles.TabLineSelIcon# " .. selected_label or "%#dotfiles.TabLineWinCount# " ) .. (is_current and "%#dotfiles.TabLineSelWinCount#" or "%#dotfiles.TabLineWinCount#") .. (#wins >= 10 and ">9" or tostring(#wins)) .. (is_modified and modified_label or " ") local win_info_display_width = 1 -- leading space + (is_current and vim.fn.strdisplaywidth(selected_label) or 0) + (#wins >= 10 and 2 or 1) + (is_modified and vim.fn.strdisplaywidth(modified_label) or 1) s = s .. win_info local total_width = 30 local label_width = total_width - win_info_display_width local name = vim.t[id].tabname name = ((name ~= nil and name ~= "") and name or tostring(id)) local display_width = vim.fn.strdisplaywidth(name) if display_width > label_width then name = vim.fn.strcharpart(name, 0, label_width - 1) .. "…" elseif display_width < label_width then name = name .. string.rep(" ", label_width - display_width) end s = s .. (is_current and "%#TabLineSel#" or "%#TabLine#") .. name end return s .. "%#TabLineFill#" end vim.api.nvim_create_user_command("TabRename", function(opts) vim.t.tabname = opts.args vim.cmd.redrawtabline() end, { nargs = 1 }) vim.api.nvim_create_user_command("TabRenameFileName", function() vim.t.tabname = vim.fn.expand("%:t:r") vim.cmd.redrawtabline() end, { nargs = 0 })