local delegate = require "utils.delegate" local leap_active = false vim.api.nvim_create_autocmd("User", { pattern = "LeapEnter", callback = function() leap_active = true end, }) vim.api.nvim_create_autocmd("User", { pattern = "LeapLeave", callback = function() leap_active = false end, }) return { "nvim-lualine/lualine.nvim", event = "VeryLazy", init = function() local diagnostics = require "lualine.components.diagnostics" diagnostics.init = delegate(function(env, self, options) -- Run super() env.M.super.init(self, options) -- Apply default options env.modules.default_config.apply_default_colors(self.options) self.options = vim.tbl_deep_extend("keep", self.options or {}, env.modules.default_config.options) -- Apply default symbols self.symbols = vim.tbl_extend( "keep", self.options.symbols or {}, self.options.icons_enabled ~= false and env.modules.default_config.symbols.icons or env.modules.default_config.symbols.no_icons ) -- Initialize highlight groups if self.options.colored then self.highlight_groups = { error = self:create_hl(self.options.diagnostics_color.error, "error"), warn = self:create_hl(self.options.diagnostics_color.warn, "warn"), info = self:create_hl(self.options.diagnostics_color.info, "info"), hint = self:create_hl(self.options.diagnostics_color.hint, "hint"), } self.spacing_hl = self:create_hl("WinSeparator", "spacing") end -- Initialize variable to store last update so we can use it in insert -- mode for no update_in_insert self.last_diagnostics_count = {} -- Error out no source if #self.options.sources < 1 then env.modules.utils_notices.add_notice "### diagnostics.sources\n\nno sources for diagnostics configured.\nPlease specify which diagnostics source you want lualine to use with `sources` option.\n" end end, diagnostics.init) diagnostics.update_status = delegate(function(env, self) local bufnr = vim.api.nvim_get_current_buf() local diagnostics_count local result = {} if self.options.update_in_insert or vim.api.nvim_get_mode().mode:sub(1, 1) ~= "i" then local error_count, warning_count, info_count, hint_count = 0, 0, 0, 0 local diagnostic_data = env.modules.sources.get_diagnostics(self.options.sources) -- sum all the counts for _, data in pairs(diagnostic_data) do error_count = error_count + data.error warning_count = warning_count + data.warn info_count = info_count + data.info hint_count = hint_count + data.hint end diagnostics_count = { error = error_count, warn = warning_count, info = info_count, hint = hint_count, } -- Save count for insert mode self.last_diagnostics_count[bufnr] = diagnostics_count else -- Use cached count in insert mode with update_in_insert disabled diagnostics_count = self.last_diagnostics_count[bufnr] or { error = 0, warn = 0, info = 0, hint = 0 } end local always_visible = false if type(self.options.always_visible) == "boolean" then always_visible = self.options.always_visible elseif type(self.options.always_visible) == "function" then always_visible = self.options.always_visible() end -- format the counts with symbols and highlights if self.options.colored then local colors, bgs = {}, {} for name, hl in pairs(self.highlight_groups) do colors[name] = self:format_hl(hl) bgs[name] = env.modules.utils.extract_highlight_colors(colors[name]:match "%%#(.-)#", "bg") end local previous_section, padding for _, section in ipairs(self.options.sections) do if diagnostics_count[section] ~= nil and (always_visible or diagnostics_count[section] > 0) then padding = previous_section and (bgs[previous_section] ~= bgs[section]) and " " or "" previous_section = section table.insert( result, colors[section] .. padding .. self.symbols[section] .. diagnostics_count[section] ) end end else for _, section in ipairs(self.options.sections) do if diagnostics_count[section] ~= nil and (always_visible or diagnostics_count[section] > 0) then table.insert(result, self.symbols[section] .. diagnostics_count[section]) end end end return table.concat(result, self:format_hl(self.spacing_hl) .. "|") end, diagnostics.update_status) end, opts = { options = { section_separators = { left = "", right = "" }, component_separators = { left = "", right = "" }, fmt = function(str) return vim.trim(str) end, globalstatus = true, disabled_filetypes = { "NvimTree" }, }, sections = { lualine_a = { "mode", { function() return "[L]" end, cond = function() return leap_active end, }, { function() local reg = vim.fn.reg_recording() if reg == "" then return "" end -- not recording return "[@" .. reg .. "]" end, }, }, lualine_b = { "filename" }, lualine_c = { "branch", { function() return "[" end, cond = function() local count = vim.diagnostic.count(0) return type( count[vim.diagnostic.severity.ERROR] or count[vim.diagnostic.severity.WARN] or count[vim.diagnostic.severity.INFO] or count[vim.diagnostic.severity.HINT] ) ~= "nil" end, padding = { left = 1, right = 0 }, color = "WinSeparator", }, { "diagnostics", symbols = { error = "", warn = "", info = "", hint = "", }, padding = 0, }, { function() return "]" end, cond = function() local count = vim.diagnostic.count(0) return type( count[vim.diagnostic.severity.ERROR] or count[vim.diagnostic.severity.WARN] or count[vim.diagnostic.severity.INFO] or count[vim.diagnostic.severity.HINT] ) ~= "nil" end, padding = { left = 0, right = 1 }, color = "WinSeparator", }, }, lualine_x = { { function() local noice_loaded, noice = pcall(require, "noice") if noice_loaded then return noice.api.status.command.get() else return "" end end, cond = function() local noice_loaded, noice = pcall(require, "noice") if noice_loaded then return noice.api.status.command.has() else return false end end, }, }, lualine_y = { "filetype" }, lualine_z = { "searchcount", "progress", "location" }, }, }, dependencies = { "nvim-tree/nvim-web-devicons", }, }