Hyprland-dotfiles/nvim/lua/modules/configs/ui/lualine.lua

348 lines
9.1 KiB
Lua
Raw Normal View History

2024-07-21 02:51:17 -04:00
return function()
local has_catppuccin = vim.g.colors_name:find("catppuccin") ~= nil
local colors = require("modules.utils").get_palette()
local icons = {
diagnostics = require("modules.utils.icons").get("diagnostics", true),
git = require("modules.utils.icons").get("git", true),
git_nosep = require("modules.utils.icons").get("git"),
misc = require("modules.utils.icons").get("misc", true),
ui = require("modules.utils.icons").get("ui", true),
}
local function custom_theme()
vim.api.nvim_create_autocmd("ColorScheme", {
group = vim.api.nvim_create_augroup("LualineColorScheme", { clear = true }),
pattern = "*",
callback = function()
has_catppuccin = vim.g.colors_name:find("catppuccin") ~= nil
require("lualine").setup({ options = { theme = custom_theme() } })
end,
})
if has_catppuccin then
colors = require("modules.utils").get_palette()
local universal_bg = require("core.settings").transparent_background and "NONE" or colors.mantle
return {
normal = {
a = { fg = colors.lavender, bg = colors.surface0, gui = "bold" },
b = { fg = colors.text, bg = universal_bg },
c = { fg = colors.text, bg = universal_bg },
},
command = {
a = { fg = colors.peach, bg = colors.surface0, gui = "bold" },
},
insert = {
a = { fg = colors.green, bg = colors.surface0, gui = "bold" },
},
visual = {
a = { fg = colors.flamingo, bg = colors.surface0, gui = "bold" },
},
terminal = {
a = { fg = colors.teal, bg = colors.surface0, gui = "bold" },
},
replace = {
a = { fg = colors.red, bg = colors.surface0, gui = "bold" },
},
inactive = {
a = { fg = colors.subtext0, bg = universal_bg, gui = "bold" },
b = { fg = colors.subtext0, bg = universal_bg },
c = { fg = colors.subtext0, bg = universal_bg },
},
}
else
return "auto"
end
end
local conditionals = {
has_enough_room = function()
return vim.o.columns > 100
end,
has_comp_before = function()
return vim.bo.filetype ~= ""
end,
has_git = function()
local gitdir = vim.fs.find(".git", {
limit = 1,
upward = true,
type = "directory",
path = vim.fn.expand("%:p:h"),
})
return #gitdir > 0
end,
}
---@class lualine_hlgrp
---@field fg string
---@field bg string
---@field gui string?
local utils = {
force_centering = function()
return "%="
end,
abbreviate_path = function(path)
local home = require("core.global").home
if path:find(home, 1, true) == 1 then
path = "~" .. path:sub(#home + 1)
end
return path
end,
---Generate <func>`color` for any component
---@param fg string @Foreground hl group
---@param gen_bg boolean @Generate guibg from hl group |StatusLine|?
---@param special_nobg boolean @Disable guibg for transparent backgrounds?
---@param bg string? @Background hl group
---@param gui string? @GUI highlight arguments
---@return nil|fun():lualine_hlgrp
gen_hl = function(fg, gen_bg, special_nobg, bg, gui)
if has_catppuccin then
return function()
local guifg = colors[fg]
local guibg = gen_bg and require("modules.utils").hl_to_rgb("StatusLine", true, colors.mantle)
or colors[bg]
local nobg = special_nobg and require("core.settings").transparent_background
return {
fg = guifg and guifg or colors.none,
bg = (guibg and not nobg) and guibg or colors.none,
gui = gui and gui or nil,
}
end
else
-- Return `nil` if the theme is user-defined
return nil
end
end,
}
local function diff_source()
local gitsigns = vim.b.gitsigns_status_dict
if gitsigns then
return {
added = gitsigns.added,
modified = gitsigns.changed,
removed = gitsigns.removed,
}
end
end
local components = {
separator = { -- use as section separators
function()
return ""
end,
padding = 0,
color = utils.gen_hl("surface1", true, true),
separator = { left = "", right = "" },
},
file_status = {
function()
local function is_new_file()
local filename = vim.fn.expand("%")
return filename ~= "" and vim.bo.buftype == "" and vim.fn.filereadable(filename) == 0
end
local symbols = {}
if vim.bo.modified then
table.insert(symbols, "[+]")
end
if vim.bo.modifiable == false then
table.insert(symbols, "[-]")
end
if vim.bo.readonly == true then
table.insert(symbols, "[RO]")
end
if is_new_file() then
table.insert(symbols, "[New]")
end
return #symbols > 0 and table.concat(symbols, "") or ""
end,
padding = { left = -1, right = 1 },
cond = conditionals.has_comp_before,
},
lsp = {
function()
local buf_ft = vim.bo.filetype
local clients = vim.lsp.get_clients({ buffer = vim.api.nvim_get_current_buf() })
local lsp_lists = {}
local available_servers = {}
if next(clients) == nil then
return icons.misc.NoActiveLsp -- No server available
end
for _, client in ipairs(clients) do
local filetypes = client.config.filetypes
local client_name = client.name
if filetypes and vim.fn.index(filetypes, buf_ft) ~= -1 then
-- Avoid adding servers that already exists.
if not lsp_lists[client_name] then
lsp_lists[client_name] = true
table.insert(available_servers, client_name)
end
end
end
return next(available_servers) == nil and icons.misc.NoActiveLsp
or string.format("%s[%s]", icons.misc.LspAvailable, table.concat(available_servers, ", "))
end,
color = utils.gen_hl("blue", true, true, nil, "bold"),
cond = conditionals.has_enough_room,
},
python_venv = {
function()
local function env_cleanup(venv)
if string.find(venv, "/") then
local final_venv = venv
for w in venv:gmatch("([^/]+)") do
final_venv = w
end
venv = final_venv
end
return venv
end
if vim.bo.filetype == "python" then
local venv = os.getenv("CONDA_DEFAULT_ENV")
if venv then
return icons.misc.PyEnv .. env_cleanup(venv)
end
venv = os.getenv("VIRTUAL_ENV")
if venv then
return icons.misc.PyEnv .. env_cleanup(venv)
end
end
return ""
end,
color = utils.gen_hl("green", true, true),
cond = conditionals.has_enough_room,
},
tabwidth = {
function()
return icons.ui.Tab .. vim.bo.tabstop
end,
padding = 1,
},
cwd = {
function()
return icons.ui.FolderWithHeart .. utils.abbreviate_path(vim.fs.normalize(vim.fn.getcwd()))
end,
color = utils.gen_hl("subtext0", true, true, nil, "bold"),
},
file_location = {
function()
local cursorline = vim.fn.line(".")
local cursorcol = vim.fn.virtcol(".")
local filelines = vim.fn.line("$")
local position
if cursorline == 1 then
position = "Top"
elseif cursorline == filelines then
position = "Bot"
else
position = string.format("%2d%%%%", math.floor(cursorline / filelines * 100))
end
return string.format("%s·%3d:%-2d", position, cursorline, cursorcol)
end,
},
}
require("modules.utils").load_plugin("lualine", {
options = {
icons_enabled = true,
theme = custom_theme(),
disabled_filetypes = { statusline = { "alpha" } },
component_separators = "",
section_separators = { left = "", right = "" },
},
sections = {
lualine_a = { "mode" },
lualine_b = {
{
"filetype",
colored = true,
icon_only = false,
icon = { align = "left" },
},
components.file_status,
vim.tbl_extend("force", components.separator, {
cond = function()
return conditionals.has_git() and conditionals.has_comp_before()
end,
}),
},
lualine_c = {
{
"branch",
icon = icons.git_nosep.Branch,
color = utils.gen_hl("subtext0", true, true, nil, "bold"),
cond = conditionals.has_git,
},
{
"diff",
symbols = {
added = icons.git.Add,
modified = icons.git.Mod_alt,
removed = icons.git.Remove,
},
source = diff_source,
colored = false,
color = utils.gen_hl("subtext0", true, true),
cond = conditionals.has_git,
padding = { right = 1 },
},
{ utils.force_centering },
{
"diagnostics",
sources = { "nvim_diagnostic" },
sections = { "error", "warn", "info", "hint" },
symbols = {
error = icons.diagnostics.Error,
warn = icons.diagnostics.Warning,
info = icons.diagnostics.Information,
hint = icons.diagnostics.Hint_alt,
},
},
components.lsp,
},
lualine_x = {
{
"encoding",
fmt = string.upper,
padding = { left = 1 },
cond = conditionals.has_enough_room,
},
{
"fileformat",
symbols = {
unix = "LF",
dos = "CRLF",
mac = "CR", -- Legacy macOS
},
padding = { left = 1 },
},
components.tabwidth,
},
lualine_y = {
components.separator,
components.python_venv,
components.cwd,
},
lualine_z = { components.file_location },
},
inactive_sections = {
lualine_a = {},
lualine_b = {},
lualine_c = { "filename" },
lualine_x = { "location" },
lualine_y = {},
lualine_z = {},
},
tabline = {},
extensions = {},
})
end