summaryrefslogtreecommitdiffstats
path: root/plugin/50-tabline.lua
diff options
context:
space:
mode:
authorThomas Vanbesien <tvanbesi@proton.me>2026-05-18 19:42:15 +0200
committerThomas Vanbesien <tvanbesi@proton.me>2026-05-18 21:40:58 +0200
commit166b87eef2cf12e50335f01de5aad1dce14ea724 (patch)
tree5b0b19bdf2718ddda43fc41f3cabb14049a9396e /plugin/50-tabline.lua
parent78b8dd64acbd270d9f2d3f4b9f9ab86358da363f (diff)
downloadnvim-config-166b87eef2cf12e50335f01de5aad1dce14ea724.tar.gz
nvim-config-166b87eef2cf12e50335f01de5aad1dce14ea724.zip
feat(nvim): add custom tabline plugin
Diffstat (limited to 'plugin/50-tabline.lua')
-rw-r--r--plugin/50-tabline.lua72
1 files changed, 72 insertions, 0 deletions
diff --git a/plugin/50-tabline.lua b/plugin/50-tabline.lua
new file mode 100644
index 0000000..8628bb2
--- /dev/null
+++ b/plugin/50-tabline.lua
@@ -0,0 +1,72 @@
+-- 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 .. "%" .. 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[vim.api.nvim_tabpage_get_number(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 })