Refactor: Components now use OOP style (#141)
This commit is contained in:
parent
2b32fb090f
commit
1b81b0021f
|
@ -0,0 +1,135 @@
|
|||
local highlight = require 'lualine.highlight'
|
||||
|
||||
-- Used to provide a unique id for each component
|
||||
local component_no = 1
|
||||
|
||||
local Component = {
|
||||
-- Creates a new component
|
||||
new = function(self, options, child)
|
||||
local new_component = {}
|
||||
new_component.options = options
|
||||
new_component._parent = child or self
|
||||
setmetatable(new_component, {__index = new_component._parent})
|
||||
-- Operation that are required for creating new components but not for inheritence
|
||||
if options ~= nil then
|
||||
component_no = component_no + 1
|
||||
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)
|
||||
if type(self.options.separator) ~= 'string' then
|
||||
if self.options.component_separators then
|
||||
if self.options.self.section < 'lualine_x' then
|
||||
self.options.separator = self.options.component_separators[1]
|
||||
else
|
||||
self.options.separator = self.options.component_separators[2]
|
||||
end
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
||||
create_option_highlights = function(self)
|
||||
-- set custom highlights
|
||||
if self.options.color then
|
||||
self.options.color_highlight = highlight.create_component_highlight_group(
|
||||
self.options.color,
|
||||
self.options.component_name,
|
||||
self.options)
|
||||
end
|
||||
end,
|
||||
|
||||
-- set upper or lower case
|
||||
apply_case = function(self)
|
||||
-- Donn't work on components that emit vim statusline escaped chars
|
||||
if self.status:find('%%') and not self.status:find('%%%%') then return end
|
||||
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)
|
||||
local l_padding = (self.options.left_padding or self.options.padding or 1)
|
||||
local r_padding = (self.options.right_padding or self.options.padding or 1)
|
||||
if l_padding then
|
||||
if self.status:find('%%#.*#') == 1 then
|
||||
-- When component has changed the highlight at begining
|
||||
-- we will add the padding after the highlight
|
||||
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)
|
||||
else
|
||||
self.status = string.rep(' ', l_padding) .. self.status
|
||||
end
|
||||
end
|
||||
if r_padding then self.status = self.status .. string.rep(' ', r_padding) end
|
||||
end,
|
||||
|
||||
-- Applies custom highlights for component
|
||||
apply_highlights = function(self, default_highlight)
|
||||
if self.options.color_highlight then
|
||||
self.status = highlight.component_format_highlight(
|
||||
self.options.color_highlight) .. self.status
|
||||
end
|
||||
self.status = self.status .. default_highlight
|
||||
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)
|
||||
if self.options.separator and #self.options.separator > 0 then
|
||||
self.status = self.status .. self.options.separator
|
||||
self.applied_separator = self.options.separator
|
||||
end
|
||||
end,
|
||||
|
||||
strip_separator = function(self, default_highlight)
|
||||
if not default_highlight then default_highlight = '' end
|
||||
if not self.applied_separator then self.applied_separator = '' end
|
||||
self.status = self.status:sub(1, (#self.status -
|
||||
(#self.applied_separator +
|
||||
#default_highlight)))
|
||||
self.applied_separator = nil
|
||||
return self.status
|
||||
end,
|
||||
|
||||
-- variable to store component output for manupulation
|
||||
status = '',
|
||||
-- Actual function the updates a component . Must be overwritten with component functionality
|
||||
update_status = function(self) end,
|
||||
|
||||
-- Driver code of the class
|
||||
draw = function(self, default_highlight)
|
||||
self.status = ''
|
||||
local status = self:update_status()
|
||||
if self.options.format then status = self.options.format(status or '') end
|
||||
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)
|
||||
self:apply_separator()
|
||||
end
|
||||
return self.status
|
||||
end
|
||||
}
|
||||
|
||||
return Component
|
|
@ -1,12 +1,31 @@
|
|||
-- Copyright (c) 2020-2021 shadmansaleh
|
||||
-- MIT license, see LICENSE for more details.
|
||||
local git_branch
|
||||
local Branch = require('lualine.component'):new()
|
||||
|
||||
-- vars
|
||||
Branch.git_branch = ''
|
||||
-- os specific path separator
|
||||
local sep = package.config:sub(1, 1)
|
||||
Branch.sep = package.config:sub(1, 1)
|
||||
-- event watcher to watch head file
|
||||
Branch.file_changed = vim.loop.new_fs_event()
|
||||
|
||||
-- Initilizer
|
||||
Branch.new = function(self, options, child)
|
||||
local new_branch = self._parent:new(options, child or Branch)
|
||||
if not new_branch.options.icon then
|
||||
new_branch.options.icon = '' -- e0a0
|
||||
end
|
||||
-- run watch head on load so branch is present when component is loaded
|
||||
Branch.update_branch()
|
||||
-- update branch state of BufEnter as different Buffer may be on different repos
|
||||
vim.cmd [[autocmd BufEnter * lua require'lualine.components.branch'.update_branch()]]
|
||||
return new_branch
|
||||
end
|
||||
|
||||
Branch.update_status = function() return Branch.git_branch end
|
||||
|
||||
-- returns full path to git directory for current directory
|
||||
local function find_git_dir()
|
||||
function Branch.find_git_dir()
|
||||
-- get file dir so we can search from that dir
|
||||
local file_dir = vim.fn.expand('%:p:h') .. ';'
|
||||
-- find .git/ folder genaral case
|
||||
|
@ -23,7 +42,7 @@ local function find_git_dir()
|
|||
git_dir = git_dir:match('gitdir: (.+)$')
|
||||
file:close()
|
||||
-- submodule / relative file path
|
||||
if git_dir:sub(1, 1) ~= sep and not git_dir:match('^%a:.*$') then
|
||||
if git_dir:sub(1, 1) ~= Branch.sep and not git_dir:match('^%a:.*$') then
|
||||
git_dir = git_file:match('(.*).git') .. git_dir
|
||||
end
|
||||
end
|
||||
|
@ -31,58 +50,37 @@ local function find_git_dir()
|
|||
end
|
||||
|
||||
-- sets git_branch veriable to branch name or commit hash if not on branch
|
||||
local function get_git_head(head_file)
|
||||
function Branch.get_git_head(head_file)
|
||||
local f_head = io.open(head_file)
|
||||
if f_head then
|
||||
local HEAD = f_head:read()
|
||||
f_head:close()
|
||||
local branch = HEAD:match('ref: refs/heads/(.+)$')
|
||||
if branch then
|
||||
git_branch = branch
|
||||
Branch.git_branch = branch
|
||||
else
|
||||
git_branch = HEAD:sub(1, 6)
|
||||
Branch.git_branch = HEAD:sub(1, 6)
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
-- event watcher to watch head file
|
||||
local file_changed = vim.loop.new_fs_event()
|
||||
local function watch_head()
|
||||
file_changed:stop()
|
||||
local git_dir = find_git_dir()
|
||||
-- Update branch
|
||||
function Branch.update_branch()
|
||||
Branch.file_changed:stop()
|
||||
local git_dir = Branch.find_git_dir()
|
||||
if #git_dir > 0 then
|
||||
local head_file = git_dir .. sep .. 'HEAD'
|
||||
get_git_head(head_file)
|
||||
file_changed:start(head_file, {}, vim.schedule_wrap(
|
||||
local head_file = git_dir .. Branch.sep .. 'HEAD'
|
||||
Branch.get_git_head(head_file)
|
||||
Branch.file_changed:start(head_file, {}, vim.schedule_wrap(
|
||||
function()
|
||||
-- reset file-watch
|
||||
watch_head()
|
||||
Branch.update_branch()
|
||||
end))
|
||||
else
|
||||
-- set to nil when git dir was not found
|
||||
git_branch = nil
|
||||
-- set to '' when git dir was not found
|
||||
Branch.git_branch = ''
|
||||
end
|
||||
end
|
||||
|
||||
local function branch(options)
|
||||
if not options.icon then
|
||||
options.icon = '' -- e0a0
|
||||
end
|
||||
|
||||
return function()
|
||||
if not git_branch or #git_branch == 0 then return '' end
|
||||
return git_branch
|
||||
end
|
||||
end
|
||||
|
||||
-- run watch head on load so branch is present when component is loaded
|
||||
watch_head()
|
||||
|
||||
-- update branch state of BufEnter as different Buffer may be on different repos
|
||||
vim.cmd [[autocmd BufEnter * lua require'lualine.components.branch'.lualine_branch_update()]]
|
||||
|
||||
return {
|
||||
init = function(options) return branch(options) end,
|
||||
lualine_branch_update = watch_head
|
||||
}
|
||||
return Branch
|
||||
|
|
|
@ -3,13 +3,106 @@
|
|||
local highlight = require('lualine.highlight')
|
||||
local utils = require('lualine.utils.utils')
|
||||
|
||||
local Diagnostics = require('lualine.component'):new()
|
||||
|
||||
-- LuaFormatter off
|
||||
local default_color_error = '#e32636'
|
||||
local default_color_warn = '#ffdf00'
|
||||
local default_color_info = '#ffffff'
|
||||
Diagnostics.default_colors = {
|
||||
error = '#e32636',
|
||||
warn = '#ffdf00',
|
||||
info = '#ffffff',
|
||||
}
|
||||
-- LuaFormatter on
|
||||
|
||||
local diagnostic_sources = {
|
||||
-- Initializer
|
||||
Diagnostics.new = function(self, options, child)
|
||||
local new_diagnostics = self._parent:new(options, child or Diagnostics)
|
||||
local default_symbols = new_diagnostics.options.icons_enabled and {
|
||||
error = ' ', -- xf659
|
||||
warn = ' ', -- xf529
|
||||
info = ' ' -- xf7fc
|
||||
} or {error = 'E:', warn = 'W:', info = 'I:'}
|
||||
new_diagnostics.symbols = vim.tbl_extend('force', default_symbols,
|
||||
new_diagnostics.options.symbols or {})
|
||||
if new_diagnostics.options.sources == nil then
|
||||
print('no sources for diagnostics configured')
|
||||
return ''
|
||||
end
|
||||
if new_diagnostics.options.sections == nil then
|
||||
new_diagnostics.options.sections = {'error', 'warn', 'info'}
|
||||
end
|
||||
if new_diagnostics.options.colored == nil then
|
||||
new_diagnostics.options.colored = true
|
||||
end
|
||||
-- apply colors
|
||||
if not new_diagnostics.options.color_error then
|
||||
new_diagnostics.options.color_error =
|
||||
utils.extract_highlight_colors('DiffDelete', 'guifg') or
|
||||
Diagnostics.default_colors.error
|
||||
end
|
||||
if not new_diagnostics.options.color_warn then
|
||||
new_diagnostics.options.color_warn =
|
||||
utils.extract_highlight_colors('DiffText', 'guifg') or
|
||||
Diagnostics.default_colors.warn
|
||||
end
|
||||
if not new_diagnostics.options.color_info then
|
||||
new_diagnostics.options.color_info =
|
||||
utils.extract_highlight_colors('Normal', 'guifg') or
|
||||
Diagnostics.default_colors.info
|
||||
end
|
||||
|
||||
if new_diagnostics.options.colored then
|
||||
new_diagnostics.highlight_groups = {
|
||||
error = highlight.create_component_highlight_group(
|
||||
{fg = new_diagnostics.options.color_error}, 'diagnostics_error',
|
||||
new_diagnostics.options),
|
||||
warn = highlight.create_component_highlight_group(
|
||||
{fg = new_diagnostics.options.color_warn}, 'diagnostics_warn',
|
||||
new_diagnostics.options),
|
||||
info = highlight.create_component_highlight_group(
|
||||
{fg = new_diagnostics.options.color_info}, 'diagnostics_info',
|
||||
new_diagnostics.options)
|
||||
}
|
||||
end
|
||||
|
||||
return new_diagnostics
|
||||
end
|
||||
|
||||
Diagnostics.update_status = function(self)
|
||||
local error_count, warning_count, info_count = 0, 0, 0
|
||||
local diagnostic_data = self.get_diagnostics(self.options.sources)
|
||||
for _, data in pairs(diagnostic_data) do
|
||||
error_count = error_count + data.error
|
||||
warning_count = warning_count + data.warn
|
||||
info_count = info_count + data.info
|
||||
end
|
||||
local result = {}
|
||||
local data = {error = error_count, warn = warning_count, info = info_count}
|
||||
if self.options.colored then
|
||||
local colors = {}
|
||||
for name, hl in pairs(self.highlight_groups) do
|
||||
colors[name] = highlight.component_format_highlight(hl)
|
||||
end
|
||||
for _, section in ipairs(self.options.sections) do
|
||||
if data[section] ~= nil and data[section] > 0 then
|
||||
table.insert(result,
|
||||
colors[section] .. self.symbols[section] .. data[section])
|
||||
end
|
||||
end
|
||||
else
|
||||
for _, section in ipairs(self.options.sections) do
|
||||
if data[section] ~= nil and data[section] > 0 then
|
||||
table.insert(result, self.symbols[section] .. data[section])
|
||||
end
|
||||
end
|
||||
end
|
||||
if result[1] ~= nil then
|
||||
return table.concat(result, ' ')
|
||||
else
|
||||
return ''
|
||||
end
|
||||
end
|
||||
|
||||
Diagnostics.diagnostic_sources = {
|
||||
nvim_lsp = function()
|
||||
local error_count = vim.lsp.diagnostic.get_count(0, 'Error')
|
||||
local warning_count = vim.lsp.diagnostic.get_count(0, 'Warning')
|
||||
|
@ -32,21 +125,14 @@ local diagnostic_sources = {
|
|||
else
|
||||
return 0, 0, 0
|
||||
end
|
||||
end,
|
||||
vim_lsp = function()
|
||||
local ok, data = pcall(vim.fn['lsp#get_buffer_diagnostics_counts'])
|
||||
if ok then
|
||||
return data.error, data.warning, data.information
|
||||
else
|
||||
return 0, 0, 0
|
||||
end
|
||||
end
|
||||
}
|
||||
|
||||
local function get_diagnostics(sources)
|
||||
Diagnostics.get_diagnostics = function(sources)
|
||||
local result = {}
|
||||
for index, source in ipairs(sources) do
|
||||
local error_count, warning_count, info_count = diagnostic_sources[source]()
|
||||
local error_count, warning_count, info_count =
|
||||
Diagnostics.diagnostic_sources[source]()
|
||||
result[index] = {
|
||||
error = error_count,
|
||||
warn = warning_count,
|
||||
|
@ -56,84 +142,4 @@ local function get_diagnostics(sources)
|
|||
return result
|
||||
end
|
||||
|
||||
local function diagnostics(options)
|
||||
local default_symbols = options.icons_enabled and {
|
||||
error = ' ', -- xf659
|
||||
warn = ' ', -- xf529
|
||||
info = ' ' -- xf7fc
|
||||
} or {error = 'E:', warn = 'W:', info = 'I:'}
|
||||
options.symbols = vim.tbl_extend('force', default_symbols,
|
||||
options.symbols or {})
|
||||
if options.sources == nil then
|
||||
print('no sources for diagnostics configured')
|
||||
return ''
|
||||
end
|
||||
if options.sections == nil then options.sections = {'error', 'warn', 'info'} end
|
||||
if options.colored == nil then options.colored = true end
|
||||
-- apply colors
|
||||
if not options.color_error then
|
||||
options.color_error =
|
||||
utils.extract_highlight_colors('DiffDelete', 'guifg') or
|
||||
default_color_error
|
||||
end
|
||||
if not options.color_warn then
|
||||
options.color_warn = utils.extract_highlight_colors('DiffText', 'guifg') or
|
||||
default_color_warn
|
||||
end
|
||||
if not options.color_info then
|
||||
options.color_info = utils.extract_highlight_colors('Normal', 'guifg') or
|
||||
default_color_info
|
||||
end
|
||||
|
||||
local highlight_groups = {}
|
||||
if options.colored then
|
||||
highlight_groups = {
|
||||
error = highlight.create_component_highlight_group(
|
||||
{fg = options.color_error}, 'diagnostics_error', options),
|
||||
warn = highlight.create_component_highlight_group(
|
||||
{fg = options.color_warn}, 'diagnostics_warn', options),
|
||||
info = highlight.create_component_highlight_group(
|
||||
{fg = options.color_info}, 'diagnostics_info', options)
|
||||
}
|
||||
end
|
||||
|
||||
return function()
|
||||
local error_count, warning_count, info_count = 0, 0, 0
|
||||
local diagnostic_data = get_diagnostics(options.sources)
|
||||
for _, data in pairs(diagnostic_data) do
|
||||
error_count = error_count + data.error
|
||||
warning_count = warning_count + data.warn
|
||||
info_count = info_count + data.info
|
||||
end
|
||||
local result = {}
|
||||
local data = {error = error_count, warn = warning_count, info = info_count}
|
||||
if options.colored then
|
||||
local colors = {}
|
||||
for name, hl in pairs(highlight_groups) do
|
||||
colors[name] = highlight.component_format_highlight(hl)
|
||||
end
|
||||
for _, section in ipairs(options.sections) do
|
||||
if data[section] ~= nil and data[section] > 0 then
|
||||
table.insert(result, colors[section] .. options.symbols[section] ..
|
||||
data[section])
|
||||
end
|
||||
end
|
||||
else
|
||||
for _, section in ipairs(options.sections) do
|
||||
if data[section] ~= nil and data[section] > 0 then
|
||||
table.insert(result, options.symbols[section] .. data[section])
|
||||
end
|
||||
end
|
||||
end
|
||||
if result[1] ~= nil then
|
||||
return table.concat(result, ' ')
|
||||
else
|
||||
return ''
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return {
|
||||
init = function(options) return diagnostics(options) end,
|
||||
get_diagnostics = get_diagnostics
|
||||
}
|
||||
return Diagnostics
|
||||
|
|
|
@ -4,13 +4,120 @@ local async = require 'lualine.utils.async'
|
|||
local utils = require 'lualine.utils.utils'
|
||||
local highlight = require 'lualine.highlight'
|
||||
|
||||
local Diff = require('lualine.component'):new()
|
||||
|
||||
-- Vars
|
||||
-- variable to store git diff stats
|
||||
local git_diff = nil
|
||||
Diff.git_diff = nil
|
||||
-- accumulates async output to process in the end
|
||||
local diff_data = ''
|
||||
Diff.diff_data = ''
|
||||
-- variable to store git_diff getter async function
|
||||
Diff.get_git_diff = nil
|
||||
-- default colors
|
||||
Diff.default_colors = {
|
||||
added = '#f0e130',
|
||||
removed = '#90ee90',
|
||||
modified = '#ff0038'
|
||||
}
|
||||
|
||||
-- Initializer
|
||||
Diff.new = function(self, options, child)
|
||||
local new_instence = self._parent:new(options, child or Diff)
|
||||
local default_symbols = {added = '+', modified = '~', removed = '-'}
|
||||
new_instence.options.symbols = vim.tbl_extend('force', default_symbols,
|
||||
new_instence.options.symbols or
|
||||
{})
|
||||
if new_instence.options.colored == nil then
|
||||
new_instence.options.colored = true
|
||||
end
|
||||
-- apply colors
|
||||
if not new_instence.options.color_added then
|
||||
new_instence.options.color_added = utils.extract_highlight_colors('DiffAdd',
|
||||
'guifg') or
|
||||
Diff.default_colors.added
|
||||
end
|
||||
if not new_instence.options.color_modified then
|
||||
new_instence.options.color_modified =
|
||||
utils.extract_highlight_colors('DiffChange', 'guifg') or
|
||||
Diff.default_colors.modified
|
||||
end
|
||||
if not new_instence.options.color_removed then
|
||||
new_instence.options.color_removed =
|
||||
utils.extract_highlight_colors('DiffDelete', 'guifg') or
|
||||
Diff.default_colors.removed
|
||||
end
|
||||
|
||||
-- create highlights and save highlight_name in highlights table
|
||||
if new_instence.options.colored then
|
||||
new_instence.highlights = {
|
||||
added = highlight.create_component_highlight_group(
|
||||
{fg = new_instence.options.color_added}, 'diff_added',
|
||||
new_instence.options),
|
||||
modified = highlight.create_component_highlight_group(
|
||||
{fg = new_instence.options.color_modified}, 'diff_modified',
|
||||
new_instence.options),
|
||||
removed = highlight.create_component_highlight_group(
|
||||
{fg = new_instence.options.color_removed}, 'diff_removed',
|
||||
new_instence.options)
|
||||
}
|
||||
end
|
||||
|
||||
vim.api.nvim_exec([[
|
||||
autocmd lualine BufEnter * lua require'lualine.components.diff'.update_git_diff_getter()
|
||||
autocmd lualine BufEnter * lua require'lualine.components.diff'.update_git_diff()
|
||||
autocmd lualine BufWritePost * lua require'lualine.components.diff'.update_git_diff()
|
||||
]], false)
|
||||
|
||||
return new_instence
|
||||
end
|
||||
|
||||
-- Function that runs everytime statusline is updated
|
||||
Diff.update_status = function(self)
|
||||
if Diff.git_diff == nil then return '' end
|
||||
|
||||
local colors = {}
|
||||
if self.options.colored then
|
||||
-- load the highlights and store them in colors table
|
||||
for name, highlight_name in pairs(self.highlights) do
|
||||
colors[name] = highlight.component_format_highlight(highlight_name)
|
||||
end
|
||||
end
|
||||
|
||||
local result = {}
|
||||
-- loop though data and load available sections in result table
|
||||
for _, name in ipairs {'added', 'modified', 'removed'} do
|
||||
if Diff.git_diff[name] and Diff.git_diff[name] > 0 then
|
||||
if self.options.colored then
|
||||
table.insert(result, colors[name] .. self.options.symbols[name] ..
|
||||
Diff.git_diff[name])
|
||||
else
|
||||
table.insert(result, self.options.symbols[name] .. Diff.git_diff[name])
|
||||
end
|
||||
end
|
||||
end
|
||||
if #result > 0 then
|
||||
return table.concat(result, ' ')
|
||||
else
|
||||
return ''
|
||||
end
|
||||
end
|
||||
|
||||
-- Api to get git sign count
|
||||
-- scheme :
|
||||
-- {
|
||||
-- added = added_count,
|
||||
-- modified = modified_count,
|
||||
-- removed = removed_count,
|
||||
-- }
|
||||
-- error_code = { added = -1, modified = -1, removed = -1 }
|
||||
function Diff.get_sign_count()
|
||||
Diff.update_git_diff_getter()
|
||||
Diff.update_git_diff()
|
||||
return Diff.git_diff or {added = -1, modified = -1, removed = -1}
|
||||
end
|
||||
|
||||
-- process diff data and update git_diff{ added, removed, modified }
|
||||
local function process_diff(data)
|
||||
function Diff.process_diff(data)
|
||||
-- Adapted from https://github.com/wbthomason/nvim-vcs.lua
|
||||
local added, removed, modified = 0, 0, 0
|
||||
for line in vim.gsplit(data, '\n') do
|
||||
|
@ -34,149 +141,50 @@ local function process_diff(data)
|
|||
end
|
||||
end
|
||||
end
|
||||
git_diff = {added = added, modified = modified, removed = removed}
|
||||
Diff.git_diff = {added = added, modified = modified, removed = removed}
|
||||
end
|
||||
|
||||
-- variable to store git_diff getter async function
|
||||
local get_git_diff = nil
|
||||
|
||||
-- Updates the async function for current file
|
||||
local function update_git_diff_getter()
|
||||
function Diff.update_git_diff_getter()
|
||||
-- stop older function properly before overwritting it
|
||||
if get_git_diff then get_git_diff:stop() end
|
||||
if Diff.get_git_diff then Diff.get_git_diff:stop() end
|
||||
-- Donn't show git diff when current buffer doesn't have a filename
|
||||
if #vim.fn.expand('%') == 0 then
|
||||
get_git_diff = nil;
|
||||
git_diff = nil;
|
||||
Diff.get_git_diff = nil;
|
||||
Diff.git_diff = nil;
|
||||
return
|
||||
end
|
||||
get_git_diff = async:new({
|
||||
Diff.get_git_diff = async:new({
|
||||
cmd = string.format(
|
||||
[[git -C %s --no-pager diff --no-color --no-ext-diff -U0 -- %s]],
|
||||
vim.fn.expand('%:h'), vim.fn.expand('%:t')),
|
||||
on_stdout = function(_, data)
|
||||
if data then diff_data = diff_data .. data end
|
||||
if data then Diff.diff_data = Diff.diff_data .. data end
|
||||
end,
|
||||
on_stderr = function(_, data)
|
||||
if data then
|
||||
git_diff = nil
|
||||
diff_data = ''
|
||||
Diff.git_diff = nil
|
||||
Diff.diff_data = ''
|
||||
end
|
||||
end,
|
||||
on_exit = function()
|
||||
if diff_data ~= '' then
|
||||
process_diff(diff_data)
|
||||
if Diff.diff_data ~= '' then
|
||||
Diff.process_diff(Diff.diff_data)
|
||||
else
|
||||
git_diff = {added = 0, modified = 0, removed = 0}
|
||||
Diff.git_diff = {added = 0, modified = 0, removed = 0}
|
||||
end
|
||||
end
|
||||
})
|
||||
end
|
||||
|
||||
-- Update git_diff veriable
|
||||
local function update_git_diff()
|
||||
function Diff.update_git_diff()
|
||||
vim.schedule_wrap(function()
|
||||
if get_git_diff then
|
||||
diff_data = ''
|
||||
get_git_diff:start()
|
||||
if Diff.get_git_diff then
|
||||
Diff.diff_data = ''
|
||||
Diff.get_git_diff:start()
|
||||
end
|
||||
end)()
|
||||
end
|
||||
|
||||
local default_color_added = '#f0e130'
|
||||
local default_color_removed = '#90ee90'
|
||||
local default_color_modified = '#ff0038'
|
||||
|
||||
local function diff(options)
|
||||
if options.colored == nil then options.colored = true end
|
||||
-- apply colors
|
||||
if not options.color_added then
|
||||
options.color_added = utils.extract_highlight_colors('DiffAdd', 'guifg') or
|
||||
default_color_added
|
||||
end
|
||||
if not options.color_modified then
|
||||
options.color_modified = utils.extract_highlight_colors('DiffChange',
|
||||
'guifg') or
|
||||
default_color_modified
|
||||
end
|
||||
if not options.color_removed then
|
||||
options.color_removed =
|
||||
utils.extract_highlight_colors('DiffDelete', 'guifg') or
|
||||
default_color_removed
|
||||
end
|
||||
|
||||
local highlights = {}
|
||||
|
||||
-- create highlights and save highlight_name in highlights table
|
||||
if options.colored then
|
||||
highlights = {
|
||||
added = highlight.create_component_highlight_group(
|
||||
{fg = options.color_added}, 'diff_added', options),
|
||||
modified = highlight.create_component_highlight_group(
|
||||
{fg = options.color_modified}, 'diff_modified', options),
|
||||
removed = highlight.create_component_highlight_group(
|
||||
{fg = options.color_removed}, 'diff_removed', options)
|
||||
}
|
||||
end
|
||||
|
||||
vim.api.nvim_exec([[
|
||||
autocmd lualine BufEnter * lua require'lualine.components.diff'.update_git_diff_getter()
|
||||
autocmd lualine BufEnter * lua require'lualine.components.diff'.update_git_diff()
|
||||
autocmd lualine BufWritePost * lua require'lualine.components.diff'.update_git_diff()
|
||||
]], false)
|
||||
|
||||
-- Function that runs everytime statusline is updated
|
||||
return function()
|
||||
if git_diff == nil then return '' end
|
||||
|
||||
local default_symbols = {added = '+', modified = '~', removed = '-'}
|
||||
options.symbols = vim.tbl_extend('force', default_symbols,
|
||||
options.symbols or {})
|
||||
local colors = {}
|
||||
if options.colored then
|
||||
-- load the highlights and store them in colors table
|
||||
for name, highlight_name in pairs(highlights) do
|
||||
colors[name] = highlight.component_format_highlight(highlight_name)
|
||||
end
|
||||
end
|
||||
|
||||
local result = {}
|
||||
-- loop though data and load available sections in result table
|
||||
for _, name in ipairs {'added', 'modified', 'removed'} do
|
||||
if git_diff[name] and git_diff[name] > 0 then
|
||||
if options.colored then
|
||||
table.insert(result,
|
||||
colors[name] .. options.symbols[name] .. git_diff[name])
|
||||
else
|
||||
table.insert(result, options.symbols[name] .. git_diff[name])
|
||||
end
|
||||
end
|
||||
end
|
||||
if #result > 0 then
|
||||
return table.concat(result, ' ')
|
||||
else
|
||||
return ''
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Api to get git sign count
|
||||
-- scheme :
|
||||
-- {
|
||||
-- added = added_count,
|
||||
-- modified = modified_count,
|
||||
-- removed = removed_count,
|
||||
-- }
|
||||
-- error_code = { added = -1, modified = -1, removed = -1 }
|
||||
local function get_sign_count()
|
||||
update_git_diff_getter()
|
||||
update_git_diff()
|
||||
return git_diff or {added = -1, modified = -1, removed = -1}
|
||||
end
|
||||
|
||||
return {
|
||||
init = function(options) return diff(options) end,
|
||||
update_git_diff = update_git_diff,
|
||||
update_git_diff_getter = update_git_diff_getter,
|
||||
get_sign_count = get_sign_count
|
||||
}
|
||||
return Diff
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
-- Copyright (c) 2020-2021 hoob3rt
|
||||
-- MIT license, see LICENSE for more details.
|
||||
local function encoding()
|
||||
local data = [[%{strlen(&fenc)?&fenc:&enc}]]
|
||||
return data
|
||||
end
|
||||
local Encoding = require('lualine.component'):new()
|
||||
|
||||
return encoding
|
||||
Encoding.update_status = function() return [[%{strlen(&fenc)?&fenc:&enc}]] end
|
||||
|
||||
return Encoding
|
||||
|
|
|
@ -1,22 +1,19 @@
|
|||
-- Copyright (c) 2020-2021 shadmansaleh
|
||||
-- MIT license, see LICENSE for more details.
|
||||
local function fileformat(options)
|
||||
local icon_linux = '' -- e712
|
||||
local icon_windos = '' -- e70f
|
||||
local icon_mac = '' -- e711
|
||||
return function()
|
||||
if options.icons_enabled and not options.icon then
|
||||
local FileFormat = require('lualine.component'):new()
|
||||
|
||||
FileFormat.icon = {
|
||||
unix = '', -- e712
|
||||
dos = '', -- e70f
|
||||
mac = '' -- e711
|
||||
}
|
||||
|
||||
FileFormat.update_status = function(self)
|
||||
if self.options.icons_enabled and not self.options.icon then
|
||||
local format = vim.bo.fileformat
|
||||
if format == 'unix' then
|
||||
return icon_linux
|
||||
elseif format == 'dos' then
|
||||
return icon_windos
|
||||
elseif format == 'mac' then
|
||||
return icon_mac
|
||||
end
|
||||
return FileFormat.icon[format] or format
|
||||
end
|
||||
return vim.bo.fileformat
|
||||
end
|
||||
end
|
||||
|
||||
return {init = function(options) return fileformat(options) end}
|
||||
return FileFormat
|
||||
|
|
|
@ -1,27 +1,39 @@
|
|||
-- Copyright (c) 2020-2021 shadmansaleh
|
||||
-- MIT license, see LICENSE for more details.
|
||||
local function filename(options)
|
||||
-- setting defaults
|
||||
if options.file_status == nil then options.file_status = true end
|
||||
if options.shorten == nil then options.shorten = true end
|
||||
if options.full_path == nil then options.full_path = false end
|
||||
local FileName = require('lualine.component'):new()
|
||||
|
||||
return function()
|
||||
local data
|
||||
if not options.full_path then
|
||||
data = vim.fn.expand('%:t')
|
||||
elseif options.shorten then
|
||||
data = vim.fn.expand('%:~:.')
|
||||
else
|
||||
data = vim.fn.expand('%:p')
|
||||
FileName.new = function(self, options, child)
|
||||
local new_instence = self._parent:new(options, child or FileName)
|
||||
|
||||
-- setting defaults
|
||||
if new_instence.options.file_status == nil then
|
||||
new_instence.options.file_status = true
|
||||
end
|
||||
if new_instence.options.shorten == nil then
|
||||
new_instence.options.shorten = true
|
||||
end
|
||||
if new_instence.options.full_path == nil then
|
||||
new_instence.options.full_path = false
|
||||
end
|
||||
|
||||
return new_instence
|
||||
end
|
||||
|
||||
FileName.update_status = function(self)
|
||||
local data = vim.fn.expand('%:p')
|
||||
if not self.options.full_path then
|
||||
data = vim.fn.expand('%:t')
|
||||
elseif self.options.shorten then
|
||||
data = vim.fn.expand('%:~:.')
|
||||
end
|
||||
|
||||
if data == '' then
|
||||
data = '[No Name]'
|
||||
elseif vim.fn.winwidth(0) <= 84 or #data > 40 then
|
||||
data = vim.fn.pathshorten(data)
|
||||
end
|
||||
|
||||
if options.file_status then
|
||||
if self.options.file_status then
|
||||
if vim.bo.modified then
|
||||
data = data .. '[+]'
|
||||
elseif vim.bo.modifiable == false or vim.bo.readonly == true then
|
||||
|
@ -30,6 +42,5 @@ local function filename(options)
|
|||
end
|
||||
return data
|
||||
end
|
||||
end
|
||||
|
||||
return {init = function(options) return filename(options) end}
|
||||
return FileName
|
||||
|
|
|
@ -1,23 +1,23 @@
|
|||
-- Copyright (c) 2020-2021 hoob3rt
|
||||
-- MIT license, see LICENSE for more details.
|
||||
local function filetype(options)
|
||||
return function()
|
||||
local FileType = require('lualine.component'):new()
|
||||
|
||||
FileType.update_status = function(self)
|
||||
local data = vim.bo.filetype
|
||||
if #data > 0 then
|
||||
local ok, devicons = pcall(require, 'nvim-web-devicons')
|
||||
if ok then
|
||||
local f_name, f_extension = vim.fn.expand('%:t'), vim.fn.expand('%:e')
|
||||
options.icon = devicons.get_icon(f_name, f_extension)
|
||||
self.options.icon = devicons.get_icon(f_name, f_extension)
|
||||
else
|
||||
ok = vim.fn.exists('*WebDevIconsGetFileTypeSymbol')
|
||||
if ok ~= 0 then
|
||||
options.icon = vim.fn.WebDevIconsGetFileTypeSymbol()
|
||||
self.options.icon = vim.fn.WebDevIconsGetFileTypeSymbol()
|
||||
end
|
||||
end
|
||||
return data
|
||||
end
|
||||
return ''
|
||||
end
|
||||
end
|
||||
|
||||
return {init = function(options) return filetype(options) end}
|
||||
return FileType
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
-- Copyright (c) 2020-2021 hoob3rt
|
||||
-- MIT license, see LICENSE for more details.
|
||||
local function hostname()
|
||||
local data = vim.loop.os_gethostname()
|
||||
return data
|
||||
end
|
||||
local HostName = require('lualine.component'):new()
|
||||
|
||||
return hostname
|
||||
HostName.update_status = vim.loop.os_gethostname()
|
||||
|
||||
return HostName
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
-- Copyright (c) 2020-2021 hoob3rt
|
||||
-- MIT license, see LICENSE for more details.
|
||||
local function location()
|
||||
local data = [[%3l:%-2c]]
|
||||
return data
|
||||
end
|
||||
local Location = require('lualine.component'):new()
|
||||
|
||||
return location
|
||||
Location.update_status = function() return [[%3l:%-2c]] end
|
||||
|
||||
return Location
|
||||
|
|
|
@ -1,42 +1,8 @@
|
|||
-- Copyright (c) 2020-2021 hoob3rt
|
||||
-- MIT license, see LICENSE for more details.
|
||||
-- LuaFormatter off
|
||||
local mode_map = {
|
||||
['n'] = 'NORMAL',
|
||||
['no'] = 'O-PENDING',
|
||||
['nov'] = 'O-PENDING',
|
||||
['noV'] = 'O-PENDING',
|
||||
['no'] = 'O-PENDING',
|
||||
['niI'] = 'NORMAL',
|
||||
['niR'] = 'NORMAL',
|
||||
['niV'] = 'NORMAL',
|
||||
['v'] = 'VISUAL',
|
||||
['V'] = 'V-LINE',
|
||||
[''] = 'V-BLOCK',
|
||||
['s'] = 'SELECT',
|
||||
['S'] = 'S-LINE',
|
||||
[''] = 'S-BLOCK',
|
||||
['i'] = 'INSERT',
|
||||
['ic'] = 'INSERT',
|
||||
['ix'] = 'INSERT',
|
||||
['R'] = 'REPLACE',
|
||||
['Rc'] = 'REPLACE',
|
||||
['Rv'] = 'V-REPLACE',
|
||||
['Rx'] = 'REPLACE',
|
||||
['c'] = 'COMMAND',
|
||||
['cv'] = 'EX',
|
||||
['ce'] = 'EX',
|
||||
['r'] = 'REPLACE',
|
||||
['rm'] = 'MORE',
|
||||
['r?'] = 'CONFIRM',
|
||||
['!'] = 'SHELL',
|
||||
['t'] = 'TERMINAL',
|
||||
}
|
||||
-- LuaFormatter on
|
||||
local function mode()
|
||||
local mode_code = vim.api.nvim_get_mode().mode
|
||||
if mode_map[mode_code] == nil then return mode_code end
|
||||
return mode_map[mode_code]
|
||||
end
|
||||
local Mode = require('lualine.component'):new()
|
||||
local get_mode = require('lualine.utils.mode').get_mode
|
||||
|
||||
return mode
|
||||
Mode.update_status = get_mode
|
||||
|
||||
return Mode
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
-- Copyright (c) 2020-2021 hoob3rt
|
||||
-- MIT license, see LICENSE for more details.
|
||||
local function progress()
|
||||
local data = [[%3P]]
|
||||
return data
|
||||
end
|
||||
local Progress = require('lualine.component'):new()
|
||||
|
||||
return progress
|
||||
Progress.update_status = function() return [[%3P]] end
|
||||
|
||||
return Progress
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
local EvalFuncComponent = require('lualine.component'):new()
|
||||
|
||||
EvalFuncComponent.update_status = function(self)
|
||||
local component = self.options[1]
|
||||
local ok, status = EvalFuncComponent.evallua(component)
|
||||
if not ok then status = EvalFuncComponent.vim_function(component) end
|
||||
return status
|
||||
end
|
||||
|
||||
EvalFuncComponent.evallua = function(code)
|
||||
if loadstring(string.format('return %s ~= nil', code)) and
|
||||
loadstring(string.format([[return %s ~= nil]], code))() then
|
||||
-- lua veriable component
|
||||
return true, loadstring(string.format(
|
||||
[[
|
||||
local ok, return_val = pcall(tostring, %s)
|
||||
if ok then return return_val end
|
||||
return '']], code))()
|
||||
end
|
||||
return false, ''
|
||||
end
|
||||
|
||||
EvalFuncComponent.vim_function = function(name)
|
||||
-- vim function component
|
||||
local ok, return_val = pcall(vim.fn[name])
|
||||
if not ok then return '' end -- function call failed
|
||||
ok, return_val = pcall(tostring, return_val)
|
||||
if ok then
|
||||
return return_val
|
||||
else
|
||||
return ''
|
||||
end
|
||||
end
|
||||
|
||||
return EvalFuncComponent
|
|
@ -0,0 +1,9 @@
|
|||
local FunctionComponent = require('lualine.component'):new()
|
||||
|
||||
FunctionComponent.new = function(self, options, child)
|
||||
local new_instence = self._parent:new(options, child or FunctionComponent)
|
||||
new_instence.update_status = options[1]
|
||||
return new_instence
|
||||
end
|
||||
|
||||
return FunctionComponent
|
|
@ -0,0 +1,19 @@
|
|||
local VarComponent = require('lualine.component'):new()
|
||||
VarComponent.update_status = function(self)
|
||||
local component = self.options[1]
|
||||
-- vim veriable component
|
||||
-- accepts g:, v:, t:, w:, b:, o, go:, vo:, to:, wo:, bo:
|
||||
-- filters g portion from g:var
|
||||
local scope = component:match('[gvtwb]?o?')
|
||||
-- filters var portion from g:var
|
||||
local var_name = component:sub(#scope + 2, #component)
|
||||
-- Displays nothing when veriable aren't present
|
||||
local return_val = vim[scope][var_name]
|
||||
if return_val == nil then return '' end
|
||||
local ok
|
||||
ok, return_val = pcall(tostring, return_val)
|
||||
if ok then return return_val end
|
||||
return ''
|
||||
end
|
||||
|
||||
return VarComponent
|
|
@ -42,7 +42,7 @@ end
|
|||
-- @param highlight_group:(string) name of highlight group
|
||||
-- @return: (string) highlight group name with mode
|
||||
local function append_mode(highlight_group)
|
||||
local mode = require('lualine.components.mode')()
|
||||
local mode = require('lualine.utils.mode').get_mode()
|
||||
if mode == 'VISUAL' or mode == 'V-BLOCK' or mode == 'V-LINE' or mode ==
|
||||
'SELECT' or mode == 'S-LINE' or mode == 'S-BLOCK' then
|
||||
highlight_group = highlight_group .. '_visual'
|
||||
|
@ -159,7 +159,7 @@ function M.get_transitional_highlights(left_section_data, right_section_data,
|
|||
-- Grab the last highlighter of left section
|
||||
if left_section_data then
|
||||
-- extract highlight_name from .....%#highlight_name#
|
||||
left_highlight_name = left_section_data:match('.*%%#(.*)#')
|
||||
left_highlight_name = left_section_data:match('.*%%#(.-)#')
|
||||
else
|
||||
-- When right section us unavailable default to lualine_c
|
||||
left_highlight_name = append_mode('lualine_c')
|
||||
|
@ -168,10 +168,8 @@ function M.get_transitional_highlights(left_section_data, right_section_data,
|
|||
end
|
||||
end
|
||||
if right_section_data then
|
||||
-- using vim-regex cause lua-paterns don't have non-greedy matching
|
||||
-- extract highlight_name from %#highlight_name#....
|
||||
right_highlight_name = vim.fn.matchlist(right_section_data,
|
||||
[[%#\(.\{-\}\)#]])[2]
|
||||
right_highlight_name = right_section_data:match('%%#(.-)#.*')
|
||||
else
|
||||
-- When right section us unavailable default to lualine_c
|
||||
right_highlight_name = append_mode('lualine_c')
|
||||
|
|
|
@ -57,70 +57,25 @@ local function check_single_separator()
|
|||
end
|
||||
end
|
||||
|
||||
local function load_special_components(component)
|
||||
return function()
|
||||
-- precedence lualine_component > vim_var > lua_var > vim_function
|
||||
if component:find('[gvtwb]?o?:') == 1 then
|
||||
-- vim veriable component
|
||||
-- accepts g:, v:, t:, w:, b:, o, go:, vo:, to:, wo:, bo:
|
||||
-- filters g portion from g:var
|
||||
local scope = component:match('[gvtwb]?o?')
|
||||
-- filters var portion from g:var
|
||||
local var_name = component:sub(#scope + 2, #component)
|
||||
-- Displays nothing when veriable aren't present
|
||||
local return_val = vim[scope][var_name]
|
||||
if return_val == nil then return '' end
|
||||
local ok
|
||||
ok, return_val = pcall(tostring, return_val)
|
||||
if ok then return return_val end
|
||||
return ''
|
||||
elseif loadstring(string.format('return %s ~= nil', component)) and
|
||||
loadstring(string.format([[return %s ~= nil]], component))() then
|
||||
-- lua veriable component
|
||||
return loadstring(string.format([[
|
||||
local ok, return_val = pcall(tostring, %s)
|
||||
if ok then return return_val end
|
||||
return '']], component))()
|
||||
else
|
||||
-- vim function component
|
||||
local ok, return_val = pcall(vim.fn[component])
|
||||
if not ok then return '' end -- function call failed
|
||||
ok, return_val = pcall(tostring, return_val)
|
||||
if ok then
|
||||
return return_val
|
||||
else
|
||||
return ''
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function component_loader(component)
|
||||
if type(component[1]) == 'function' then return component end
|
||||
if type(component[1]) == 'function' then
|
||||
return require 'lualine.components.special.functon_component':new(component)
|
||||
end
|
||||
if type(component[1]) == 'string' then
|
||||
-- Keep component name for later use as component[1] will be overwritten
|
||||
-- With component function
|
||||
component.component_name = component[1]
|
||||
-- apply default args
|
||||
for opt_name, opt_val in pairs(config.options) do
|
||||
if component[opt_name] == nil then component[opt_name] = opt_val end
|
||||
end
|
||||
-- load the component
|
||||
local ok, loaded_component = pcall(require, 'lualine.components.' ..
|
||||
component.component_name)
|
||||
if not ok then
|
||||
loaded_component = load_special_components(component.component_name)
|
||||
end
|
||||
component[1] = loaded_component
|
||||
if type(component[1]) == 'table' then
|
||||
component[1] = component[1].init(component)
|
||||
end
|
||||
-- set custom highlights
|
||||
if component.color then
|
||||
component.color_highlight = highlight.create_component_highlight_group(
|
||||
component.color, component.component_name,
|
||||
component)
|
||||
local ok, loaded_component = pcall(require,
|
||||
'lualine.components.' .. component[1])
|
||||
if ok then
|
||||
component.component_name = component[1]
|
||||
loaded_component = loaded_component:new(component)
|
||||
elseif component[1]:find('[gvtwb]?o?:') == 1 then
|
||||
loaded_component =
|
||||
require 'lualine.components.special.vim_var_component':new(component)
|
||||
else
|
||||
loaded_component =
|
||||
require 'lualine.components.special.eval_func_component':new(component)
|
||||
end
|
||||
return loaded_component
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -132,8 +87,9 @@ local function load_sections(sections)
|
|||
end
|
||||
component.self = {}
|
||||
component.self.section = section_name
|
||||
component_loader(component)
|
||||
section[index] = component
|
||||
-- apply default args
|
||||
component = vim.tbl_extend('keep', component, config.options)
|
||||
section[index] = component_loader(component)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,82 +0,0 @@
|
|||
-- Copyright (c) 2020-2021 shadmansaleh
|
||||
-- MIT license, see LICENSE for more details.
|
||||
local M = {}
|
||||
|
||||
local highlight = require 'lualine.highlight'
|
||||
|
||||
-- set upper or lower case
|
||||
function M.apply_case(status, options)
|
||||
-- Donn't work on components that emit vim statusline escaped chars
|
||||
if status:find('%%') and not status:find('%%%%') then return status end
|
||||
if options.upper == true then
|
||||
return status:upper()
|
||||
elseif options.lower == true then
|
||||
return status:lower()
|
||||
end
|
||||
return status
|
||||
end
|
||||
|
||||
-- Adds spaces to left and right of a component
|
||||
function M.apply_padding(status, options)
|
||||
local l_padding = (options.left_padding or options.padding or 1)
|
||||
local r_padding = (options.right_padding or options.padding or 1)
|
||||
if l_padding then
|
||||
if status:find('%%#.*#') == 1 then
|
||||
-- When component has changed the highlight at begining
|
||||
-- we will add the padding after the highlight
|
||||
local pre_highlight = vim.fn.matchlist(status, [[\(%#.\{-\}#\)]])[2]
|
||||
status = pre_highlight .. string.rep(' ', l_padding) ..
|
||||
status:sub(#pre_highlight + 1, #status)
|
||||
else
|
||||
status = string.rep(' ', l_padding) .. status
|
||||
end
|
||||
end
|
||||
if r_padding then status = status .. string.rep(' ', r_padding) end
|
||||
return status
|
||||
end
|
||||
|
||||
-- Applies custom highlights for component
|
||||
function M.apply_highlights(status, options, default_hl)
|
||||
if options.color_highlight then
|
||||
status = highlight.component_format_highlight(options.color_highlight) ..
|
||||
status
|
||||
end
|
||||
return status .. default_hl
|
||||
end
|
||||
|
||||
-- Apply icon in front of component
|
||||
function M.apply_icon(status, options)
|
||||
if options.icons_enabled and options.icon then
|
||||
status = options.icon .. ' ' .. status
|
||||
end
|
||||
return status
|
||||
end
|
||||
|
||||
-- Apply separator at end of component only when
|
||||
-- custom highlights haven't affected background
|
||||
function M.apply_spearator(status, options)
|
||||
local separator
|
||||
if options.separator and #options.separator > 0 then
|
||||
separator = options.separator
|
||||
elseif options.component_separators then
|
||||
if options.self.section < 'lualine_x' then
|
||||
separator = options.component_separators[1]
|
||||
else
|
||||
separator = options.component_separators[2]
|
||||
end
|
||||
options.separator = separator
|
||||
end
|
||||
if separator then status = status .. separator end
|
||||
options.separator_applied = separator
|
||||
return status
|
||||
end
|
||||
|
||||
function M.strip_separator(status, options)
|
||||
if options.separator_applied then
|
||||
status = status:sub(1, #status - #options.separator_applied)
|
||||
options.separator_applied = nil
|
||||
end
|
||||
return status
|
||||
end
|
||||
|
||||
return M
|
|
@ -0,0 +1,45 @@
|
|||
-- Copyright (c) 2020-2021 hoob3rt
|
||||
-- MIT license, see LICENSE for more details.
|
||||
-- LuaFormatter off
|
||||
|
||||
local Mode = {}
|
||||
|
||||
Mode.map = {
|
||||
['n'] = 'NORMAL',
|
||||
['no'] = 'O-PENDING',
|
||||
['nov'] = 'O-PENDING',
|
||||
['noV'] = 'O-PENDING',
|
||||
['no'] = 'O-PENDING',
|
||||
['niI'] = 'NORMAL',
|
||||
['niR'] = 'NORMAL',
|
||||
['niV'] = 'NORMAL',
|
||||
['v'] = 'VISUAL',
|
||||
['V'] = 'V-LINE',
|
||||
[''] = 'V-BLOCK',
|
||||
['s'] = 'SELECT',
|
||||
['S'] = 'S-LINE',
|
||||
[''] = 'S-BLOCK',
|
||||
['i'] = 'INSERT',
|
||||
['ic'] = 'INSERT',
|
||||
['ix'] = 'INSERT',
|
||||
['R'] = 'REPLACE',
|
||||
['Rc'] = 'REPLACE',
|
||||
['Rv'] = 'V-REPLACE',
|
||||
['Rx'] = 'REPLACE',
|
||||
['c'] = 'COMMAND',
|
||||
['cv'] = 'EX',
|
||||
['ce'] = 'EX',
|
||||
['r'] = 'REPLACE',
|
||||
['rm'] = 'MORE',
|
||||
['r?'] = 'CONFIRM',
|
||||
['!'] = 'SHELL',
|
||||
['t'] = 'TERMINAL',
|
||||
}
|
||||
-- LuaFormatter on
|
||||
function Mode.get_mode()
|
||||
local mode_code = vim.api.nvim_get_mode().mode
|
||||
if Mode.map[mode_code] == nil then return mode_code end
|
||||
return Mode.map[mode_code]
|
||||
end
|
||||
|
||||
return Mode
|
|
@ -1,52 +1,49 @@
|
|||
-- Copyright (c) 2020-2021 hoob3rt
|
||||
-- MIT license, see LICENSE for more details.
|
||||
local utils_component = require('lualine.utils.component')
|
||||
local M = {}
|
||||
local utils = require('lualine.utils.utils')
|
||||
-- Returns formated string for a section
|
||||
function M.draw_section(section, highlight_name)
|
||||
local status = {}
|
||||
local drawn_components = {}
|
||||
for _, component in pairs(section) do
|
||||
local localstatus = component[1]()
|
||||
if #localstatus > 0 then
|
||||
local custom_highlight_at_begining =
|
||||
localstatus:find('%%#.*#') == 1 or component.color ~= nil
|
||||
-- Apply modifier functions for options
|
||||
if component.format then localstatus = component.format(localstatus) end
|
||||
localstatus = utils_component.apply_icon(localstatus, component)
|
||||
localstatus = utils_component.apply_case(localstatus, component)
|
||||
localstatus = utils_component.apply_padding(localstatus, component)
|
||||
localstatus = utils_component.apply_highlights(localstatus, component,
|
||||
-- load components into status table
|
||||
table.insert(status, component:draw(highlight_name))
|
||||
end
|
||||
|
||||
-- Flags required for knowing when to remove component separator
|
||||
local next_component_colored = false
|
||||
local last_component_found = false
|
||||
|
||||
-- Check through components to see when component separator need to be removed
|
||||
for component_no = #section, 1, -1 do
|
||||
-- Remove component separator with highlight for last component
|
||||
if not last_component_found and #status[component_no] > 0 then
|
||||
last_component_found = true
|
||||
status[component_no] = section[component_no]:strip_separator(
|
||||
highlight_name)
|
||||
localstatus = utils_component.apply_spearator(localstatus, component)
|
||||
if custom_highlight_at_begining or (#drawn_components > 0 and
|
||||
not drawn_components[#drawn_components].separator_applied) then
|
||||
end
|
||||
-- Remove component separator when color option is used in next component
|
||||
if next_component_colored then
|
||||
next_component_colored = false
|
||||
status[component_no] = section[component_no]:strip_separator()
|
||||
end
|
||||
-- Remove component separator when color option is used to color background
|
||||
if section[component_no].options.color and
|
||||
section[component_no].options.color.bg then
|
||||
next_component_colored = true
|
||||
status[component_no] = section[component_no]:strip_separator()
|
||||
end
|
||||
end
|
||||
|
||||
-- Remove empty strings from status
|
||||
status = utils.list_shrink(status)
|
||||
local status_str = table.concat(status)
|
||||
if status_str:find('%%#.*#') == 1 then
|
||||
-- Don't prepend with old highlight when the component changes it imidiately
|
||||
-- Or when it was already applied with separator
|
||||
table.insert(status, localstatus)
|
||||
return status_str
|
||||
else
|
||||
table.insert(status, highlight_name .. localstatus)
|
||||
return highlight_name .. status_str
|
||||
end
|
||||
table.insert(drawn_components, component)
|
||||
end
|
||||
end
|
||||
-- Draw nothing when all the components were empty
|
||||
if #status == 0 then return '' end
|
||||
-- Remove separators sorounding custom highlighted component
|
||||
for i = 1, #status do
|
||||
if (drawn_components[i].color and drawn_components[i].color.bg) or
|
||||
drawn_components[i].custom_highlight then
|
||||
status[i] =
|
||||
utils_component.strip_separator(status[i], drawn_components[i])
|
||||
if i > 1 then
|
||||
status[i - 1] = utils_component.strip_separator(status[i - 1],
|
||||
drawn_components[i - 1])
|
||||
end
|
||||
end
|
||||
end
|
||||
status[#status] = utils_component.strip_separator(status[#status],
|
||||
drawn_components[#status])
|
||||
return table.concat(status)
|
||||
end
|
||||
|
||||
return M
|
||||
|
|
|
@ -54,4 +54,13 @@ function M.clear_highlights()
|
|||
end
|
||||
end
|
||||
|
||||
-- remove empty strings from list
|
||||
function M.list_shrink(list)
|
||||
local new_list = {}
|
||||
for i = 1, #list do
|
||||
if list[i] and #list[i] > 0 then table.insert(new_list, list[i]) end
|
||||
end
|
||||
return new_list
|
||||
end
|
||||
|
||||
return M
|
||||
|
|
Loading…
Reference in New Issue