1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
|
-- 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("TabRenameToCurrentFileNameNoExt", function()
vim.t.tabname = vim.fn.expand("%:t:r")
vim.cmd.redrawtabline()
end, { nargs = 0 })
|