2021-05-07 00:54:49 +00:00
|
|
|
-- Copyright (c) 2020-2021 shadmansaleh
|
|
|
|
-- MIT license, see LICENSE for more details.
|
2021-04-11 08:20:41 +00:00
|
|
|
local highlight = require 'lualine.highlight'
|
|
|
|
|
|
|
|
-- Used to provide a unique id for each component
|
|
|
|
local component_no = 1
|
|
|
|
|
2021-09-14 15:14:23 +00:00
|
|
|
local function check_deprecated_options(options)
|
|
|
|
local function rename_notice(before, now)
|
|
|
|
if options[before] then
|
|
|
|
require('lualine.utils.notices').add_notice(string.format(
|
|
|
|
[[
|
|
|
|
### option.%s
|
|
|
|
%s option has been renamed to `%s`. Please use `%s` instead in your config
|
|
|
|
for %s component.
|
|
|
|
]],
|
|
|
|
before,
|
|
|
|
before,
|
|
|
|
now,
|
|
|
|
now,
|
|
|
|
options.component_name or 'function'
|
|
|
|
))
|
|
|
|
options[now] = options[before]
|
|
|
|
options[before] = nil
|
|
|
|
end
|
|
|
|
end
|
|
|
|
rename_notice('format', 'fmt')
|
|
|
|
rename_notice('condition', 'cond')
|
|
|
|
end
|
2021-04-11 08:20:41 +00:00
|
|
|
local Component = {
|
|
|
|
-- Creates a new component
|
|
|
|
new = function(self, options, child)
|
|
|
|
local new_component = {}
|
|
|
|
new_component.options = options
|
|
|
|
new_component._parent = child or self
|
2021-09-03 18:28:20 +00:00
|
|
|
setmetatable(new_component, { __index = new_component._parent })
|
2021-04-11 08:20:41 +00:00
|
|
|
-- Operation that are required for creating new components but not for inheritence
|
|
|
|
if options ~= nil then
|
|
|
|
component_no = component_no + 1
|
2021-09-14 15:14:23 +00:00
|
|
|
check_deprecated_options(new_component.options)
|
2021-04-11 08:20:41 +00:00
|
|
|
if not options.component_name then
|
|
|
|
new_component.options.component_name = tostring(component_no)
|
|
|
|
end
|
|
|
|
new_component.component_no = component_no
|
|
|
|
new_component:set_separator()
|
|
|
|
new_component:create_option_highlights()
|
|
|
|
end
|
|
|
|
return new_component
|
|
|
|
end,
|
|
|
|
|
|
|
|
set_separator = function(self)
|
2021-05-07 00:54:49 +00:00
|
|
|
if self.options.separator == nil then
|
2021-04-11 08:20:41 +00:00
|
|
|
if self.options.component_separators then
|
|
|
|
if self.options.self.section < 'lualine_x' then
|
2021-09-14 15:14:23 +00:00
|
|
|
self.options.separator = self.options.component_separators.left
|
2021-04-11 08:20:41 +00:00
|
|
|
else
|
2021-09-14 15:14:23 +00:00
|
|
|
self.options.separator = self.options.component_separators.right
|
2021-04-11 08:20:41 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end,
|
|
|
|
|
|
|
|
create_option_highlights = function(self)
|
|
|
|
-- set custom highlights
|
2021-08-09 07:53:42 +00:00
|
|
|
if self.options.color then
|
2021-04-11 08:20:41 +00:00
|
|
|
self.options.color_highlight = highlight.create_component_highlight_group(
|
2021-09-03 18:28:20 +00:00
|
|
|
self.options.color,
|
|
|
|
self.options.component_name,
|
|
|
|
self.options
|
|
|
|
)
|
2021-04-11 08:20:41 +00:00
|
|
|
end
|
|
|
|
end,
|
|
|
|
|
|
|
|
-- set upper or lower case
|
|
|
|
apply_case = function(self)
|
|
|
|
-- Donn't work on components that emit vim statusline escaped chars
|
2021-09-03 18:28:20 +00:00
|
|
|
if self.status:find '%%' and not self.status:find '%%%%' then
|
|
|
|
return
|
|
|
|
end
|
2021-04-11 08:20:41 +00:00
|
|
|
if self.options.upper == true then
|
|
|
|
self.status = self.status:upper()
|
|
|
|
elseif self.options.lower == true then
|
|
|
|
self.status = self.status:lower()
|
|
|
|
end
|
|
|
|
end,
|
|
|
|
|
|
|
|
-- Adds spaces to left and right of a component
|
|
|
|
apply_padding = function(self)
|
2021-09-14 15:14:23 +00:00
|
|
|
local padding = self.options.padding
|
|
|
|
local l_padding, r_padding
|
|
|
|
if padding == nil then
|
|
|
|
padding = 1
|
|
|
|
end
|
|
|
|
if type(padding) == 'number' then
|
|
|
|
l_padding, r_padding = padding, padding
|
|
|
|
elseif type(padding) == 'table' then
|
|
|
|
l_padding, r_padding = padding.left, padding.right
|
|
|
|
end
|
2021-04-11 08:20:41 +00:00
|
|
|
if l_padding then
|
2021-09-03 18:28:20 +00:00
|
|
|
if self.status:find '%%#.*#' == 1 then
|
2021-04-11 08:20:41 +00:00
|
|
|
-- When component has changed the highlight at begining
|
|
|
|
-- we will add the padding after the highlight
|
2021-09-03 18:28:20 +00:00
|
|
|
local pre_highlight = vim.fn.matchlist(self.status, [[\(%#.\{-\}#\)]])[2]
|
|
|
|
self.status = pre_highlight .. string.rep(' ', l_padding) .. self.status:sub(#pre_highlight + 1, #self.status)
|
2021-04-11 08:20:41 +00:00
|
|
|
else
|
|
|
|
self.status = string.rep(' ', l_padding) .. self.status
|
|
|
|
end
|
|
|
|
end
|
2021-09-03 18:28:20 +00:00
|
|
|
if r_padding then
|
|
|
|
self.status = self.status .. string.rep(' ', r_padding)
|
|
|
|
end
|
2021-04-11 08:20:41 +00:00
|
|
|
end,
|
|
|
|
|
|
|
|
-- Applies custom highlights for component
|
|
|
|
apply_highlights = function(self, default_highlight)
|
|
|
|
if self.options.color_highlight then
|
2021-09-03 18:28:20 +00:00
|
|
|
self.status = highlight.component_format_highlight(self.options.color_highlight) .. self.status
|
2021-04-11 08:20:41 +00:00
|
|
|
end
|
2021-09-03 18:28:20 +00:00
|
|
|
if type(self.options.separator) ~= 'table' and self.status:find '%%#' then
|
2021-08-26 11:26:13 +00:00
|
|
|
-- Apply default highlight only when we aren't applying trans sep and
|
|
|
|
-- the component has changed it's hl. since we won't be applying
|
|
|
|
-- regular sep in those cases so ending with default hl isn't neccessay
|
|
|
|
self.status = self.status .. default_highlight
|
|
|
|
-- Also put it in applied sep so when sep get struped so does the hl
|
|
|
|
self.applied_separator = default_highlight
|
|
|
|
end
|
|
|
|
-- Prepend default hl when the component doesn't start with hl otherwise
|
|
|
|
-- color in previous component can cause side effect
|
2021-09-03 18:28:20 +00:00
|
|
|
if not self.status:find '^%%#' then
|
|
|
|
self.status = default_highlight .. self.status
|
|
|
|
end
|
2021-04-11 08:20:41 +00:00
|
|
|
end,
|
|
|
|
|
|
|
|
-- Apply icon in front of component
|
|
|
|
apply_icon = function(self)
|
|
|
|
if self.options.icons_enabled and self.options.icon then
|
|
|
|
self.status = self.options.icon .. ' ' .. self.status
|
|
|
|
end
|
|
|
|
end,
|
|
|
|
|
|
|
|
-- Apply separator at end of component only when
|
|
|
|
-- custom highlights haven't affected background
|
|
|
|
apply_separator = function(self)
|
2021-05-07 00:54:49 +00:00
|
|
|
local separator = self.options.separator
|
|
|
|
if type(separator) == 'table' then
|
|
|
|
if self.options.separator[2] == '' then
|
|
|
|
if self.options.self.section < 'lualine_x' then
|
2021-09-14 15:14:23 +00:00
|
|
|
separator = self.options.component_separators.left
|
2021-05-07 00:54:49 +00:00
|
|
|
else
|
2021-09-14 15:14:23 +00:00
|
|
|
separator = self.options.component_separators.right
|
2021-05-07 00:54:49 +00:00
|
|
|
end
|
|
|
|
else
|
|
|
|
return
|
|
|
|
end
|
|
|
|
end
|
|
|
|
if separator and #separator > 0 then
|
|
|
|
self.status = self.status .. separator
|
2021-08-26 11:26:13 +00:00
|
|
|
self.applied_separator = self.applied_separator .. separator
|
2021-05-07 00:54:49 +00:00
|
|
|
end
|
|
|
|
end,
|
|
|
|
|
|
|
|
apply_section_separators = function(self)
|
2021-09-03 18:28:20 +00:00
|
|
|
if type(self.options.separator) ~= 'table' then
|
|
|
|
return
|
|
|
|
end
|
2021-09-14 15:14:23 +00:00
|
|
|
if self.options.separator.left ~= nil and self.options.separator.left ~= '' then
|
|
|
|
self.status = string.format('%%s{%s}%s', self.options.separator.left, self.status)
|
2021-05-07 00:54:49 +00:00
|
|
|
self.strip_previous_separator = true
|
|
|
|
end
|
2021-09-14 15:14:23 +00:00
|
|
|
if self.options.separator.right ~= nil and self.options.separator.right ~= '' then
|
|
|
|
self.status = string.format('%s%%S{%s}', self.status, self.options.separator.right)
|
2021-04-11 08:20:41 +00:00
|
|
|
end
|
|
|
|
end,
|
|
|
|
|
2021-05-07 00:54:49 +00:00
|
|
|
strip_separator = function(self)
|
2021-09-03 18:28:20 +00:00
|
|
|
if not self.applied_separator then
|
|
|
|
self.applied_separator = ''
|
|
|
|
end
|
|
|
|
self.status = self.status:sub(1, (#self.status - #self.applied_separator))
|
2021-04-11 08:20:41 +00:00
|
|
|
self.applied_separator = nil
|
|
|
|
return self.status
|
|
|
|
end,
|
|
|
|
|
2021-08-03 12:03:26 +00:00
|
|
|
-- variable to store component output for manipulation
|
2021-04-11 08:20:41 +00:00
|
|
|
status = '',
|
2021-08-03 12:03:26 +00:00
|
|
|
-- Actual function that updates a component. Must be overwritten with component functionality
|
2021-04-13 12:36:51 +00:00
|
|
|
-- luacheck: push no unused args
|
2021-08-26 11:26:13 +00:00
|
|
|
update_status = function(self, is_focused) end,
|
2021-04-13 12:36:51 +00:00
|
|
|
-- luacheck: pop
|
2021-04-11 08:20:41 +00:00
|
|
|
|
|
|
|
-- Driver code of the class
|
2021-08-08 16:03:58 +00:00
|
|
|
draw = function(self, default_highlight, is_focused)
|
2021-04-11 08:20:41 +00:00
|
|
|
self.status = ''
|
2021-08-26 11:26:13 +00:00
|
|
|
self.applied_separator = ''
|
2021-08-08 16:03:58 +00:00
|
|
|
|
2021-09-14 15:14:23 +00:00
|
|
|
if self.options.cond ~= nil and self.options.cond() ~= true then
|
2021-04-06 13:31:45 +00:00
|
|
|
return self.status
|
|
|
|
end
|
2021-08-08 16:03:58 +00:00
|
|
|
local status = self:update_status(is_focused)
|
2021-09-14 15:14:23 +00:00
|
|
|
if self.options.fmt then
|
|
|
|
status = self.options.fmt(status or '')
|
2021-09-03 18:28:20 +00:00
|
|
|
end
|
2021-04-11 08:20:41 +00:00
|
|
|
if type(status) == 'string' and #status > 0 then
|
|
|
|
self.status = status
|
|
|
|
self:apply_icon()
|
|
|
|
self:apply_case()
|
|
|
|
self:apply_padding()
|
|
|
|
self:apply_highlights(default_highlight)
|
2021-08-26 11:26:13 +00:00
|
|
|
self:apply_section_separators()
|
2021-08-08 16:03:58 +00:00
|
|
|
self:apply_separator()
|
2021-04-11 08:20:41 +00:00
|
|
|
end
|
|
|
|
return self.status
|
2021-09-03 18:28:20 +00:00
|
|
|
end,
|
2021-04-11 08:20:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return Component
|