Files
LazyVim/lua/lazyvim/util/lualine.lua
Zhou Fang e50b43544f fix(lualine): dynamically fetch the color used in lualine (#4788)
## Description

The color used in lualine was previously static and did not update
dynamically when a new colorscheme was applied. This resulted in
inconsistencies between the theme and the lualine colors, as the 'local'
color table returned the highlight color defined during initialization.

This pull request resolves the issue by ensuring that the lualine colors
are always in sync with the current colorscheme. It achieves this by
using `LazyVim.ui.fg(HIGHLIGHT)` to dynamically fetch the appropriate
highlight colors, making the lualine colors responsive to colorscheme
changes.

## Related Issue(s)

<!--
  If this PR fixes any issues, please link to the issue here.
  - Fixes #<issue_number>
-->

## Screenshots

**Before**


![image](https://github.com/user-attachments/assets/6b78483b-4a64-4ec3-a902-a0d1ed10a992)

**After**


![image](https://github.com/user-attachments/assets/3f73ec26-cbf1-4ff7-873f-6c7b2c13c481)

## Checklist

- [x] I've read the
[CONTRIBUTING](https://github.com/LazyVim/LazyVim/blob/main/CONTRIBUTING.md)
guidelines.
2024-11-14 15:53:27 +01:00

185 lines
4.9 KiB
Lua

---@class lazyvim.util.lualine
local M = {}
---@param icon string
---@param status fun(): nil|"ok"|"error"|"pending"
function M.status(icon, status)
local colors = {
ok = "Special",
error = "DiagnosticError",
pending = "DiagnosticWarn",
}
return {
function()
return icon
end,
cond = function()
return status() ~= nil
end,
color = function()
return LazyVim.ui.fg(colors[status()] or colors.ok)
end,
}
end
---@param name string
---@param icon? string
function M.cmp_source(name, icon)
icon = icon or LazyVim.config.icons.kinds[name:sub(1, 1):upper() .. name:sub(2)]
local started = false
return M.status(icon, function()
if not package.loaded["cmp"] then
return
end
for _, s in ipairs(require("cmp").core.sources or {}) do
if s.name == name then
if s.source:is_available() then
started = true
else
return started and "error" or nil
end
if s.status == s.SourceStatus.FETCHING then
return "pending"
end
return "ok"
end
end
end)
end
---@param component any
---@param text string
---@param hl_group? string
---@return string
function M.format(component, text, hl_group)
text = text:gsub("%%", "%%%%")
if not hl_group or hl_group == "" then
return text
end
---@type table<string, string>
component.hl_cache = component.hl_cache or {}
local lualine_hl_group = component.hl_cache[hl_group]
if not lualine_hl_group then
local utils = require("lualine.utils.utils")
---@type string[]
local gui = vim.tbl_filter(function(x)
return x
end, {
utils.extract_highlight_colors(hl_group, "bold") and "bold",
utils.extract_highlight_colors(hl_group, "italic") and "italic",
})
lualine_hl_group = component:create_hl({
fg = utils.extract_highlight_colors(hl_group, "fg"),
gui = #gui > 0 and table.concat(gui, ",") or nil,
}, "LV_" .. hl_group) --[[@as string]]
component.hl_cache[hl_group] = lualine_hl_group
end
return component:format_hl(lualine_hl_group) .. text .. component:get_default_hl()
end
---@param opts? {relative: "cwd"|"root", modified_hl: string?, directory_hl: string?, filename_hl: string?, modified_sign: string?, readonly_icon: string?, length: number?}
function M.pretty_path(opts)
opts = vim.tbl_extend("force", {
relative = "cwd",
modified_hl = "MatchParen",
directory_hl = "",
filename_hl = "Bold",
modified_sign = "",
readonly_icon = " 󰌾 ",
length = 3,
}, opts or {})
return function(self)
local path = vim.fn.expand("%:p") --[[@as string]]
if path == "" then
return ""
end
path = LazyVim.norm(path)
local root = LazyVim.root.get({ normalize = true })
local cwd = LazyVim.root.cwd()
if opts.relative == "cwd" and path:find(cwd, 1, true) == 1 then
path = path:sub(#cwd + 2)
elseif path:find(root, 1, true) == 1 then
path = path:sub(#root + 2)
end
local sep = package.config:sub(1, 1)
local parts = vim.split(path, "[\\/]")
if opts.length == 0 then
parts = parts
elseif #parts > opts.length then
parts = { parts[1], "", unpack(parts, #parts - opts.length + 2, #parts) }
end
if opts.modified_hl and vim.bo.modified then
parts[#parts] = parts[#parts] .. opts.modified_sign
parts[#parts] = M.format(self, parts[#parts], opts.modified_hl)
else
parts[#parts] = M.format(self, parts[#parts], opts.filename_hl)
end
local dir = ""
if #parts > 1 then
dir = table.concat({ unpack(parts, 1, #parts - 1) }, sep)
dir = M.format(self, dir .. sep, opts.directory_hl)
end
local readonly = ""
if vim.bo.readonly then
readonly = M.format(self, opts.readonly_icon, opts.modified_hl)
end
return dir .. parts[#parts] .. readonly
end
end
---@param opts? {cwd:false, subdirectory: true, parent: true, other: true, icon?:string}
function M.root_dir(opts)
opts = vim.tbl_extend("force", {
cwd = false,
subdirectory = true,
parent = true,
other = true,
icon = "󱉭 ",
color = function()
return LazyVim.ui.fg("Special")
end,
}, opts or {})
local function get()
local cwd = LazyVim.root.cwd()
local root = LazyVim.root.get({ normalize = true })
local name = vim.fs.basename(root)
if root == cwd then
-- root is cwd
return opts.cwd and name
elseif root:find(cwd, 1, true) == 1 then
-- root is subdirectory of cwd
return opts.subdirectory and name
elseif cwd:find(root, 1, true) == 1 then
-- root is parent directory of cwd
return opts.parent and name
else
-- root and cwd are not related
return opts.other and name
end
end
return {
function()
return (opts.icon and opts.icon .. " ") .. get()
end,
cond = function()
return type(get()) == "string"
end,
color = opts.color,
}
end
return M