summaryrefslogtreecommitdiffstats
path: root/.config/nvim/plugin/50-tabline.lua
blob: b2f2488c4d2f5656016e0c9b0feba12e1140e78b (plain)
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("TabRenameFileName", function()
	vim.t.tabname = vim.fn.expand("%:t:r")
	vim.cmd.redrawtabline()
end, { nargs = 0 })