nvim: factor out custom lualine components

This commit is contained in:
Fernando Schauenburg 2024-07-22 22:49:27 +02:00
parent b87bec08c3
commit 932b7b0047
8 changed files with 205 additions and 235 deletions

View file

@ -1,224 +1,60 @@
local M = { "nvim-lualine/lualine.nvim" }
return {
"nvim-lualine/lualine.nvim",
local icons = require("fschauen.util.icons")
local ui = icons.ui
dependencies = "nvim-tree/nvim-web-devicons",
local bright = "#ffffff" -- alternative: '#f9f5d7'
opts = function()
local component = require("lualine.fschauen.component")
local icons = require("fschauen.util.icons")
local window = require("fschauen.window")
M.dependencies = "nvim-tree/nvim-web-devicons"
local diagnostics = component.colored_if_focused("diagnostics")
local filetype = component.colored_if_focused("filetype")
local status = component.colored_if_focused("fschauen.status")
local whitespace = component.colored_if_focused("fschauen.whitespace")
M.config = function()
local window = require("fschauen.window")
local filename = (function()
local C = require("lualine.component"):extend()
function C:init(options)
C.super.init(self, options)
local color = options.color or {}
local modified = { gui = "italic" }
self.custom_highlights = { -- [is_focused, modified]
[true] = {
[true] = self:create_hl(
vim.tbl_extend("force", color, modified),
"focus_modified"
),
[false] = self:create_hl(color, "focus"),
},
[false] = {
[true] = self:create_hl(modified, "nofocus_modified"),
[false] = self:create_hl({}, "nofocus"),
},
}
end
function C:update_status(is_focused)
self.options.color_highlight = self.custom_highlights[is_focused][vim.bo.modified]
local path = vim.fn.expand("%:~:.")
if window.is_wide() then
return path
elseif window.is_medium() then
return vim.fn.pathshorten(path) -- only first letter of directories
else
return vim.fn.fnamemodify(path, ":t") -- only tail
end
end
return C
end)()
local mode = (function()
local C = require("lualine.component"):extend()
C.map = {
["n"] = icons.modes.Normal, -- 'Normal ', -- Normal
["no"] = icons.modes.OperatorPending, -- 'O-Pend ', -- Operator-pending
["ni"] = icons.modes.NormalI, -- 'Normal ', -- Normal via i_CTRL-O
["v"] = icons.modes.Visual, -- 'Visual ', -- Visual by character
[""] = icons.modes.VisualBlock, -- 'V-Block', -- Visual blockwise
["s"] = icons.modes.Select, -- 'Select ', -- Select by character
[""] = icons.modes.SelectBlock, -- 'S-Block', -- Select blockwise
["i"] = icons.modes.Insert, -- 'Insert ', -- Insert
["r"] = icons.modes.Replace, -- 'Replace', -- Replace
["rv"] = icons.modes.VirtualReplace, -- 'V-Repl ', -- Virtual Replace
["c"] = icons.modes.Command, -- 'Command', -- Command-line
["cv"] = icons.modes.Ex, -- ' Ex ', -- Ex mode
["rm"] = icons.modes.modeore, -- ' modeore ', -- -- modeORE --
["r?"] = icons.modes.Cofirm, -- 'Confirm', -- :confirm
["!"] = icons.modes.Shell, -- ' Shell ', -- External command executing
["t"] = icons.modes.Term, -- ' Term ', -- Terminal
local sections = {
lualine_a = {
"fschauen.mode",
},
lualine_b = {
{ "branch", icon = icons.git.Branch, cond = window.is_medium },
},
lualine_c = {
"fschauen.filename",
status,
},
lualine_x = {
diagnostics,
"fschauen.searchcount",
{ filetype, cond = window.is_medium },
},
lualine_y = {
{ "fileformat", cond = window.is_medium },
"progress",
},
lualine_z = {
"location",
whitespace,
},
}
function C:update_status(is_focused)
if not is_focused then return " " .. ui.Sleep end
local code = vim.api.nvim_get_mode().mode:lower()
local symbol = C.map[code:sub(1, 2)] or C.map[code:sub(1, 1)] or code
return " " .. symbol .. " "
end
return C
end)()
local searchcount = (function()
local C = require("lualine.component"):extend()
function C:init(options)
C.super.init(self, options)
self.options = vim.tbl_extend("keep", self.options or {}, {
maxcount = 999,
timeout = 250,
})
end
function C:update_status()
if vim.v.hlsearch == 0 then return "" end
local count = vim.fn.searchcount {
maxcount = self.options.maxcount,
timeout = self.options.timeout,
}
if next(count) == nil then return "" end
local denominator = count.total > count.maxcount and ""
or string.format("%d", count.total)
return string.format(ui.Search .. "%d/%s", count.current, denominator)
end
return C
end)()
local colored_if_focused = function(component)
if type(component) == "string" then
local C = require("lualine.components." .. component):extend()
function C:update_status(is_focused)
self.options.colored = is_focused
return C.super.update_status(self, is_focused)
end
return C
elseif type(component) == "function" then
local C = require("lualine.component"):extend()
function C:init(options)
C.super.init(self, options)
self.saved_hl = self.options.color_highlight
end
function C:update_status(is_focused)
self.options.color_highlight = is_focused and self.saved_hl or nil
return component(is_focused)
end
return C
end
end
local trailing_whitespace = {
colored_if_focused(function()
local trailing = [[\s\+$]]
local lineno = vim.fn.search(trailing, "nwc")
if lineno == 0 then return "" end
local result = ui.Attention .. lineno
local total = vim.fn.searchcount({ pattern = trailing }).total
if total > 1 then result = result .. string.format(" (%d total)", total) end
return result
end),
color = { bg = orange },
cond = function() return vim.bo.filetype ~= "help" end,
}
local status = {
colored_if_focused(function(_)
local status = ""
if vim.bo.modified then status = status .. ui.Modified end
if vim.bo.readonly or not vim.bo.modifiable then status = status .. ui.ReadOnly end
return status
end),
color = {
fg = bright,
},
}
local sections = {
lualine_a = {
mode,
},
lualine_b = {
{ "branch", icon = icons.git.Branch, cond = window.is_medium },
},
lualine_c = {
filename,
status,
},
lualine_x = {
colored_if_focused("diagnostics"),
searchcount,
{ colored_if_focused("filetype"), cond = window.is_medium },
},
lualine_y = {
{ "fileformat", cond = window.is_medium },
"progress",
},
lualine_z = {
"location",
trailing_whitespace,
},
}
require("lualine").setup {
options = {
icons_enabled = true,
component_separators = {
left = "",
right = "",
return {
options = {
icons_enabled = true,
component_separators = { left = "", right = "" },
section_separators = { left = "", right = "" },
},
section_separators = {
left = "",
right = "",
sections = sections,
inactive_sections = sections,
extensions = {
"fugitive",
"quickfix",
"nvim-tree",
"lazy",
"man",
"trouble",
},
},
sections = sections,
inactive_sections = sections,
extensions = {
"fugitive",
"quickfix",
"nvim-tree",
"lazy",
"man",
"trouble",
},
}
end
return M
}
end,
}

View file

@ -72,25 +72,6 @@ M.kind = {
Variable = "󰀫 ", -- 
}
M.modes = {
Normal = "", -- "Normal " "n"
OperatorPending = "", -- "O-Pend " "no"
NormalI = "", -- "Normal " "ni" (normal via i_CTRL-O)
Visual = "󰒉", -- "Visual " "v"
VisualBlock = "󰩭", -- "V-Block" ""
Select = "󰒉", -- "Select " "s"
SelectBlock = "󰩭", -- "S-Block" ""
Insert = "", -- "Insert " "i"
Replace = "󰄾", -- "Replace" "r"
VirtualReplace = "󰶻", -- "V-Repl " "rv"
Command = "", -- "Command" "c"
Ex = "", -- " Ex " "cv"
modeore = "", -- " modeore "rm" (modeORE)
Confirm = "󰭚", -- "Confirm" "r?" (:confirm)
Shell = "", -- " Shell " "!" (external command executing)
Terminal = "", -- " Term " "t"
}
M.ui = {
Attention = "",
Bug = "", -- 

View file

@ -0,0 +1,37 @@
local M = require("lualine.component"):extend()
function M:init(opts)
M.super.init(self, opts)
local color = opts.color or {}
local modified = { gui = "italic" }
self.custom_highlights = { -- [is_focused, modified]
[true] = {
[true] = self:create_hl(vim.tbl_extend("force", color, modified), "focus_modified"),
[false] = self:create_hl(color, "focus"),
},
[false] = {
[true] = self:create_hl(modified, "nofocus_modified"),
[false] = self:create_hl({}, "nofocus"),
},
}
end
local window = require("fschauen.window")
function M:update_status(is_focused)
self.options.color_highlight = self.custom_highlights[is_focused][vim.bo.modified]
local path = vim.fn.expand("%:~:.")
if window.is_wide() then
return path
elseif window.is_medium() then
return vim.fn.pathshorten(path) -- only first letter of directories
else
return vim.fn.fnamemodify(path, ":t") -- only tail
end
end
return M

View file

@ -0,0 +1,32 @@
local M = require("lualine.component"):extend()
-- stylua: ignore start
M.map = {
["n"] = "", -- "Normal "
["no"] = "", -- "O-Pend "
["ni"] = "", -- "Normal " (normal via i_CTRL-O)
["v"] = "󰒉", -- "Visual "
[""] = "󰩭", -- "V-Block"
["s"] = "󰒉", -- "Select "
[""] = "󰩭", -- "S-Block"
["i"] = "", -- "Insert "
["r"] = "󰄾", -- "Replace"
["rv"] = "󰶻", -- "V-Repl "
["c"] = "", -- "Command"
["cv"] = "", -- " Ex "
["rm"] = "", -- " modeore (modeORE)
["r?"] = "󰭚", -- "Confirm" (:confirm)
["!"] = "", -- " Shell " (external command executing)
["t"] = "", -- " Term "
}
-- stylua: ignore end
function M:update_status(is_focused)
if not is_focused then return " 󰒲 " end
local code = vim.api.nvim_get_mode().mode:lower()
local symbol = M.map[code:sub(1, 2)] or M.map[code:sub(1, 1)] or code
return " " .. symbol .. " "
end
return M

View file

@ -0,0 +1,22 @@
local M = require("lualine.component"):extend()
function M:init(opts)
local default_opts = { maxcount = 999, timeout = 250 }
M.super.init(self, vim.tbl_extend("keep", opts or {}, default_opts))
end
function M:update_status()
if vim.v.hlsearch == 0 then return "" end
local count = vim.fn.searchcount {
maxcount = self.options.maxcount,
timeout = self.options.timeout,
}
if next(count) == nil then return "" end
local denominator = count.total > count.maxcount and "󰛤"
or string.format("%d", count.total)
return string.format(" %d/%s", count.current, denominator)
end
return M

View file

@ -0,0 +1,15 @@
local M = require("lualine.fschauen.component"):extend()
function M:init(opts)
opts.color = opts.color or { fg = "#ffffff" } -- alternative: '#f9f5d7'
M.super.init(self, opts)
end
function M:update_status(--[[is_focused]]_)
local status = ""
if vim.bo.modified then status = status .. "" end
if vim.bo.readonly or not vim.bo.modifiable then status = status .. "" end
return status
end
return M

View file

@ -0,0 +1,22 @@
local M = require("lualine.fschauen.component"):extend()
function M:init(opts)
opts.color = opts.color or { bg = "#d65d0e" }
opts.cond = opts.cond or function() return vim.bo.filetype ~= "help" end
M.super.init(self, opts)
end
function M:update_status(--[[is_focused]]_)
local trailing = [[\s\+$]]
local lineno = vim.fn.search(trailing, "nwc")
if lineno == 0 then return "" end
local result = "" .. lineno
local total = vim.fn.searchcount({ pattern = trailing }).total
if total > 1 then result = result .. string.format(" (%d total)", total) end
return result
end
return M

View file

@ -0,0 +1,25 @@
local M = require("lualine.component"):extend()
function M:init(opts)
opts.colored = opts.colored ~= false -- colored by default
M.super.init(self, opts)
self.saved_hl = self.options.color_highlight
end
function M:draw(default_highlight, is_focused)
self.options.color_highlight = self.options.colored and self.saved_hl or nil
return M.super.draw(self, default_highlight, is_focused)
end
M.colored_if_focused = function(component)
local C = require("lualine.components." .. component):extend()
function C:update_status(is_focused)
self.options.colored = is_focused
return C.super.update_status(self, is_focused)
end
return C
end
return M