Files
LazyVim/lua/lazyvim/util/lualine.lua
Jamie Davies 1d4157e681 fix(lualine): apply highlight groups correctly to truncated pretty_paths (#4379)
## Description

This is a small fix to the path truncating in
`LazyVim.lualine.pretty_path()` to make the filename highlighting
actually apply to only the filename, rather than the filename and all
path elements after the inserted ellipsis (`…`).

This keeps it consistent with the behaviour exhibited when the path
isn't truncated, and is what I think most users would expect the
behaviour to be.

## Screenshots

Before this fix:

<img width="320" alt="image"
src="https://github.com/user-attachments/assets/d708a140-2b23-457a-a296-dd411d29d268">

```
   nvim/…/nvim/lua/plugins/lazyvim/ui.lua
   └──┬──┘└──────────────┬──────────────┘
directory_hl        filename_hl
```

After this fix:

<img width="319" alt="image"
src="https://github.com/user-attachments/assets/e9d13fdd-79a8-4e3d-942a-58d0e2bb8bca">

```
nvim/…/nvim/lua/plugins/lazyvim/ui.lua
└──────────────┬───────────────┘└─┬──┘
         directory_hl        filename_hl
```

## Checklist

- [x] I've read the
[CONTRIBUTING](https://github.com/LazyVim/LazyVim/blob/main/CONTRIBUTING.md)
guidelines.
2024-11-07 16:26:17 +01:00

176 lines
4.6 KiB
Lua

---@class lazyvim.util.lualine
local M = {}
function M.cmp_source(name, icon)
local started = false
local function status()
if not package.loaded["cmp"] then
return
end
for _, s in ipairs(require("cmp").core.sources) 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
local colors = {
ok = LazyVim.ui.fg("Special"),
error = LazyVim.ui.fg("DiagnosticError"),
pending = LazyVim.ui.fg("DiagnosticWarn"),
}
return {
function()
return icon or LazyVim.config.icons.kinds[name:sub(1, 1):upper() .. name:sub(2)]
end,
cond = function()
return status() ~= nil
end,
color = function()
return colors[status()] or colors.ok
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
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)
else
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 = LazyVim.ui.fg("Special"),
}, 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