-- Statusline nativa (reemplaza lualine.nvim), con la paleta de config.native-colorscheme. local M = {} local colors = require("config.native-colorscheme").colors local mode_names = { n = "NORMAL", no = "O-PENDING", nt = "NORMAL", v = "VISUAL", V = "V-LINE", ["\22"] = "V-BLOCK", s = "SELECT", S = "S-LINE", ["\19"] = "S-BLOCK", i = "INSERT", R = "REPLACE", Rv = "V-REPLACE", c = "COMMAND", cv = "EX", r = "PROMPT", ["r?"] = "CONFIRM", ["!"] = "SHELL", t = "TERMINAL", } local mode_hl = { n = "StlModeNormal", i = "StlModeInsert", v = "StlModeVisual", V = "StlModeVisual", ["\22"] = "StlModeVisual", s = "StlModeVisual", S = "StlModeVisual", c = "StlModeCommand", R = "StlModeReplace", r = "StlModeReplace", t = "StlModeTerminal", ["!"] = "StlModeTerminal", } function M.set_highlights() local hl = function(name, fg, bg, bold) vim.api.nvim_set_hl(0, name, { fg = fg, bg = bg, bold = bold ~= false }) end hl("StlModeIcon", colors.base4, colors.base03) hl("StlModeNormal", colors.blue100, colors.base03) hl("StlModeInsert", colors.green100, colors.base03) hl("StlModeVisual", colors.magenta100, colors.base03) hl("StlModeCommand", colors.yellow100, colors.base03) hl("StlModeReplace", colors.red100, colors.base03) hl("StlModeTerminal", colors.orange100, colors.base03) hl("StlBranch", colors.orange100, colors.base03) hl("StlDiffAdd", colors.green300, colors.base03) hl("StlDiffChange", colors.yellow300, colors.base03) hl("StlDiffDelete", colors.red300, colors.base03) hl("StlFile", colors.yellow100, colors.base03) hl("StlDiagError", colors.red300, colors.base03) hl("StlDiagWarn", colors.yellow300, colors.base03) hl("StlDiagInfo", colors.blue300, colors.base03) hl("StlDiagHint", colors.cyan300, colors.base03) hl("StlUpdates", colors.orange300, colors.bg_statusline, false) hl("StlLsp", colors.base4, colors.base03) hl("StlFt", colors.magenta100, colors.base03) hl("StlProgress", colors.cyan100, colors.base03) hl("StlSep", colors.base00, colors.base03, false) hl("StlBg", colors.fg, colors.bg_statusline, false) end -- Handlers de click (:h 'statusline' %@); globales porque %@ necesita un nombre simple. function _G.StlClickFile() Snacks.picker.files() end function _G.StlClickDiag() Snacks.picker.diagnostics() end local function filename() local name = vim.api.nvim_buf_get_name(0) if name == "" then return "[Sin nombre]" end local file = vim.fn.fnamemodify(name, ":t") local parent = vim.fn.fnamemodify(name, ":h:t") return parent .. "/" .. file end local function git() local out = {} -- vim.b para el repo del buffer; vim.g como fallback (repo del cwd, ej. en oil) local head = vim.b.gitsigns_head or vim.g.gitsigns_head if head and head ~= "" then out[#out + 1] = "%#StlBranch# " .. head end local status = vim.b.gitsigns_status_dict if status then if (status.added or 0) > 0 then out[#out + 1] = "%#StlDiffAdd# " .. status.added end if (status.changed or 0) > 0 then out[#out + 1] = "%#StlDiffChange# " .. status.changed end if (status.removed or 0) > 0 then out[#out + 1] = "%#StlDiffDelete# " .. status.removed end end if #out == 0 then return "" end return table.concat(out) end local diag_specs = { { vim.diagnostic.severity.ERROR, "StlDiagError", " " }, { vim.diagnostic.severity.WARN, "StlDiagWarn", " " }, { vim.diagnostic.severity.INFO, "StlDiagInfo", " " }, { vim.diagnostic.severity.HINT, "StlDiagHint", "󰠠 " }, } local function diagnostics() local counts = vim.diagnostic.count(0) local parts = {} for _, spec in ipairs(diag_specs) do local n = counts[spec[1]] if n and n > 0 then parts[#parts + 1] = "%#" .. spec[2] .. "#" .. spec[3] .. n end end if #parts == 0 then return "" end return "%@v:lua.StlClickDiag@" .. table.concat(parts, " ") .. "%X " end local function lsp_clients() local clients = vim.lsp.get_clients { bufnr = 0 } if #clients == 0 then return "No LSP" end local names = {} for _, client in ipairs(clients) do names[#names + 1] = client.name end return table.concat(names, ",") end local function lazy_updates() local ok, status = pcall(require, "lazy.status") if ok and status.has_updates() then return "%#StlUpdates#" .. status.updates() .. " " end return "" end local function filetype() local ft = vim.bo.filetype if ft == "" then return "" end local ok, mini = pcall(require, "mini.icons") if ok then local ok_get, icon, icon_hl = pcall(mini.get, "filetype", ft) if ok_get and icon then return "%#" .. icon_hl .. "#" .. icon .. " %#StlFt#" .. ft .. " " end end return "%#StlFt#" .. ft .. " " end -- Como el componente 'progress' de lualine: Top / Bot / porcentaje local function progress() local cur = vim.fn.line "." local total = vim.fn.line "$" if cur == 1 then return "Top" elseif cur == total then return "Bot" end return string.format("%2d%%%%", math.floor(cur / total * 100)) end function M.render() local mode = vim.api.nvim_get_mode().mode local hl = mode_hl[mode:sub(1, 1)] or "StlModeNormal" local name = mode_names[mode] or mode_names[mode:sub(1, 1)] or mode local left = vim.tbl_filter(function(s) return s ~= "" end, { "%#StlModeIcon# %#" .. hl .. "#" .. name, git(), "%#StlFile#%@v:lua.StlClickFile@ " .. filename() .. "%X", }) return table.concat(left, "%#StlSep# │ ") .. table.concat { " %#StlBg#%=", diagnostics(), lazy_updates(), "%#StlLsp#", lsp_clients(), " ", filetype(), "%#StlProgress#", progress(), " ", } end function M.setup() M.set_highlights() vim.api.nvim_create_autocmd("ColorScheme", { group = vim.api.nvim_create_augroup("native_statusline", { clear = true }), callback = M.set_highlights, }) vim.o.statusline = "%!v:lua.require'config.statusline'.render()" end return M