local M = {} local modes = { n = { "NORMAL", "StatuslineModeNormal" }, i = { "INSERT", "StatuslineModeInsert" }, v = { "VISUAL", "StatuslineModeVisual" }, V = { "V-LINE", "StatuslineModeVisual" }, [""] = { "V-BLOCK", "StatuslineModeVisual" }, R = { "REPLACE", "StatuslineModeReplace" }, c = { "COMMAND", "StatuslineModeCommand" }, } local function mode() local m = vim.fn.mode() local entry = modes[m] or { m, "StatusLine" } return string.format("%%#%s# %s %%#StatusLine#", entry[2], entry[1]) end ---------------------------------------------------------------------- -- Git branch (buffer-lokal, gecached, kein redraw-spam) ---------------------------------------------------------------------- local function update_git_branch(bufnr) bufnr = bufnr or 0 -- nur in echten Dateien if vim.bo[bufnr].buftype ~= "" then vim.b[bufnr].git_branch = "" return end -- kein Git → nichts tun if vim.fn.executable("git") ~= 1 then vim.b[bufnr].git_branch = "" return end local branch = vim.fn.systemlist( "git rev-parse --abbrev-ref HEAD 2>/dev/null" )[1] if branch and branch ~= "" then vim.b[bufnr].git_branch = "  " .. branch .. " " else vim.b[bufnr].git_branch = "" end end ---------------------------------------------------------------------- -- Autocmd: Git nur bei Bedarf aktualisieren ---------------------------------------------------------------------- vim.api.nvim_create_autocmd( { "BufEnter", "FocusGained" }, { callback = function(args) update_git_branch(args.buf) end, } ) ---------------------------------------------------------------------- -- Statusline-Sektionen (reine Darstellung, keine IO) ---------------------------------------------------------------------- local function git() return vim.b.git_branch or "" end local function git_diff() local gsd = vim.b.gitsigns_status_dict if not gsd then return "" end local parts = {} if gsd.added and gsd.added > 0 then table.insert(parts, "+" .. gsd.added) end if gsd.changed and gsd.changed > 0 then table.insert(parts, "~" .. gsd.changed) end if gsd.removed and gsd.removed > 0 then table.insert(parts, "-" .. gsd.removed) end if #parts > 0 then return " " .. table.concat(parts, " ") .. " " end return "" end local function filename() local name = vim.fn.expand("%:t") if name == "" then name = "[No Name]" end if vim.bo.modified then name = name .. " [+]" end return " " .. name .. " " end local function treesitter() local ok = vim.treesitter.highlighter.active[vim.api.nvim_get_current_buf()] if ok then return " 🌳 " end return "" end local function diagnostics() local counts = { error = #vim.diagnostic.get(0, { severity = vim.diagnostic.severity.ERROR }), warn = #vim.diagnostic.get(0, { severity = vim.diagnostic.severity.WARN }), info = #vim.diagnostic.get(0, { severity = vim.diagnostic.severity.INFO }), hint = #vim.diagnostic.get(0, { severity = vim.diagnostic.severity.HINT }), } local parts = {} if counts.error > 0 then table.insert(parts, "  " .. counts.error) end if counts.warn > 0 then table.insert(parts, "  " .. counts.warn) end if counts.info > 0 then table.insert(parts, "  " .. counts.info) end if counts.hint > 0 then table.insert(parts, "  " .. counts.hint) end if #parts > 0 then return " " .. table.concat(parts, " ") .. " " end return "" end local function fileinfo() local ft = vim.bo.filetype ~= "" and vim.bo.filetype or "none" local enc = vim.bo.fileencoding ~= "" and vim.bo.fileencoding or vim.o.encoding return string.format(" %s %s ", ft, enc) end local function position() return string.format(" %d:%d ", vim.fn.line("."), vim.fn.col(".")) end ---------------------------------------------------------------------- -- Öffentliche Statusline-Funktion ---------------------------------------------------------------------- function M.statusline() return table.concat({ -- LEFT: Mode & Context mode(), "%#PmenuSel#", git(), git_diff(), "%#StatusLine#", filename(), "%=", -- RIGHT: Feedback & Meta diagnostics(), treesitter(), "%#StatusLineNC#", fileinfo(), " %p%% ", position(), }) end return M