Regenerate nvim config
This commit is contained in:
656
config/neovim/store/lazy-plugins/lualine.nvim/lua/lualine.lua
Normal file
656
config/neovim/store/lazy-plugins/lualine.nvim/lua/lualine.lua
Normal file
@ -0,0 +1,656 @@
|
||||
-- Copyright (c) 2020-2021 hoob3rt
|
||||
-- MIT license, see LICENSE for more details.
|
||||
local M = {}
|
||||
|
||||
local lualine_require = require('lualine_require')
|
||||
local modules = lualine_require.lazy_require {
|
||||
highlight = 'lualine.highlight',
|
||||
loader = 'lualine.utils.loader',
|
||||
utils_section = 'lualine.utils.section',
|
||||
utils = 'lualine.utils.utils',
|
||||
utils_notices = 'lualine.utils.notices',
|
||||
config_module = 'lualine.config',
|
||||
nvim_opts = 'lualine.utils.nvim_opts',
|
||||
}
|
||||
local config -- Stores currently applied config
|
||||
local timers = {
|
||||
stl_timer = vim.loop.new_timer(),
|
||||
tal_timer = vim.loop.new_timer(),
|
||||
wb_timer = vim.loop.new_timer(),
|
||||
halt_stl_refresh = false, -- mutex ?
|
||||
halt_tal_refresh = false,
|
||||
halt_wb_refresh = false,
|
||||
}
|
||||
|
||||
local last_focus = {}
|
||||
local refresh_real_curwin
|
||||
|
||||
-- The events on which lualine redraws itself
|
||||
local default_refresh_events =
|
||||
'WinEnter,BufEnter,BufWritePost,SessionLoadPost,FileChangedShellPost,VimResized,Filetype,CursorMoved,CursorMovedI,ModeChanged'
|
||||
-- Helper for apply_transitional_separators()
|
||||
--- finds first applied highlight group after str_checked in status
|
||||
---@param status string : unprocessed statusline string
|
||||
---@param str_checked number : position of how far status has been checked
|
||||
---@return string|nil the hl group name or nil
|
||||
local function find_next_hl(status, str_checked)
|
||||
-- Gets the next valid hl group from str_checked
|
||||
local hl_pos_start, hl_pos_end = status:find('%%#.-#', str_checked)
|
||||
while true do
|
||||
if not hl_pos_start then
|
||||
return nil
|
||||
end
|
||||
-- When there are more that one hl group next to one another like
|
||||
-- %#HL1#%#HL2#%#HL3# we need to return HL3. This makes that happen.
|
||||
local next_start, next_end = status:find('^%%#.-#', hl_pos_end + 1)
|
||||
if next_start == nil then
|
||||
break
|
||||
end
|
||||
hl_pos_start, hl_pos_end = next_start, next_end
|
||||
end
|
||||
return status:sub(hl_pos_start + 2, hl_pos_end - 1)
|
||||
end
|
||||
|
||||
-- Helper for apply_transitional_separators()
|
||||
--- applies transitional separator highlight + transitional separator
|
||||
---@param status string : unprocessed statusline string
|
||||
---@param str_checked number : position of how far status has been checked
|
||||
---@param last_hl string : last applied hl group name before str_checked
|
||||
---@param reverse boolean : reverse the hl group ( true for right separators )
|
||||
---@return string|nil concatenate separator highlight and transitional separator
|
||||
local function fill_section_separator(status, is_focused, str_checked, last_hl, sep, reverse)
|
||||
-- Inserts transitional separator along with transitional highlight
|
||||
local next_hl = find_next_hl(status, str_checked)
|
||||
if last_hl == nil then
|
||||
last_hl = modules.highlight.get_stl_default_hl(is_focused)
|
||||
end
|
||||
if next_hl == nil then
|
||||
next_hl = modules.highlight.get_stl_default_hl(is_focused)
|
||||
end
|
||||
if #next_hl == 0 or #last_hl == 0 then
|
||||
return
|
||||
end
|
||||
local transitional_highlight = reverse -- lua ternary assignment x ? y : z
|
||||
and modules.highlight.get_transitional_highlights(last_hl, next_hl)
|
||||
or modules.highlight.get_transitional_highlights(next_hl, last_hl)
|
||||
if transitional_highlight then
|
||||
return transitional_highlight .. sep
|
||||
end
|
||||
end
|
||||
|
||||
--- processes statusline string
|
||||
--- replaces %z/Z{sep} with proper left/right separator highlight + sep
|
||||
---@param status string : unprocessed statusline string
|
||||
---@return string : processed statusline string
|
||||
local function apply_transitional_separators(status, is_focused)
|
||||
local status_applied = {} -- Collects all the pieces for concatenation
|
||||
local last_hl -- Stores last highlight group that we found
|
||||
local last_hl_reseted = false -- Whether last_hl is nil after reset
|
||||
-- it after %=
|
||||
local copied_pos = 1 -- Tracks how much we've copied over to status_applied
|
||||
local str_checked = 1 -- Tracks where the searcher head is at
|
||||
|
||||
-- Process entire status replace the %z{sep} & %Z{sep} placeholders
|
||||
-- with proper transitional separator.
|
||||
while str_checked ~= nil do
|
||||
str_checked = status:find('%%', str_checked)
|
||||
if str_checked == nil then
|
||||
break
|
||||
end
|
||||
table.insert(status_applied, status:sub(copied_pos, str_checked - 1))
|
||||
-- -1 so we don't copy '%'
|
||||
copied_pos = str_checked
|
||||
local next_char = modules.utils.charAt(status, str_checked + 1)
|
||||
if next_char == '#' then
|
||||
-- %#hl_name# highlights
|
||||
last_hl = status:match('^%%#(.-)#', str_checked)
|
||||
str_checked = str_checked + #last_hl + 3
|
||||
elseif next_char == 'z' then
|
||||
-- %z{sep} is marker for left separator and
|
||||
local sep = status:match('^%%z{(.-)}', str_checked)
|
||||
str_checked = str_checked + #sep + 4 -- 4 = len(%{})
|
||||
if not (last_hl == nil and last_hl_reseted) then
|
||||
local trans_sep = fill_section_separator(status, is_focused, str_checked, last_hl, sep, false)
|
||||
if trans_sep then
|
||||
table.insert(status_applied, trans_sep)
|
||||
end
|
||||
end
|
||||
if last_hl_reseted then
|
||||
last_hl_reseted = false
|
||||
end
|
||||
copied_pos = str_checked
|
||||
elseif next_char == 'Z' then
|
||||
-- %Z{sep} is marker for right separator and
|
||||
local sep = status:match('^%%Z{(.-)}', str_checked)
|
||||
str_checked = str_checked + #sep + 4 -- 4 = len(%{})
|
||||
if status:find('^%%z', str_checked) or status:find('^%%<%%Z', str_checked) then
|
||||
-- When transitional right_sep and left_sep are right next to each other
|
||||
-- and in this exact order skip the left sep as we can't draw both.
|
||||
str_checked = status:find('}', str_checked) + 1
|
||||
end
|
||||
local trans_sep = fill_section_separator(status, is_focused, str_checked, last_hl, sep, true)
|
||||
if trans_sep then
|
||||
table.insert(status_applied, trans_sep)
|
||||
end
|
||||
copied_pos = str_checked
|
||||
elseif next_char == '%' then
|
||||
str_checked = str_checked + 2 -- Skip the following % too
|
||||
elseif next_char == '=' and last_hl and (last_hl:find('^lualine_a') or last_hl:find('^lualine_b')) then
|
||||
-- TODO: Fix this properly
|
||||
-- This check for lualine_a and lualine_b is dumb. It doesn't guarantee
|
||||
-- c or x section isn't present. Worst case scenario after this patch
|
||||
-- we have another visual bug that occurs less frequently.
|
||||
-- Annoying Edge Cases
|
||||
last_hl = nil
|
||||
last_hl_reseted = true
|
||||
str_checked = str_checked + 1 -- Skip the following % too
|
||||
else
|
||||
str_checked = str_checked + 1 -- Push it forward to avoid inf loop
|
||||
end
|
||||
end
|
||||
table.insert(status_applied, status:sub(copied_pos)) -- Final chunk
|
||||
return table.concat(status_applied)
|
||||
end
|
||||
|
||||
--- creates the statusline string
|
||||
---@param sections table : section config where components are replaced with
|
||||
--- component objects
|
||||
---@param is_focused boolean : whether being evaluated for focused window or not
|
||||
---@return string statusline string
|
||||
local statusline = modules.utils.retry_call_wrap(function(sections, is_focused, is_winbar)
|
||||
-- The sequence sections should maintain [SECTION_SEQUENCE]
|
||||
local section_sequence = { 'a', 'b', 'c', 'x', 'y', 'z' }
|
||||
local status = {}
|
||||
local applied_midsection_divider = false
|
||||
local applied_trunc = false
|
||||
for _, section_name in ipairs(section_sequence) do
|
||||
if sections['lualine_' .. section_name] then
|
||||
-- insert highlight+components of this section to status_builder
|
||||
local section_data =
|
||||
modules.utils_section.draw_section(sections['lualine_' .. section_name], section_name, is_focused)
|
||||
if #section_data > 0 then
|
||||
if not applied_midsection_divider and section_name > 'c' then
|
||||
applied_midsection_divider = true
|
||||
section_data = modules.highlight.format_highlight('c', is_focused) .. '%=' .. section_data
|
||||
end
|
||||
if not applied_trunc and section_name > 'b' then
|
||||
applied_trunc = true
|
||||
section_data = '%<' .. section_data
|
||||
end
|
||||
table.insert(status, section_data)
|
||||
end
|
||||
end
|
||||
end
|
||||
if applied_midsection_divider == false and config.options.always_divide_middle ~= false and not is_winbar then
|
||||
-- When non of section x,y,z is present
|
||||
table.insert(status, modules.highlight.format_highlight('c', is_focused) .. '%=')
|
||||
end
|
||||
return apply_transitional_separators(table.concat(status), is_focused)
|
||||
end)
|
||||
|
||||
--- check if any extension matches the filetype and return proper sections
|
||||
---@param current_ft string : filetype name of current file
|
||||
---@param is_focused boolean : whether being evaluated for focused window or not
|
||||
---@return table|nil : (section_table) section config where components are replaced with
|
||||
--- component objects
|
||||
-- TODO: change this so it uses a hash table instead of iteration over list
|
||||
-- to improve redraws. Add buftype / bufname for extensions
|
||||
-- or some kind of cond ?
|
||||
local function get_extension_sections(current_ft, is_focused, sec_name)
|
||||
for _, extension in ipairs(config.extensions) do
|
||||
if vim.tbl_contains(extension.filetypes, current_ft) then
|
||||
if is_focused then
|
||||
return extension[sec_name]
|
||||
else
|
||||
return extension['inactive_' .. sec_name] or extension[sec_name]
|
||||
end
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
---@return string statusline string for tabline
|
||||
local function tabline()
|
||||
return statusline(config.tabline, 3)
|
||||
end
|
||||
|
||||
local function notify_theme_error(theme_name)
|
||||
local message_template = theme_name ~= 'auto'
|
||||
and [[
|
||||
### options.theme
|
||||
Theme `%s` not found, falling back to `auto`. Check if spelling is right.
|
||||
]]
|
||||
or [[
|
||||
### options.theme
|
||||
Theme `%s` failed, falling back to `gruvbox`.
|
||||
This shouldn't happen.
|
||||
Please report the issue at https://github.com/nvim-lualine/lualine.nvim/issues .
|
||||
Also provide what colorscheme you're using.
|
||||
]]
|
||||
modules.utils_notices.add_notice(string.format(message_template, theme_name))
|
||||
end
|
||||
|
||||
--- Sets up theme by defining hl groups and setting theme cache in 'highlight.lua'.
|
||||
--- Uses 'options.theme' variable to apply the theme:
|
||||
--- - If the value is a string, it'll load a theme of that name.
|
||||
--- - If it's a table, it's directly used as the theme.
|
||||
--- If loading the theme fails, this falls back to 'auto' theme.
|
||||
--- If the 'auto' theme also fails, this falls back to 'gruvbox' theme.
|
||||
--- Also sets up auto command to reload lualine on ColorScheme or background changes.
|
||||
local function setup_theme()
|
||||
local function get_theme_from_config()
|
||||
local theme_name = config.options.theme
|
||||
if type(theme_name) == 'string' then
|
||||
local ok, theme = pcall(modules.loader.load_theme, theme_name)
|
||||
if ok and theme then
|
||||
return theme
|
||||
end
|
||||
elseif type(theme_name) == 'table' then
|
||||
-- use the provided theme as-is
|
||||
return config.options.theme
|
||||
elseif type(theme_name) == 'function' then
|
||||
-- call function and use returned (dynamic) theme as-is
|
||||
return config.options.theme()
|
||||
end
|
||||
if theme_name ~= 'auto' then
|
||||
notify_theme_error(theme_name)
|
||||
local ok, theme = pcall(modules.loader.load_theme, 'auto')
|
||||
if ok and theme then
|
||||
return theme
|
||||
end
|
||||
end
|
||||
notify_theme_error('auto')
|
||||
return modules.loader.load_theme('gruvbox')
|
||||
end
|
||||
local theme = get_theme_from_config()
|
||||
modules.highlight.create_highlight_groups(theme)
|
||||
vim.cmd([[autocmd lualine ColorScheme * lua require'lualine'.setup()
|
||||
autocmd lualine OptionSet background lua require'lualine'.setup()]])
|
||||
end
|
||||
|
||||
---@alias StatusDispatchSecs
|
||||
---| 'sections'
|
||||
---| 'winbar'
|
||||
--- generates lualine.statusline & lualine.winbar function
|
||||
--- creates a closer that can draw sections of sec_name.
|
||||
---@param sec_name StatusDispatchSecs
|
||||
---@return function(focused:bool):string
|
||||
local function status_dispatch(sec_name)
|
||||
return function(focused)
|
||||
local retval
|
||||
local current_ft = refresh_real_curwin
|
||||
and vim.api.nvim_buf_get_option(vim.api.nvim_win_get_buf(refresh_real_curwin), 'filetype')
|
||||
or vim.bo.filetype
|
||||
local is_focused = focused ~= nil and focused or modules.utils.is_focused()
|
||||
if
|
||||
vim.tbl_contains(
|
||||
config.options.disabled_filetypes[(sec_name == 'sections' and 'statusline' or sec_name)],
|
||||
current_ft
|
||||
)
|
||||
then
|
||||
-- disable on specific filetypes
|
||||
return nil
|
||||
end
|
||||
local extension_sections = get_extension_sections(current_ft, is_focused, sec_name)
|
||||
if extension_sections ~= nil then
|
||||
retval = statusline(extension_sections, is_focused, sec_name == 'winbar')
|
||||
else
|
||||
retval = statusline(config[(is_focused and '' or 'inactive_') .. sec_name], is_focused, sec_name == 'winbar')
|
||||
end
|
||||
return retval
|
||||
end
|
||||
end
|
||||
|
||||
---@alias LualineRefreshOptsKind
|
||||
---| 'all'
|
||||
---| 'tabpage'
|
||||
---| 'window'
|
||||
---@alias LualineRefreshOptsPlace
|
||||
---| 'statusline'
|
||||
---| 'tabline'
|
||||
---| 'winbar'
|
||||
---@class LualineRefreshOpts
|
||||
---@field scope LualineRefreshOptsKind
|
||||
---@field place LualineRefreshOptsPlace[]
|
||||
---@field trigger 'autocmd'|'autocmd_redired'|'timer'|'unknown'
|
||||
--- Refresh contents of lualine
|
||||
---@param opts LualineRefreshOpts
|
||||
local function refresh(opts)
|
||||
if opts == nil then
|
||||
opts = {}
|
||||
end
|
||||
opts = vim.tbl_extend('keep', opts, {
|
||||
scope = 'tabpage',
|
||||
place = { 'statusline', 'winbar', 'tabline' },
|
||||
trigger = 'unknown',
|
||||
})
|
||||
|
||||
-- updating statusline in autocommands context seems to trigger 100 different bugs
|
||||
-- lets just defer it to a timer context and update there
|
||||
-- Since updating stl in command mode doesn't take effect
|
||||
-- refresh ModeChanged command in autocmd context as exception.
|
||||
-- workaround for
|
||||
-- https://github.com/neovim/neovim/issues/15300
|
||||
-- https://github.com/neovim/neovim/issues/19464
|
||||
-- https://github.com/nvim-lualine/lualine.nvim/issues/753
|
||||
-- https://github.com/nvim-lualine/lualine.nvim/issues/751
|
||||
-- https://github.com/nvim-lualine/lualine.nvim/issues/755
|
||||
-- https://github.com/neovim/neovim/issues/19472
|
||||
-- https://github.com/nvim-lualine/lualine.nvim/issues/791
|
||||
if
|
||||
opts.trigger == 'autocmd'
|
||||
and vim.v.event.new_mode ~= 'c'
|
||||
-- scheduling in op-pending mode seems to call the callback forever.
|
||||
-- so this is restricted in op-pending mode.
|
||||
-- https://github.com/neovim/neovim/issues/22263
|
||||
-- https://github.com/nvim-lualine/lualine.nvim/issues/967
|
||||
-- note this breaks mode component while switching to op-pending mode
|
||||
and not vim.tbl_contains({ 'no', 'nov', 'noV' }, vim.v.event.new_mode)
|
||||
and not vim.tbl_contains({ 'no', 'nov', 'noV' }, vim.v.event.old_mode)
|
||||
then
|
||||
opts.trigger = 'autocmd_redired'
|
||||
vim.schedule(function()
|
||||
M.refresh(opts)
|
||||
end)
|
||||
return
|
||||
end
|
||||
|
||||
local wins = {}
|
||||
local old_actual_curwin = vim.g.actual_curwin
|
||||
|
||||
-- ignore focus on filetypes listed in options.ignore_focus
|
||||
local curwin = vim.api.nvim_get_current_win()
|
||||
local curtab = vim.api.nvim_get_current_tabpage()
|
||||
if last_focus[curtab] == nil or not vim.api.nvim_win_is_valid(last_focus[curtab]) then
|
||||
if
|
||||
not vim.tbl_contains(
|
||||
config.options.ignore_focus,
|
||||
vim.api.nvim_buf_get_option(vim.api.nvim_win_get_buf(curwin), 'filetype')
|
||||
)
|
||||
then
|
||||
last_focus[curtab] = curwin
|
||||
else
|
||||
local tab_wins = vim.api.nvim_tabpage_list_wins(curtab)
|
||||
if #tab_wins == 1 then
|
||||
last_focus[curtab] = curwin
|
||||
else
|
||||
local focusable_win = curwin
|
||||
for _, win in ipairs(tab_wins) do
|
||||
if
|
||||
not vim.tbl_contains(
|
||||
config.options.ignore_focus,
|
||||
vim.api.nvim_buf_get_option(vim.api.nvim_win_get_buf(win), 'filetype')
|
||||
)
|
||||
then
|
||||
focusable_win = win
|
||||
break
|
||||
end
|
||||
end
|
||||
last_focus[curtab] = focusable_win
|
||||
end
|
||||
end
|
||||
else
|
||||
if
|
||||
not vim.tbl_contains(
|
||||
config.options.ignore_focus,
|
||||
vim.api.nvim_buf_get_option(vim.api.nvim_win_get_buf(curwin), 'filetype')
|
||||
)
|
||||
then
|
||||
last_focus[curtab] = curwin
|
||||
end
|
||||
end
|
||||
vim.g.actual_curwin = last_focus[curtab]
|
||||
|
||||
-- gather which windows needs update
|
||||
if opts.scope == 'all' then
|
||||
if vim.tbl_contains(opts.place, 'statusline') or vim.tbl_contains(opts.place, 'winbar') then
|
||||
wins = vim.tbl_filter(function(win)
|
||||
return vim.fn.win_gettype(win) ~= 'popup'
|
||||
end, vim.api.nvim_list_wins())
|
||||
end
|
||||
elseif opts.scope == 'tabpage' then
|
||||
if vim.tbl_contains(opts.place, 'statusline') or vim.tbl_contains(opts.place, 'winbar') then
|
||||
wins = vim.tbl_filter(function(win)
|
||||
return vim.fn.win_gettype(win) ~= 'popup'
|
||||
end, vim.api.nvim_tabpage_list_wins(0))
|
||||
end
|
||||
elseif opts.scope == 'window' then
|
||||
wins = { curwin }
|
||||
end
|
||||
|
||||
-- update them
|
||||
if not timers.halt_stl_refresh and vim.tbl_contains(opts.place, 'statusline') then
|
||||
for _, win in ipairs(wins) do
|
||||
refresh_real_curwin = config.options.globalstatus and last_focus[curtab] or win
|
||||
local set_win = config.options.globalstatus
|
||||
and vim.fn.win_gettype(refresh_real_curwin) == 'popup'
|
||||
and refresh_real_curwin
|
||||
or win
|
||||
local stl_cur = vim.api.nvim_win_call(refresh_real_curwin, M.statusline)
|
||||
local stl_last = modules.nvim_opts.get_cache('statusline', { window = set_win })
|
||||
if stl_cur or stl_last then
|
||||
modules.nvim_opts.set('statusline', stl_cur, { window = set_win })
|
||||
end
|
||||
end
|
||||
end
|
||||
if not timers.halt_wb_refresh and vim.tbl_contains(opts.place, 'winbar') then
|
||||
for _, win in ipairs(wins) do
|
||||
refresh_real_curwin = win
|
||||
if vim.api.nvim_win_get_height(win) > 1 then
|
||||
local wbr_cur = vim.api.nvim_win_call(refresh_real_curwin, M.winbar)
|
||||
local wbr_last = modules.nvim_opts.get_cache('winbar', { window = win })
|
||||
if wbr_cur or wbr_last then
|
||||
modules.nvim_opts.set('winbar', wbr_cur, { window = win })
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
if not timers.halt_tal_refresh and vim.tbl_contains(opts.place, 'tabline') then
|
||||
refresh_real_curwin = curwin
|
||||
local tbl_cur = vim.api.nvim_win_call(curwin, tabline)
|
||||
local tbl_last = modules.nvim_opts.get_cache('tabline', { global = true })
|
||||
if tbl_cur or tbl_last then
|
||||
modules.nvim_opts.set('tabline', tbl_cur, { global = true })
|
||||
end
|
||||
end
|
||||
|
||||
vim.g.actual_curwin = old_actual_curwin
|
||||
refresh_real_curwin = nil
|
||||
end
|
||||
|
||||
--- Sets &tabline option to lualine
|
||||
---@param hide boolean|nil if should hide tabline
|
||||
local function set_tabline(hide)
|
||||
vim.loop.timer_stop(timers.tal_timer)
|
||||
timers.halt_tal_refresh = true
|
||||
vim.cmd([[augroup lualine_tal_refresh | exe "autocmd!" | augroup END]])
|
||||
if not hide and next(config.tabline) ~= nil then
|
||||
vim.loop.timer_start(
|
||||
timers.tal_timer,
|
||||
0,
|
||||
config.options.refresh.tabline,
|
||||
modules.utils.timer_call(timers.tal_timer, 'lualine_tal_refresh', function()
|
||||
refresh { kind = 'tabpage', place = { 'tabline' }, trigger = 'timer' }
|
||||
end, 3, 'lualine: Failed to refresh tabline')
|
||||
)
|
||||
modules.utils.define_autocmd(
|
||||
default_refresh_events,
|
||||
'*',
|
||||
"call v:lua.require'lualine'.refresh({'kind': 'tabpage', 'place': ['tabline'], 'trigger': 'autocmd'})",
|
||||
'lualine_tal_refresh'
|
||||
)
|
||||
modules.nvim_opts.set('showtabline', 2, { global = true })
|
||||
timers.halt_tal_refresh = false
|
||||
else
|
||||
modules.nvim_opts.restore('tabline', { global = true })
|
||||
modules.nvim_opts.restore('showtabline', { global = true })
|
||||
end
|
||||
end
|
||||
|
||||
--- Sets &statusline option to lualine
|
||||
--- adds auto command to redraw lualine on VimResized event
|
||||
---@param hide boolean|nil if should hide statusline
|
||||
local function set_statusline(hide)
|
||||
vim.loop.timer_stop(timers.stl_timer)
|
||||
timers.halt_stl_refresh = true
|
||||
vim.cmd([[augroup lualine_stl_refresh | exe "autocmd!" | augroup END]])
|
||||
if not hide and (next(config.sections) ~= nil or next(config.inactive_sections) ~= nil) then
|
||||
if vim.go.statusline == '' then
|
||||
modules.nvim_opts.set('statusline', '%#Normal#', { global = true })
|
||||
end
|
||||
if config.options.globalstatus then
|
||||
modules.nvim_opts.set('laststatus', 3, { global = true })
|
||||
vim.loop.timer_start(
|
||||
timers.stl_timer,
|
||||
0,
|
||||
config.options.refresh.statusline,
|
||||
modules.utils.timer_call(timers.stl_timer, 'lualine_stl_refresh', function()
|
||||
refresh { kind = 'window', place = { 'statusline' }, trigger = 'timer' }
|
||||
end, 3, 'lualine: Failed to refresh statusline')
|
||||
)
|
||||
modules.utils.define_autocmd(
|
||||
default_refresh_events,
|
||||
'*',
|
||||
"call v:lua.require'lualine'.refresh({'kind': 'window', 'place': ['statusline'], 'trigger': 'autocmd'})",
|
||||
'lualine_stl_refresh'
|
||||
)
|
||||
else
|
||||
modules.nvim_opts.set('laststatus', 2, { global = true })
|
||||
vim.loop.timer_start(
|
||||
timers.stl_timer,
|
||||
0,
|
||||
config.options.refresh.statusline,
|
||||
modules.utils.timer_call(timers.stl_timer, 'lualine_stl_refresh', function()
|
||||
refresh { kind = 'tabpage', place = { 'statusline' }, trigger = 'timer' }
|
||||
end, 3, 'lualine: Failed to refresh statusline')
|
||||
)
|
||||
modules.utils.define_autocmd(
|
||||
default_refresh_events,
|
||||
'*',
|
||||
"call v:lua.require'lualine'.refresh({'kind': 'tabpage', 'place': ['statusline'], 'trigger': 'autocmd'})",
|
||||
'lualine_stl_refresh'
|
||||
)
|
||||
end
|
||||
timers.halt_stl_refresh = false
|
||||
else
|
||||
modules.nvim_opts.restore('statusline', { global = true })
|
||||
for _, win in ipairs(vim.api.nvim_list_wins()) do
|
||||
modules.nvim_opts.restore('statusline', { window = win })
|
||||
end
|
||||
modules.nvim_opts.restore('laststatus', { global = true })
|
||||
end
|
||||
end
|
||||
|
||||
--- Sets &winbar option to lualine
|
||||
---@param hide boolean|nil if should unset winbar
|
||||
local function set_winbar(hide)
|
||||
vim.loop.timer_stop(timers.wb_timer)
|
||||
timers.halt_wb_refresh = true
|
||||
vim.cmd([[augroup lualine_wb_refresh | exe "autocmd!" | augroup END]])
|
||||
if not hide and (next(config.winbar) ~= nil or next(config.inactive_winbar) ~= nil) then
|
||||
vim.loop.timer_start(
|
||||
timers.wb_timer,
|
||||
0,
|
||||
config.options.refresh.winbar,
|
||||
modules.utils.timer_call(timers.wb_timer, 'lualine_wb_refresh', function()
|
||||
refresh { kind = 'tabpage', place = { 'winbar' }, trigger = 'timer' }
|
||||
end, 3, 'lualine: Failed to refresh winbar')
|
||||
)
|
||||
modules.utils.define_autocmd(
|
||||
default_refresh_events,
|
||||
'*',
|
||||
"call v:lua.require'lualine'.refresh({'kind': 'tabpage', 'place': ['winbar'], 'trigger': 'autocmd'})",
|
||||
'lualine_wb_refresh'
|
||||
)
|
||||
timers.halt_wb_refresh = false
|
||||
elseif vim.fn.has('nvim-0.8') == 1 then
|
||||
modules.nvim_opts.restore('winbar', { global = true })
|
||||
for _, win in ipairs(vim.api.nvim_list_wins()) do
|
||||
modules.nvim_opts.restore('winbar', { window = win })
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
---@alias LualineHideOptsPlace
|
||||
---| 'statusline'
|
||||
---| 'tabline'
|
||||
---| 'winbar'
|
||||
---@class LualineHideOpts
|
||||
---@field place LualineHideOptsPlace[]
|
||||
---@field unhide boolean
|
||||
---@param opts LualineHideOpts
|
||||
local function hide(opts)
|
||||
if opts == nil then
|
||||
opts = {}
|
||||
end
|
||||
opts = vim.tbl_extend('keep', opts, {
|
||||
place = { 'statusline', 'tabline', 'winbar' },
|
||||
unhide = false,
|
||||
})
|
||||
local hide_fn = {
|
||||
statusline = set_statusline,
|
||||
tabline = set_tabline,
|
||||
winbar = set_winbar,
|
||||
}
|
||||
for _, place in ipairs(opts.place) do
|
||||
if hide_fn[place] then
|
||||
hide_fn[place](not opts.unhide)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--- Check neovim compatibilitu
|
||||
local function verify_nvim_version()
|
||||
if vim.fn.has('nvim-0.7') == 1 then
|
||||
return true
|
||||
end
|
||||
modules.utils_notices.add_notice([[
|
||||
### Incompatible Neovim version
|
||||
Lualine supports neovim 0.7 and up. It seems you're using a older version.
|
||||
Please update to newer version. Or if you have atleast neovim 0.5 you
|
||||
can use older compatible versions of lualine using compat tags like
|
||||
`compat-nvim-0.5`, `compat-nvim-0.6`.
|
||||
]])
|
||||
return false
|
||||
end
|
||||
|
||||
-- lualine.setup function
|
||||
--- sets new user config
|
||||
--- This function doesn't load components/theme etc... They are done before
|
||||
--- first statusline redraw and after new config. This is more efficient when
|
||||
--- lualine config is done in several setup calls as chunks. This way
|
||||
--- we don't initialize components just to throw them away. Instead they are
|
||||
--- initialized when we know we will use them.
|
||||
--- sets &last_status to 2
|
||||
---@param user_config table table
|
||||
local function setup(user_config)
|
||||
if package.loaded['lualine.utils.notices'] then
|
||||
-- When notices module is not loaded there are no notices to clear.
|
||||
modules.utils_notices.clear_notices()
|
||||
end
|
||||
if verify_nvim_version() then
|
||||
config = modules.config_module.apply_configuration(user_config)
|
||||
vim.cmd([[augroup lualine | exe "autocmd!" | augroup END]])
|
||||
setup_theme()
|
||||
-- load components & extensions
|
||||
modules.loader.load_all(config)
|
||||
set_statusline()
|
||||
set_tabline()
|
||||
set_winbar()
|
||||
end
|
||||
if package.loaded['lualine.utils.notices'] then
|
||||
modules.utils_notices.notice_message_startup()
|
||||
end
|
||||
end
|
||||
|
||||
M = {
|
||||
setup = setup,
|
||||
statusline = status_dispatch('sections'),
|
||||
tabline = tabline,
|
||||
get_config = modules.config_module.get_config,
|
||||
refresh = refresh,
|
||||
winbar = status_dispatch('winbar'),
|
||||
hide = hide,
|
||||
}
|
||||
|
||||
return M
|
||||
@ -0,0 +1,291 @@
|
||||
-- Copyright (c) 2020-2021 shadmansaleh
|
||||
-- MIT license, see LICENSE for more details.
|
||||
local lualine_require = require('lualine_require')
|
||||
local require = lualine_require.require
|
||||
local M = require('lualine.utils.class'):extend()
|
||||
local modules = lualine_require.lazy_require {
|
||||
highlight = 'lualine.highlight',
|
||||
utils_notices = 'lualine.utils.notices',
|
||||
fn_store = 'lualine.utils.fn_store',
|
||||
}
|
||||
|
||||
-- Used to provide a unique id for each component
|
||||
local component_no = 1
|
||||
function M._reset_components()
|
||||
component_no = 1
|
||||
end
|
||||
|
||||
-- variable to store component output for manipulation
|
||||
M.status = ''
|
||||
|
||||
function M:__tostring()
|
||||
local str = 'Component: ' .. self.options.component_name
|
||||
if self.debug then
|
||||
str = str .. '\n---------------------\n' .. vim.inspect(self)
|
||||
end
|
||||
return str
|
||||
end
|
||||
|
||||
M.__is_lualine_component = true
|
||||
|
||||
---initialize new component
|
||||
---@param options table options for component
|
||||
function M:init(options)
|
||||
self.options = options or {}
|
||||
component_no = component_no + 1
|
||||
if not self.options.component_name then
|
||||
self.options.component_name = tostring(component_no)
|
||||
end
|
||||
self.component_no = component_no
|
||||
self:set_separator()
|
||||
self:create_option_highlights()
|
||||
self:set_on_click()
|
||||
end
|
||||
|
||||
---sets the default separator for component based on whether the component
|
||||
---is in left sections or right sections when separator option is omitted.
|
||||
function M:set_separator()
|
||||
if self.options.separator == nil then
|
||||
if self.options.component_separators then
|
||||
if self.options.self.section < 'x' then
|
||||
self.options.separator = self.options.component_separators.left
|
||||
else
|
||||
self.options.separator = self.options.component_separators.right
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
---creates hl group from color option
|
||||
function M:create_option_highlights()
|
||||
-- set custom highlights
|
||||
if self.options.color then
|
||||
self.options.color_highlight = self:create_hl(self.options.color)
|
||||
end
|
||||
-- setup icon highlight
|
||||
if type(self.options.icon) == 'table' and self.options.icon.color then
|
||||
self.options.icon_color_highlight = self:create_hl(self.options.icon.color)
|
||||
end
|
||||
end
|
||||
|
||||
---Setup on click function so they can be added during drawing.
|
||||
function M:set_on_click()
|
||||
if self.options.on_click ~= nil then
|
||||
if vim.fn.has('nvim-0.8') == 0 then
|
||||
modules.utils_notices.add_notice(
|
||||
'### Options.on_click\nSorry `on_click` can only be used in neovim 0.8 or higher.\n'
|
||||
)
|
||||
self.options.on_click = nil
|
||||
return
|
||||
end
|
||||
self.on_click_id = modules.fn_store.register_fn(self.component_no, self.options.on_click)
|
||||
end
|
||||
end
|
||||
|
||||
---adds spaces to left and right of a component
|
||||
function M:apply_padding()
|
||||
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
|
||||
if l_padding then
|
||||
if self.status:find('%%#.*#') == 1 then
|
||||
-- When component has changed the highlight at beginning
|
||||
-- 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
|
||||
function M:apply_highlights(default_highlight)
|
||||
if self.options.color_highlight then
|
||||
local hl_fmt
|
||||
hl_fmt, M.color_fn_cache = self:format_hl(self.options.color_highlight)
|
||||
self.status = hl_fmt .. self.status
|
||||
end
|
||||
if type(self.options.separator) ~= 'table' and self.status:find('%%#') then
|
||||
-- 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 necessary
|
||||
self.status = self.status .. default_highlight
|
||||
-- Also put it in applied sep so when sep get striped 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
|
||||
if not self.status:find('^%%#') then
|
||||
self.status = default_highlight .. self.status
|
||||
end
|
||||
end
|
||||
|
||||
---apply icon to component (appends/prepends component with icon)
|
||||
function M:apply_icon()
|
||||
local icon = self.options.icon
|
||||
if self.options.icons_enabled and icon then
|
||||
if type(icon) == 'table' then
|
||||
icon = icon[1]
|
||||
end
|
||||
if
|
||||
self.options.icon_color_highlight
|
||||
and type(self.options.icon) == 'table'
|
||||
and self.options.icon.align == 'right'
|
||||
then
|
||||
self.status = table.concat {
|
||||
self.status,
|
||||
' ',
|
||||
self:format_hl(self.options.icon_color_highlight),
|
||||
icon,
|
||||
self:get_default_hl(),
|
||||
}
|
||||
elseif self.options.icon_color_highlight then
|
||||
self.status = table.concat {
|
||||
self:format_hl(self.options.icon_color_highlight),
|
||||
icon,
|
||||
self:get_default_hl(),
|
||||
' ',
|
||||
self.status,
|
||||
}
|
||||
elseif type(self.options.icon) == 'table' and self.options.icon.align == 'right' then
|
||||
self.status = table.concat({ self.status, icon }, ' ')
|
||||
else
|
||||
self.status = table.concat({ icon, self.status }, ' ')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
---apply separator at end of component only when
|
||||
---custom highlights haven't affected background
|
||||
function M:apply_separator()
|
||||
local separator = self.options.separator
|
||||
if type(separator) == 'table' then
|
||||
if self.options.separator[2] == '' then
|
||||
if self.options.self.section < 'x' then
|
||||
separator = self.options.component_separators.left
|
||||
else
|
||||
separator = self.options.component_separators.right
|
||||
end
|
||||
else
|
||||
return
|
||||
end
|
||||
end
|
||||
if separator and #separator > 0 then
|
||||
self.status = self.status .. separator
|
||||
self.applied_separator = self.applied_separator .. separator
|
||||
end
|
||||
end
|
||||
|
||||
---apply transitional separator for the component
|
||||
function M:apply_section_separators()
|
||||
if type(self.options.separator) ~= 'table' then
|
||||
return
|
||||
end
|
||||
if self.options.separator.left ~= nil and self.options.separator.left ~= '' then
|
||||
self.status = string.format('%%z{%s}%s', self.options.separator.left, self.status)
|
||||
self.strip_previous_separator = true
|
||||
end
|
||||
if self.options.separator.right ~= nil and self.options.separator.right ~= '' then
|
||||
self.status = string.format('%s%%Z{%s}', self.status, self.options.separator.right)
|
||||
end
|
||||
end
|
||||
|
||||
---Add on click function description to already drawn item
|
||||
function M:apply_on_click()
|
||||
if self.on_click_id then
|
||||
self.status = self:format_fn(self.on_click_id, self.status)
|
||||
end
|
||||
end
|
||||
|
||||
---remove separator from tail of this component.
|
||||
---called by lualine.utils.sections.draw_section to manage unnecessary separators
|
||||
function M:strip_separator()
|
||||
if not self.applied_separator then
|
||||
self.applied_separator = ''
|
||||
end
|
||||
self.status = self.status:sub(1, (#self.status - #self.applied_separator))
|
||||
self.applied_separator = nil
|
||||
return self.status
|
||||
end
|
||||
|
||||
function M:get_default_hl()
|
||||
if self.options.color_highlight then
|
||||
return self:format_hl(self.options.color_highlight)
|
||||
elseif self.default_hl then
|
||||
return self.default_hl
|
||||
else
|
||||
return modules.highlight.format_highlight(self.options.self.section)
|
||||
end
|
||||
end
|
||||
|
||||
---create a lualine highlight for color
|
||||
---@param color table|string|function defined color for hl
|
||||
---@param hint string|nil hint for hl name
|
||||
---@return table an identifier to later retrieve the hl for application
|
||||
function M:create_hl(color, hint)
|
||||
hint = hint and self.options.component_name .. '_' .. hint or self.options.component_name
|
||||
return modules.highlight.create_component_highlight_group(color, hint, self.options, false)
|
||||
end
|
||||
|
||||
---Get stl formatted hl group for hl_token
|
||||
---@param hl_token table identifier received from create_hl or create_component_highlight_group
|
||||
---@return string stl formatted hl group for hl_token
|
||||
function M:format_hl(hl_token)
|
||||
return modules.highlight.component_format_highlight(hl_token)
|
||||
end
|
||||
|
||||
---Wrap str with click format for function of id
|
||||
---@param id number
|
||||
---@param str string
|
||||
---@return string
|
||||
function M:format_fn(id, str)
|
||||
return string.format("%%%d@v:lua.require'lualine.utils.fn_store'.call_fn@%s%%T", id, str)
|
||||
end
|
||||
|
||||
-- luacheck: push no unused args
|
||||
---actual function that updates a component. Must be overwritten with component functionality
|
||||
function M:update_status(is_focused) end
|
||||
-- luacheck: pop
|
||||
|
||||
---driver code of the class
|
||||
---@param default_highlight string default hl group of section where component resides
|
||||
---@param is_focused boolean|number whether drawing for active or inactive statusline.
|
||||
---@return string stl formatted rendering string for component
|
||||
function M:draw(default_highlight, is_focused)
|
||||
self.status = ''
|
||||
self.applied_separator = ''
|
||||
|
||||
if self.options.cond ~= nil and self.options.cond() ~= true then
|
||||
return self.status
|
||||
end
|
||||
self.default_hl = default_highlight
|
||||
local status = self:update_status(is_focused)
|
||||
if self.options.fmt then
|
||||
status = self.options.fmt(status or '', self)
|
||||
end
|
||||
if type(status) == 'string' and (#status > 0 or self.options.draw_empty) then
|
||||
self.status = status
|
||||
if #status > 0 then
|
||||
self:apply_icon()
|
||||
self:apply_padding()
|
||||
end
|
||||
self:apply_on_click()
|
||||
self:apply_highlights(default_highlight)
|
||||
self:apply_section_separators()
|
||||
self:apply_separator()
|
||||
end
|
||||
return self.status
|
||||
end
|
||||
|
||||
return M
|
||||
@ -0,0 +1,149 @@
|
||||
local M = {}
|
||||
|
||||
local require = require('lualine_require').require
|
||||
local utils = require('lualine.utils.utils')
|
||||
|
||||
-- vars
|
||||
local current_git_branch = ''
|
||||
local current_git_dir = ''
|
||||
local branch_cache = {} -- stores last known branch for a buffer
|
||||
local active_bufnr = '0'
|
||||
-- os specific path separator
|
||||
local sep = package.config:sub(1, 1)
|
||||
-- event watcher to watch head file
|
||||
-- Use file watch for non Windows and poll for Windows.
|
||||
-- Windows doesn't like file watch for some reason.
|
||||
local file_changed = sep ~= '\\' and vim.loop.new_fs_event() or vim.loop.new_fs_poll()
|
||||
local git_dir_cache = {} -- Stores git paths that we already know of
|
||||
|
||||
---sets git_branch variable to branch name or commit hash if not on branch
|
||||
---@param head_file string full path of .git/HEAD file
|
||||
local function 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
|
||||
current_git_branch = branch
|
||||
else
|
||||
current_git_branch = HEAD:sub(1, 6)
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
---updates the current value of git_branch and sets up file watch on HEAD file
|
||||
local function update_branch()
|
||||
active_bufnr = tostring(vim.api.nvim_get_current_buf())
|
||||
file_changed:stop()
|
||||
local git_dir = current_git_dir
|
||||
if git_dir and #git_dir > 0 then
|
||||
local head_file = git_dir .. sep .. 'HEAD'
|
||||
get_git_head(head_file)
|
||||
file_changed:start(
|
||||
head_file,
|
||||
sep ~= '\\' and {} or 1000,
|
||||
vim.schedule_wrap(function()
|
||||
-- reset file-watch
|
||||
update_branch()
|
||||
end)
|
||||
)
|
||||
else
|
||||
-- set to '' when git dir was not found
|
||||
current_git_branch = ''
|
||||
end
|
||||
branch_cache[vim.api.nvim_get_current_buf()] = current_git_branch
|
||||
end
|
||||
|
||||
---updates the current value of current_git_branch and sets up file watch on HEAD file if value changed
|
||||
local function update_current_git_dir(git_dir)
|
||||
if current_git_dir ~= git_dir then
|
||||
current_git_dir = git_dir
|
||||
update_branch()
|
||||
end
|
||||
end
|
||||
|
||||
---returns full path to git directory for dir_path or current directory
|
||||
---@param dir_path string|nil
|
||||
---@return string|nil
|
||||
function M.find_git_dir(dir_path)
|
||||
local git_dir = vim.env.GIT_DIR
|
||||
if git_dir then
|
||||
update_current_git_dir(git_dir)
|
||||
return git_dir
|
||||
end
|
||||
|
||||
-- get file dir so we can search from that dir
|
||||
local file_dir = dir_path or vim.fn.expand('%:p:h')
|
||||
|
||||
-- extract correct file dir from terminals
|
||||
if file_dir and file_dir:match('term://.*') then
|
||||
file_dir = vim.fn.expand(file_dir:gsub('term://(.+)//.+', '%1'))
|
||||
end
|
||||
|
||||
local root_dir = file_dir
|
||||
-- Search upward for .git file or folder
|
||||
while root_dir do
|
||||
if git_dir_cache[root_dir] then
|
||||
git_dir = git_dir_cache[root_dir]
|
||||
break
|
||||
end
|
||||
local git_path = root_dir .. sep .. '.git'
|
||||
local git_file_stat = vim.loop.fs_stat(git_path)
|
||||
if git_file_stat then
|
||||
if git_file_stat.type == 'directory' then
|
||||
git_dir = git_path
|
||||
elseif git_file_stat.type == 'file' then
|
||||
-- separate git-dir or submodule is used
|
||||
local file = io.open(git_path)
|
||||
if file then
|
||||
git_dir = file:read()
|
||||
git_dir = git_dir and git_dir:match('gitdir: (.+)$')
|
||||
file:close()
|
||||
end
|
||||
-- submodule / relative file path
|
||||
if git_dir and git_dir:sub(1, 1) ~= sep and not git_dir:match('^%a:.*$') then
|
||||
git_dir = git_path:match('(.*).git') .. git_dir
|
||||
end
|
||||
end
|
||||
if git_dir then
|
||||
local head_file_stat = vim.loop.fs_stat(git_dir .. sep .. 'HEAD')
|
||||
if head_file_stat and head_file_stat.type == 'file' then
|
||||
break
|
||||
else
|
||||
git_dir = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
root_dir = root_dir:match('(.*)' .. sep .. '.-')
|
||||
end
|
||||
|
||||
git_dir_cache[file_dir] = git_dir
|
||||
if dir_path == nil then
|
||||
update_current_git_dir(git_dir)
|
||||
end
|
||||
return git_dir
|
||||
end
|
||||
|
||||
---initializes git_branch module
|
||||
function M.init()
|
||||
-- run watch head on load so branch is present when component is loaded
|
||||
M.find_git_dir()
|
||||
-- update branch state of BufEnter as different Buffer may be on different repos
|
||||
utils.define_autocmd('BufEnter', "lua require'lualine.components.branch.git_branch'.find_git_dir()")
|
||||
end
|
||||
function M.get_branch(bufnr)
|
||||
if vim.g.actual_curbuf ~= nil and active_bufnr ~= vim.g.actual_curbuf then
|
||||
-- Workaround for https://github.com/nvim-lualine/lualine.nvim/issues/286
|
||||
-- See upstream issue https://github.com/neovim/neovim/issues/15300
|
||||
-- Diff is out of sync re sync it.
|
||||
M.find_git_dir()
|
||||
end
|
||||
if bufnr then
|
||||
return branch_cache[bufnr] or ''
|
||||
end
|
||||
return current_git_branch
|
||||
end
|
||||
|
||||
return M
|
||||
@ -0,0 +1,25 @@
|
||||
-- Copyright (c) 2020-2021 shadmansaleh
|
||||
-- MIT license, see LICENSE for more details.
|
||||
local M = require('lualine.component'):extend()
|
||||
local modules = require('lualine_require').lazy_require {
|
||||
git_branch = 'lualine.components.branch.git_branch',
|
||||
highlight = 'lualine.highlight',
|
||||
utils = 'lualine.utils.utils',
|
||||
}
|
||||
|
||||
-- Initializer
|
||||
M.init = function(self, options)
|
||||
M.super.init(self, options)
|
||||
if not self.options.icon then
|
||||
self.options.icon = '' -- e0a0
|
||||
end
|
||||
modules.git_branch.init()
|
||||
end
|
||||
|
||||
M.update_status = function(_, is_focused)
|
||||
local buf = (not is_focused and vim.api.nvim_get_current_buf())
|
||||
local branch = modules.git_branch.get_branch(buf)
|
||||
return modules.utils.stl_escape(branch)
|
||||
end
|
||||
|
||||
return M
|
||||
@ -0,0 +1,192 @@
|
||||
local Buffer = require('lualine.utils.class'):extend()
|
||||
|
||||
local modules = require('lualine_require').lazy_require {
|
||||
highlight = 'lualine.highlight',
|
||||
utils = 'lualine.utils.utils',
|
||||
}
|
||||
|
||||
---initialize a new buffer from opts
|
||||
---@param opts table
|
||||
function Buffer:init(opts)
|
||||
assert(opts.bufnr, 'Cannot create Buffer without bufnr')
|
||||
self.bufnr = opts.bufnr
|
||||
self.buf_index = opts.buf_index
|
||||
self.options = opts.options
|
||||
self.highlights = opts.highlights
|
||||
self:get_props()
|
||||
end
|
||||
|
||||
function Buffer:is_current()
|
||||
return vim.api.nvim_get_current_buf() == self.bufnr
|
||||
end
|
||||
|
||||
function Buffer:is_alternate()
|
||||
return vim.fn.bufnr('#') == self.bufnr and not self:is_current()
|
||||
end
|
||||
|
||||
---setup icons, modified status for buffer
|
||||
function Buffer:get_props()
|
||||
self.file = modules.utils.stl_escape(vim.api.nvim_buf_get_name(self.bufnr))
|
||||
self.buftype = vim.api.nvim_buf_get_option(self.bufnr, 'buftype')
|
||||
self.filetype = vim.api.nvim_buf_get_option(self.bufnr, 'filetype')
|
||||
local modified = self.options.show_modified_status and vim.api.nvim_buf_get_option(self.bufnr, 'modified')
|
||||
self.modified_icon = modified and self.options.symbols.modified or ''
|
||||
self.alternate_file_icon = self:is_alternate() and self.options.symbols.alternate_file or ''
|
||||
self.icon = ''
|
||||
if self.options.icons_enabled then
|
||||
local dev
|
||||
local status, _ = pcall(require, 'nvim-web-devicons')
|
||||
if not status then
|
||||
dev, _ = '', ''
|
||||
elseif self.filetype == 'TelescopePrompt' then
|
||||
dev, _ = require('nvim-web-devicons').get_icon('telescope')
|
||||
elseif self.filetype == 'fugitive' then
|
||||
dev, _ = require('nvim-web-devicons').get_icon('git')
|
||||
elseif self.filetype == 'vimwiki' then
|
||||
dev, _ = require('nvim-web-devicons').get_icon('markdown')
|
||||
elseif self.buftype == 'terminal' then
|
||||
dev, _ = require('nvim-web-devicons').get_icon('zsh')
|
||||
elseif vim.fn.isdirectory(self.file) == 1 then
|
||||
dev, _ = self.options.symbols.directory, nil
|
||||
else
|
||||
dev, _ = require('nvim-web-devicons').get_icon(self.file, vim.fn.expand('#' .. self.bufnr .. ':e'))
|
||||
end
|
||||
if dev then
|
||||
self.icon = dev .. ' '
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
---returns line configured for handling mouse click
|
||||
---@param name string
|
||||
---@return string
|
||||
function Buffer:configure_mouse_click(name)
|
||||
return string.format('%%%s@LualineSwitchBuffer@%s%%T', self.bufnr, name)
|
||||
end
|
||||
|
||||
---returns rendered buffer
|
||||
---@return string
|
||||
function Buffer:render()
|
||||
local name = self:name()
|
||||
if self.options.fmt then
|
||||
name = self.options.fmt(name or '', self)
|
||||
end
|
||||
|
||||
if self.ellipse then -- show ellipsis
|
||||
name = '...'
|
||||
else
|
||||
name = self:apply_mode(name)
|
||||
end
|
||||
name = Buffer.apply_padding(name, self.options.padding)
|
||||
self.len = vim.fn.strchars(name)
|
||||
|
||||
-- setup for mouse clicks
|
||||
local line = self:configure_mouse_click(name)
|
||||
-- apply highlight
|
||||
line = modules.highlight.component_format_highlight(self.highlights[(self.current and 'active' or 'inactive')])
|
||||
.. line
|
||||
|
||||
-- apply separators
|
||||
if self.options.self.section < 'x' and not self.first then
|
||||
local sep_before = self:separator_before()
|
||||
line = sep_before .. line
|
||||
self.len = self.len + vim.fn.strchars(sep_before)
|
||||
elseif self.options.self.section >= 'x' and not self.last then
|
||||
local sep_after = self:separator_after()
|
||||
line = line .. sep_after
|
||||
self.len = self.len + vim.fn.strchars(sep_after)
|
||||
end
|
||||
return line
|
||||
end
|
||||
|
||||
---apply separator before current buffer
|
||||
---@return string
|
||||
function Buffer:separator_before()
|
||||
if self.current or self.aftercurrent then
|
||||
return '%Z{' .. self.options.section_separators.left .. '}'
|
||||
else
|
||||
return self.options.component_separators.left
|
||||
end
|
||||
end
|
||||
|
||||
---apply separator after current buffer
|
||||
---@return string
|
||||
function Buffer:separator_after()
|
||||
if self.current or self.beforecurrent then
|
||||
return '%z{' .. self.options.section_separators.right .. '}'
|
||||
else
|
||||
return self.options.component_separators.right
|
||||
end
|
||||
end
|
||||
|
||||
---returns name of current buffer after filtering special buffers
|
||||
---@return string
|
||||
function Buffer:name()
|
||||
if self.options.filetype_names[self.filetype] then
|
||||
return self.options.filetype_names[self.filetype]
|
||||
elseif self.buftype == 'help' then
|
||||
return 'help:' .. vim.fn.fnamemodify(self.file, ':t:r')
|
||||
elseif self.buftype == 'terminal' then
|
||||
local match = string.match(vim.split(self.file, ' ')[1], 'term:.*:(%a+)')
|
||||
return match ~= nil and match or vim.fn.fnamemodify(vim.env.SHELL, ':t')
|
||||
elseif self.buftype == 'quickfix' then
|
||||
local is_loclist = 0 ~= vim.fn.getloclist(0, { filewinid = 1 }).filewinid
|
||||
return is_loclist and 'Location list' or 'Quickfix List'
|
||||
elseif vim.fn.isdirectory(self.file) == 1 then
|
||||
return vim.fn.fnamemodify(self.file, ':p:.')
|
||||
elseif self.file == '' then
|
||||
return '[No Name]'
|
||||
end
|
||||
|
||||
local name
|
||||
if self.options.show_filename_only then
|
||||
name = vim.fn.fnamemodify(self.file, ':t')
|
||||
else
|
||||
name = vim.fn.pathshorten(vim.fn.fnamemodify(self.file, ':p:.'))
|
||||
end
|
||||
if self.options.hide_filename_extension then
|
||||
name = vim.fn.fnamemodify(name, ':r')
|
||||
end
|
||||
return name
|
||||
end
|
||||
|
||||
---adds spaces to left and right
|
||||
function Buffer.apply_padding(str, padding)
|
||||
local l_padding, r_padding = 1, 1
|
||||
if type(padding) == 'number' then
|
||||
l_padding, r_padding = padding, padding
|
||||
elseif type(padding) == 'table' then
|
||||
l_padding, r_padding = padding.left or 0, padding.right or 0
|
||||
end
|
||||
return string.rep(' ', l_padding) .. str .. string.rep(' ', r_padding)
|
||||
end
|
||||
|
||||
function Buffer:apply_mode(name)
|
||||
if self.options.mode == 0 then
|
||||
return string.format('%s%s%s%s', self.alternate_file_icon, self.icon, name, self.modified_icon)
|
||||
end
|
||||
|
||||
if self.options.mode == 1 then
|
||||
return string.format('%s%s %s%s', self.alternate_file_icon, self.buf_index or '', self.icon, self.modified_icon)
|
||||
end
|
||||
|
||||
if self.options.mode == 2 then
|
||||
return string.format(
|
||||
'%s%s %s%s%s',
|
||||
self.alternate_file_icon,
|
||||
self.buf_index or '',
|
||||
self.icon,
|
||||
name,
|
||||
self.modified_icon
|
||||
)
|
||||
end
|
||||
|
||||
if self.options.mode == 3 then
|
||||
return string.format('%s%s %s%s', self.alternate_file_icon, self.bufnr or '', self.icon, self.modified_icon)
|
||||
end
|
||||
|
||||
-- if self.options.mode == 4 then
|
||||
return string.format('%s%s %s%s%s', self.alternate_file_icon, self.bufnr or '', self.icon, name, self.modified_icon)
|
||||
end
|
||||
|
||||
return Buffer
|
||||
@ -0,0 +1,245 @@
|
||||
-- Copyright (c) 2020-2021 shadmansaleh
|
||||
-- MIT license, see LICENSE for more details.
|
||||
local require = require('lualine_require').require
|
||||
local Buffer = require('lualine.components.buffers.buffer')
|
||||
local M = require('lualine.component'):extend()
|
||||
local highlight = require('lualine.highlight')
|
||||
|
||||
local default_options = {
|
||||
show_filename_only = true,
|
||||
hide_filename_extension = false,
|
||||
show_modified_status = true,
|
||||
mode = 0,
|
||||
max_length = 0,
|
||||
filetype_names = {
|
||||
TelescopePrompt = 'Telescope',
|
||||
dashboard = 'Dashboard',
|
||||
packer = 'Packer',
|
||||
fzf = 'FZF',
|
||||
alpha = 'Alpha',
|
||||
},
|
||||
use_mode_colors = false,
|
||||
buffers_color = {
|
||||
active = nil,
|
||||
inactive = nil,
|
||||
},
|
||||
symbols = {
|
||||
modified = ' ●',
|
||||
alternate_file = '#',
|
||||
directory = '',
|
||||
},
|
||||
}
|
||||
|
||||
-- This function is duplicated in tabs
|
||||
---returns the proper hl for buffer in section. Used for setting default highlights
|
||||
---@param section string name of section buffers component is in
|
||||
---@param is_active boolean
|
||||
---@return string hl name
|
||||
local function get_hl(section, is_active)
|
||||
local suffix = is_active and highlight.get_mode_suffix() or '_inactive'
|
||||
local section_redirects = {
|
||||
lualine_x = 'lualine_c',
|
||||
lualine_y = 'lualine_b',
|
||||
lualine_z = 'lualine_a',
|
||||
}
|
||||
if section_redirects[section] then
|
||||
section = highlight.highlight_exists(section .. suffix) and section or section_redirects[section]
|
||||
end
|
||||
return section .. suffix
|
||||
end
|
||||
|
||||
function M:init(options)
|
||||
M.super.init(self, options)
|
||||
-- if use_mode_colors is set, use a function so that the colors update
|
||||
local default_active = options.use_mode_colors
|
||||
and function()
|
||||
return get_hl('lualine_' .. options.self.section, true)
|
||||
end
|
||||
or get_hl('lualine_' .. options.self.section, true)
|
||||
default_options.buffers_color = {
|
||||
active = default_active,
|
||||
inactive = get_hl('lualine_' .. options.self.section, false),
|
||||
}
|
||||
self.options = vim.tbl_deep_extend('keep', self.options or {}, default_options)
|
||||
if self.options.component_name == 'buffers' then
|
||||
self.highlights = {
|
||||
active = self:create_hl(self.options.buffers_color.active, 'active'),
|
||||
inactive = self:create_hl(self.options.buffers_color.inactive, 'inactive'),
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
function M:new_buffer(bufnr, buf_index)
|
||||
bufnr = bufnr or vim.api.nvim_get_current_buf()
|
||||
buf_index = buf_index or ''
|
||||
return Buffer:new {
|
||||
bufnr = bufnr,
|
||||
buf_index = buf_index,
|
||||
options = self.options,
|
||||
highlights = self.highlights,
|
||||
}
|
||||
end
|
||||
|
||||
function M:buffers()
|
||||
local buffers = {}
|
||||
M.bufpos2nr = {}
|
||||
for b = 1, vim.fn.bufnr('$') do
|
||||
if vim.fn.buflisted(b) ~= 0 and vim.api.nvim_buf_get_option(b, 'buftype') ~= 'quickfix' then
|
||||
buffers[#buffers + 1] = self:new_buffer(b, #buffers + 1)
|
||||
M.bufpos2nr[#buffers] = b
|
||||
end
|
||||
end
|
||||
|
||||
return buffers
|
||||
end
|
||||
|
||||
function M:update_status()
|
||||
local data = {}
|
||||
local buffers = self:buffers()
|
||||
local current = -2
|
||||
-- mark the first, last, current, before current, after current buffers
|
||||
-- for rendering
|
||||
if buffers[1] then
|
||||
buffers[1].first = true
|
||||
end
|
||||
if buffers[#buffers] then
|
||||
buffers[#buffers].last = true
|
||||
end
|
||||
for i, buffer in ipairs(buffers) do
|
||||
if buffer:is_current() then
|
||||
buffer.current = true
|
||||
current = i
|
||||
end
|
||||
end
|
||||
if buffers[current - 1] then
|
||||
buffers[current - 1].beforecurrent = true
|
||||
end
|
||||
if buffers[current + 1] then
|
||||
buffers[current + 1].aftercurrent = true
|
||||
end
|
||||
|
||||
local max_length = self.options.max_length
|
||||
if type(max_length) == 'function' then
|
||||
max_length = max_length(self)
|
||||
end
|
||||
|
||||
if max_length == 0 then
|
||||
max_length = math.floor(2 * vim.o.columns / 3)
|
||||
end
|
||||
local total_length
|
||||
for i, buffer in pairs(buffers) do
|
||||
if buffer.current then
|
||||
current = i
|
||||
end
|
||||
end
|
||||
-- start drawing from current buffer and draw left and right of it until
|
||||
-- all buffers are drawn or max_length has been reached.
|
||||
if current == -2 then
|
||||
local b = self:new_buffer()
|
||||
b.current = true
|
||||
if self.options.self.section < 'x' then
|
||||
b.last = true
|
||||
if #buffers > 0 then
|
||||
buffers[#buffers].last = nil
|
||||
end
|
||||
buffers[#buffers + 1] = b
|
||||
current = #buffers
|
||||
else
|
||||
b.first = true
|
||||
if #buffers > 0 then
|
||||
buffers[1].first = nil
|
||||
end
|
||||
table.insert(buffers, 1, b)
|
||||
current = 1
|
||||
end
|
||||
end
|
||||
local current_buffer = buffers[current]
|
||||
data[#data + 1] = current_buffer:render()
|
||||
total_length = current_buffer.len
|
||||
local i = 0
|
||||
local before, after
|
||||
while true do
|
||||
i = i + 1
|
||||
before = buffers[current - i]
|
||||
after = buffers[current + i]
|
||||
local rendered_before, rendered_after
|
||||
if before == nil and after == nil then
|
||||
break
|
||||
end
|
||||
-- draw left most undrawn buffer if fits in max_length
|
||||
if before then
|
||||
rendered_before = before:render()
|
||||
total_length = total_length + before.len
|
||||
if total_length > max_length then
|
||||
break
|
||||
end
|
||||
table.insert(data, 1, rendered_before)
|
||||
end
|
||||
-- draw right most undrawn buffer if fits in max_length
|
||||
if after then
|
||||
rendered_after = after:render()
|
||||
total_length = total_length + after.len
|
||||
if total_length > max_length then
|
||||
break
|
||||
end
|
||||
data[#data + 1] = rendered_after
|
||||
end
|
||||
end
|
||||
-- draw ellipsis (...) on relevant sides if all buffers don't fit in max_length
|
||||
if total_length > max_length then
|
||||
if before ~= nil then
|
||||
before.ellipse = true
|
||||
before.first = true
|
||||
table.insert(data, 1, before:render())
|
||||
end
|
||||
if after ~= nil then
|
||||
after.ellipse = true
|
||||
after.last = true
|
||||
data[#data + 1] = after:render()
|
||||
end
|
||||
end
|
||||
|
||||
return table.concat(data)
|
||||
end
|
||||
|
||||
function M:draw()
|
||||
self.status = ''
|
||||
self.applied_separator = ''
|
||||
|
||||
if self.options.cond ~= nil and self.options.cond() ~= true then
|
||||
return self.status
|
||||
end
|
||||
local status = self:update_status()
|
||||
if type(status) == 'string' and #status > 0 then
|
||||
self.status = status
|
||||
self:apply_section_separators()
|
||||
self:apply_separator()
|
||||
end
|
||||
return self.status
|
||||
end
|
||||
|
||||
function M.buffer_jump(buf_pos, bang)
|
||||
if buf_pos == '$' then
|
||||
buf_pos = #M.bufpos2nr
|
||||
else
|
||||
buf_pos = tonumber(buf_pos)
|
||||
end
|
||||
if buf_pos < 1 or buf_pos > #M.bufpos2nr then
|
||||
if bang ~= '!' then
|
||||
error('Error: Unable to jump buffer position out of range')
|
||||
else
|
||||
return
|
||||
end
|
||||
end
|
||||
vim.api.nvim_set_current_buf(M.bufpos2nr[buf_pos])
|
||||
end
|
||||
|
||||
vim.cmd([[
|
||||
function! LualineSwitchBuffer(bufnr, mouseclicks, mousebutton, modifiers)
|
||||
execute ":buffer " . a:bufnr
|
||||
endfunction
|
||||
|
||||
command! -nargs=1 -bang LualineBuffersJump call v:lua.require'lualine.components.buffers'.buffer_jump(<f-args>, "<bang>")
|
||||
]])
|
||||
|
||||
return M
|
||||
@ -0,0 +1,31 @@
|
||||
-- Copyright (c) 2023 Willothy
|
||||
-- MIT license, see LICENSE for more details.
|
||||
local lualine_require = require('lualine_require')
|
||||
local M = lualine_require.require('lualine.component'):extend()
|
||||
|
||||
local default_options = {
|
||||
-- default, us, uk, iso, or format (ex. "%d/%m/%Y ...")
|
||||
style = 'default',
|
||||
}
|
||||
|
||||
function M:init(options)
|
||||
M.super.init(self, options)
|
||||
self.options = vim.tbl_deep_extend('keep', self.options or {}, default_options)
|
||||
end
|
||||
|
||||
function M:update_status()
|
||||
local fmt = self.options.style
|
||||
if self.options.style == 'default' then
|
||||
fmt = '%A, %B %d | %H:%M'
|
||||
elseif self.options.style == 'us' then
|
||||
fmt = '%m/%d/%Y'
|
||||
elseif self.options.style == 'uk' then
|
||||
fmt = '%d/%m/%Y'
|
||||
elseif self.options.style == 'iso' then
|
||||
fmt = '%Y-%m-%d'
|
||||
end
|
||||
|
||||
return os.date(fmt)
|
||||
end
|
||||
|
||||
return M
|
||||
@ -0,0 +1,59 @@
|
||||
local require = require('lualine_require').require
|
||||
local utils = require('lualine.utils.utils')
|
||||
local M = {}
|
||||
|
||||
-- default symbols for diagnostics component
|
||||
M.symbols = {
|
||||
icons = {
|
||||
error = ' ', -- x000f015a
|
||||
warn = ' ', -- x000f002a
|
||||
info = ' ', -- x000f02fd
|
||||
hint = ' ', -- x000f0336
|
||||
},
|
||||
no_icons = { error = 'E:', warn = 'W:', info = 'I:', hint = 'H:' },
|
||||
}
|
||||
|
||||
-- default options for diagnostics component
|
||||
M.options = {
|
||||
colored = true,
|
||||
update_in_insert = false,
|
||||
always_visible = false,
|
||||
sources = { 'nvim_diagnostic', 'coc' },
|
||||
sections = { 'error', 'warn', 'info', 'hint' },
|
||||
}
|
||||
|
||||
function M.apply_default_colors(opts)
|
||||
local default_diagnostics_color = {
|
||||
error = {
|
||||
fg = utils.extract_color_from_hllist(
|
||||
{ 'fg', 'sp' },
|
||||
{ 'DiagnosticError', 'LspDiagnosticsDefaultError', 'DiffDelete' },
|
||||
'#e32636'
|
||||
),
|
||||
},
|
||||
warn = {
|
||||
fg = utils.extract_color_from_hllist(
|
||||
{ 'fg', 'sp' },
|
||||
{ 'DiagnosticWarn', 'LspDiagnosticsDefaultWarning', 'DiffText' },
|
||||
'#ffa500'
|
||||
),
|
||||
},
|
||||
info = {
|
||||
fg = utils.extract_color_from_hllist(
|
||||
{ 'fg', 'sp' },
|
||||
{ 'DiagnosticInfo', 'LspDiagnosticsDefaultInformation', 'Normal' },
|
||||
'#ffffff'
|
||||
),
|
||||
},
|
||||
hint = {
|
||||
fg = utils.extract_color_from_hllist(
|
||||
{ 'fg', 'sp' },
|
||||
{ 'DiagnosticHint', 'LspDiagnosticsDefaultHint', 'DiffChange' },
|
||||
'#273faf'
|
||||
),
|
||||
},
|
||||
}
|
||||
opts.diagnostics_color = vim.tbl_deep_extend('keep', opts.diagnostics_color or {}, default_diagnostics_color)
|
||||
end
|
||||
|
||||
return M
|
||||
@ -0,0 +1,111 @@
|
||||
-- Copyright (c) 2020-2021 hoob3rt
|
||||
-- MIT license, see LICENSE for more details.
|
||||
local lualine_require = require('lualine_require')
|
||||
local modules = lualine_require.lazy_require {
|
||||
default_config = 'lualine.components.diagnostics.config',
|
||||
sources = 'lualine.components.diagnostics.sources',
|
||||
highlight = 'lualine.highlight',
|
||||
utils = 'lualine.utils.utils',
|
||||
utils_notices = 'lualine.utils.notices',
|
||||
}
|
||||
|
||||
local M = lualine_require.require('lualine.component'):extend()
|
||||
|
||||
M.diagnostics_sources = modules.sources.sources
|
||||
M.get_diagnostics = modules.sources.get_diagnostics
|
||||
|
||||
-- Initializer
|
||||
function M:init(options)
|
||||
-- Run super()
|
||||
M.super.init(self, options)
|
||||
-- Apply default options
|
||||
modules.default_config.apply_default_colors(self.options)
|
||||
self.options = vim.tbl_deep_extend('keep', self.options or {}, modules.default_config.options)
|
||||
-- Apply default symbols
|
||||
self.symbols = vim.tbl_extend(
|
||||
'keep',
|
||||
self.options.symbols or {},
|
||||
self.options.icons_enabled ~= false and modules.default_config.symbols.icons
|
||||
or modules.default_config.symbols.no_icons
|
||||
)
|
||||
-- Initialize highlight groups
|
||||
if self.options.colored then
|
||||
self.highlight_groups = {
|
||||
error = self:create_hl(self.options.diagnostics_color.error, 'error'),
|
||||
warn = self:create_hl(self.options.diagnostics_color.warn, 'warn'),
|
||||
info = self:create_hl(self.options.diagnostics_color.info, 'info'),
|
||||
hint = self:create_hl(self.options.diagnostics_color.hint, 'hint'),
|
||||
}
|
||||
end
|
||||
|
||||
-- Initialize variable to store last update so we can use it in insert
|
||||
-- mode for no update_in_insert
|
||||
self.last_diagnostics_count = {}
|
||||
|
||||
-- Error out no source
|
||||
if #self.options.sources < 1 then
|
||||
modules.utils_notices.add_notice(
|
||||
'### diagnostics.sources\n\nno sources for diagnostics configured.\nPlease specify which diagnostics source you want lualine to use with `sources` option.\n'
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
function M:update_status()
|
||||
local bufnr = vim.api.nvim_get_current_buf()
|
||||
local diagnostics_count
|
||||
local result = {}
|
||||
if self.options.update_in_insert or vim.api.nvim_get_mode().mode:sub(1, 1) ~= 'i' then
|
||||
local error_count, warning_count, info_count, hint_count = 0, 0, 0, 0
|
||||
local diagnostic_data = modules.sources.get_diagnostics(self.options.sources)
|
||||
-- sum all the counts
|
||||
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
|
||||
hint_count = hint_count + data.hint
|
||||
end
|
||||
diagnostics_count = {
|
||||
error = error_count,
|
||||
warn = warning_count,
|
||||
info = info_count,
|
||||
hint = hint_count,
|
||||
}
|
||||
-- Save count for insert mode
|
||||
self.last_diagnostics_count[bufnr] = diagnostics_count
|
||||
else -- Use cached count in insert mode with update_in_insert disabled
|
||||
diagnostics_count = self.last_diagnostics_count[bufnr] or { error = 0, warn = 0, info = 0, hint = 0 }
|
||||
end
|
||||
|
||||
local always_visible = false
|
||||
if type(self.options.always_visible) == 'boolean' then
|
||||
always_visible = self.options.always_visible
|
||||
elseif type(self.options.always_visible) == 'function' then
|
||||
always_visible = self.options.always_visible()
|
||||
end
|
||||
|
||||
-- format the counts with symbols and highlights
|
||||
if self.options.colored then
|
||||
local colors, bgs = {}, {}
|
||||
for name, hl in pairs(self.highlight_groups) do
|
||||
colors[name] = self:format_hl(hl)
|
||||
bgs[name] = modules.utils.extract_highlight_colors(colors[name]:match('%%#(.-)#'), 'bg')
|
||||
end
|
||||
local previous_section, padding
|
||||
for _, section in ipairs(self.options.sections) do
|
||||
if diagnostics_count[section] ~= nil and (always_visible or diagnostics_count[section] > 0) then
|
||||
padding = previous_section and (bgs[previous_section] ~= bgs[section]) and ' ' or ''
|
||||
previous_section = section
|
||||
table.insert(result, colors[section] .. padding .. self.symbols[section] .. diagnostics_count[section])
|
||||
end
|
||||
end
|
||||
else
|
||||
for _, section in ipairs(self.options.sections) do
|
||||
if diagnostics_count[section] ~= nil and (always_visible or diagnostics_count[section] > 0) then
|
||||
table.insert(result, self.symbols[section] .. diagnostics_count[section])
|
||||
end
|
||||
end
|
||||
end
|
||||
return table.concat(result, ' ')
|
||||
end
|
||||
|
||||
return M
|
||||
@ -0,0 +1,100 @@
|
||||
local M = {}
|
||||
|
||||
---functions that how how to retrieve diagnostics from specific source.
|
||||
---returns error_count:number, warning_count:number,
|
||||
--- info_count:number, hint_count:number
|
||||
M.sources = {
|
||||
nvim_lsp = function()
|
||||
local error_count, warning_count, info_count, hint_count
|
||||
local diagnostics = vim.diagnostic.get(0)
|
||||
local count = { 0, 0, 0, 0 }
|
||||
for _, diagnostic in ipairs(diagnostics) do
|
||||
if vim.startswith(vim.diagnostic.get_namespace(diagnostic.namespace).name, 'vim.lsp') then
|
||||
count[diagnostic.severity] = count[diagnostic.severity] + 1
|
||||
end
|
||||
end
|
||||
error_count = count[vim.diagnostic.severity.ERROR]
|
||||
warning_count = count[vim.diagnostic.severity.WARN]
|
||||
info_count = count[vim.diagnostic.severity.INFO]
|
||||
hint_count = count[vim.diagnostic.severity.HINT]
|
||||
return error_count, warning_count, info_count, hint_count
|
||||
end,
|
||||
nvim_workspace_diagnostic = function()
|
||||
local diag_severity = vim.diagnostic.severity
|
||||
|
||||
local function workspace_diag(severity)
|
||||
local count = vim.diagnostic.get(nil, { severity = severity })
|
||||
return vim.tbl_count(count)
|
||||
end
|
||||
|
||||
return workspace_diag(diag_severity.ERROR),
|
||||
workspace_diag(diag_severity.WARN),
|
||||
workspace_diag(diag_severity.INFO),
|
||||
workspace_diag(diag_severity.HINT)
|
||||
end,
|
||||
nvim_diagnostic = function()
|
||||
local diagnostics = vim.diagnostic.get(0)
|
||||
local count = { 0, 0, 0, 0 }
|
||||
for _, diagnostic in ipairs(diagnostics) do
|
||||
count[diagnostic.severity] = count[diagnostic.severity] + 1
|
||||
end
|
||||
return count[vim.diagnostic.severity.ERROR],
|
||||
count[vim.diagnostic.severity.WARN],
|
||||
count[vim.diagnostic.severity.INFO],
|
||||
count[vim.diagnostic.severity.HINT]
|
||||
end,
|
||||
coc = function()
|
||||
local data = vim.b.coc_diagnostic_info
|
||||
if data then
|
||||
return data.error, data.warning, data.information, data.hint
|
||||
else
|
||||
return 0, 0, 0, 0
|
||||
end
|
||||
end,
|
||||
ale = function()
|
||||
local ok, data = pcall(vim.fn['ale#statusline#Count'], vim.api.nvim_get_current_buf())
|
||||
if ok then
|
||||
return data.error + data.style_error, data.warning + data.style_warning, data.info, 0
|
||||
else
|
||||
return 0, 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, data.hint
|
||||
else
|
||||
return 0, 0, 0, 0
|
||||
end
|
||||
end,
|
||||
}
|
||||
|
||||
---returns list of diagnostics count from all sources
|
||||
---@param sources table list of sources
|
||||
---@return table {{error_count, warning_count, info_count, hint_count}}
|
||||
M.get_diagnostics = function(sources)
|
||||
local result = {}
|
||||
for index, source in ipairs(sources) do
|
||||
if type(source) == 'string' then
|
||||
local error_count, warning_count, info_count, hint_count = M.sources[source]()
|
||||
result[index] = {
|
||||
error = error_count,
|
||||
warn = warning_count,
|
||||
info = info_count,
|
||||
hint = hint_count,
|
||||
}
|
||||
elseif type(source) == 'function' then
|
||||
local source_result = source()
|
||||
source_result = type(source_result) == 'table' and source_result or {}
|
||||
result[index] = {
|
||||
error = source_result.error or 0,
|
||||
warn = source_result.warn or 0,
|
||||
info = source_result.info or 0,
|
||||
hint = source_result.hint or 0,
|
||||
}
|
||||
end
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
return M
|
||||
@ -0,0 +1,138 @@
|
||||
local lualine_require = require('lualine_require')
|
||||
local modules = lualine_require.lazy_require {
|
||||
utils = 'lualine.utils.utils',
|
||||
Job = 'lualine.utils.job',
|
||||
}
|
||||
|
||||
local M = {}
|
||||
|
||||
-- Vars
|
||||
-- variable to store git diff stats
|
||||
local git_diff = nil
|
||||
-- accumulates output from diff process
|
||||
local diff_output_cache = {}
|
||||
-- variable to store git_diff job
|
||||
local diff_job = nil
|
||||
|
||||
local active_bufnr = '0'
|
||||
local diff_cache = {} -- Stores last known value of diff of a buffer
|
||||
|
||||
---initialize the module
|
||||
---param opts table
|
||||
function M.init(opts)
|
||||
if type(opts.source) == 'function' then
|
||||
M.src = opts.source
|
||||
else
|
||||
modules.utils.define_autocmd('BufEnter', "lua require'lualine.components.diff.git_diff'.update_diff_args()")
|
||||
modules.utils.define_autocmd('BufWritePost', "lua require'lualine.components.diff.git_diff'.update_git_diff()")
|
||||
M.update_diff_args()
|
||||
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 }
|
||||
---@param bufnr number|nil
|
||||
function M.get_sign_count(bufnr)
|
||||
if bufnr then
|
||||
return diff_cache[bufnr]
|
||||
end
|
||||
if M.src then
|
||||
git_diff = M.src()
|
||||
diff_cache[vim.api.nvim_get_current_buf()] = git_diff
|
||||
elseif vim.g.actual_curbuf ~= nil and active_bufnr ~= vim.g.actual_curbuf then
|
||||
-- Workaround for https://github.com/nvim-lualine/lualine.nvim/issues/286
|
||||
-- See upstream issue https://github.com/neovim/neovim/issues/15300
|
||||
-- Diff is out of sync re sync it.
|
||||
M.update_diff_args()
|
||||
end
|
||||
return git_diff
|
||||
end
|
||||
|
||||
---process diff data and update git_diff{ added, removed, modified }
|
||||
---@param data string output on stdout od git diff job
|
||||
local function process_diff(data)
|
||||
-- Adapted from https://github.com/wbthomason/nvim-vcs.lua
|
||||
local added, removed, modified = 0, 0, 0
|
||||
for _, line in ipairs(data) do
|
||||
if string.find(line, [[^@@ ]]) then
|
||||
local tokens = vim.fn.matchlist(line, [[^@@ -\v(\d+),?(\d*) \+(\d+),?(\d*)]])
|
||||
local line_stats = {
|
||||
mod_count = tokens[3] == nil and 0 or tokens[3] == '' and 1 or tonumber(tokens[3]),
|
||||
new_count = tokens[5] == nil and 0 or tokens[5] == '' and 1 or tonumber(tokens[5]),
|
||||
}
|
||||
|
||||
if line_stats.mod_count == 0 and line_stats.new_count > 0 then
|
||||
added = added + line_stats.new_count
|
||||
elseif line_stats.mod_count > 0 and line_stats.new_count == 0 then
|
||||
removed = removed + line_stats.mod_count
|
||||
else
|
||||
local min = math.min(line_stats.mod_count, line_stats.new_count)
|
||||
modified = modified + min
|
||||
added = added + line_stats.new_count - min
|
||||
removed = removed + line_stats.mod_count - min
|
||||
end
|
||||
end
|
||||
end
|
||||
git_diff = { added = added, modified = modified, removed = removed }
|
||||
end
|
||||
|
||||
---updates the job args
|
||||
function M.update_diff_args()
|
||||
-- Don't show git diff when current buffer doesn't have a filename
|
||||
active_bufnr = tostring(vim.api.nvim_get_current_buf())
|
||||
if #vim.fn.expand('%') == 0 then
|
||||
M.diff_args = nil
|
||||
git_diff = nil
|
||||
return
|
||||
end
|
||||
M.diff_args = {
|
||||
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 next(data) then
|
||||
diff_output_cache = vim.list_extend(diff_output_cache, data)
|
||||
end
|
||||
end,
|
||||
on_stderr = function(_, data)
|
||||
data = table.concat(data, '\n')
|
||||
if #data > 0 then
|
||||
git_diff = nil
|
||||
diff_output_cache = {}
|
||||
end
|
||||
end,
|
||||
on_exit = function()
|
||||
if #diff_output_cache > 0 then
|
||||
process_diff(diff_output_cache)
|
||||
else
|
||||
git_diff = { added = 0, modified = 0, removed = 0 }
|
||||
end
|
||||
diff_cache[vim.api.nvim_get_current_buf()] = git_diff
|
||||
end,
|
||||
}
|
||||
M.update_git_diff()
|
||||
end
|
||||
|
||||
---update git_diff variable
|
||||
function M.update_git_diff()
|
||||
if M.diff_args then
|
||||
diff_output_cache = {}
|
||||
if diff_job then
|
||||
diff_job:stop()
|
||||
end
|
||||
diff_job = modules.Job(M.diff_args)
|
||||
if diff_job then
|
||||
diff_job:start()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return M
|
||||
@ -0,0 +1,93 @@
|
||||
-- Copyright (c) 2020-2021 shadmansaleh
|
||||
-- MIT license, see LICENSE for more details.
|
||||
local lualine_require = require('lualine_require')
|
||||
local modules = lualine_require.lazy_require {
|
||||
git_diff = 'lualine.components.diff.git_diff',
|
||||
utils = 'lualine.utils.utils',
|
||||
utils_notices = 'lualine.utils.notices',
|
||||
highlight = 'lualine.highlight',
|
||||
}
|
||||
local M = lualine_require.require('lualine.component'):extend()
|
||||
|
||||
local default_options = {
|
||||
colored = true,
|
||||
symbols = { added = '+', modified = '~', removed = '-' },
|
||||
}
|
||||
|
||||
local function apply_default_colors(opts)
|
||||
local default_diff_color = {
|
||||
added = {
|
||||
fg = modules.utils.extract_color_from_hllist(
|
||||
'fg',
|
||||
{ 'LuaLineDiffAdd', 'GitSignsAdd', 'GitGutterAdd', 'DiffAdded', 'DiffAdd' },
|
||||
'#90ee90'
|
||||
),
|
||||
},
|
||||
modified = {
|
||||
fg = modules.utils.extract_color_from_hllist(
|
||||
'fg',
|
||||
{ 'LuaLineDiffChange', 'GitSignsChange', 'GitGutterChange', 'DiffChanged', 'DiffChange' },
|
||||
'#f0e130'
|
||||
),
|
||||
},
|
||||
removed = {
|
||||
fg = modules.utils.extract_color_from_hllist(
|
||||
'fg',
|
||||
{ 'LuaLineDiffDelete', 'GitSignsDelete', 'GitGutterDelete', 'DiffRemoved', 'DiffDelete' },
|
||||
'#ff0038'
|
||||
),
|
||||
},
|
||||
}
|
||||
opts.diff_color = vim.tbl_deep_extend('keep', opts.diff_color or {}, default_diff_color)
|
||||
end
|
||||
|
||||
-- Initializer
|
||||
function M:init(options)
|
||||
M.super.init(self, options)
|
||||
apply_default_colors(self.options)
|
||||
self.options = vim.tbl_deep_extend('keep', self.options or {}, default_options)
|
||||
-- create highlights and save highlight_name in highlights table
|
||||
if self.options.colored then
|
||||
self.highlights = {
|
||||
added = self:create_hl(self.options.diff_color.added, 'added'),
|
||||
modified = self:create_hl(self.options.diff_color.modified, 'modified'),
|
||||
removed = self:create_hl(self.options.diff_color.removed, 'removed'),
|
||||
}
|
||||
end
|
||||
modules.git_diff.init(self.options)
|
||||
end
|
||||
|
||||
-- Function that runs every time statusline is updated
|
||||
function M:update_status(is_focused)
|
||||
local git_diff = modules.git_diff.get_sign_count((not is_focused and vim.api.nvim_get_current_buf()))
|
||||
if 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] = self:format_hl(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 self.options.colored then
|
||||
table.insert(result, colors[name] .. self.options.symbols[name] .. git_diff[name])
|
||||
else
|
||||
table.insert(result, self.options.symbols[name] .. git_diff[name])
|
||||
end
|
||||
end
|
||||
end
|
||||
if #result > 0 then
|
||||
return table.concat(result, ' ')
|
||||
else
|
||||
return ''
|
||||
end
|
||||
end
|
||||
|
||||
return M
|
||||
@ -0,0 +1,7 @@
|
||||
-- Copyright (c) 2020-2021 hoob3rt
|
||||
-- MIT license, see LICENSE for more details.
|
||||
local function encoding()
|
||||
return vim.opt.fileencoding:get()
|
||||
end
|
||||
|
||||
return encoding
|
||||
@ -0,0 +1,30 @@
|
||||
-- Copyright (c) 2020-2021 shadmansaleh
|
||||
-- MIT license, see LICENSE for more details.
|
||||
local M = require('lualine.component'):extend()
|
||||
|
||||
-- stylua: ignore
|
||||
local symbols = {
|
||||
unix = '', -- e712
|
||||
dos = '', -- e70f
|
||||
mac = '', -- e711
|
||||
}
|
||||
|
||||
-- Initializer
|
||||
function M:init(options)
|
||||
-- Run super()
|
||||
M.super.init(self, options)
|
||||
-- Apply default symbols
|
||||
self.symbols = vim.tbl_extend('keep', self.options.symbols or {}, symbols)
|
||||
end
|
||||
|
||||
-- Function that runs every time statusline is updated
|
||||
function M:update_status()
|
||||
local format = vim.bo.fileformat
|
||||
if self.options.icons_enabled then
|
||||
return self.symbols[format] or format
|
||||
else
|
||||
return format
|
||||
end
|
||||
end
|
||||
|
||||
return M
|
||||
@ -0,0 +1,119 @@
|
||||
-- Copyright (c) 2020-2021 shadmansaleh
|
||||
-- MIT license, see LICENSE for more details.
|
||||
local M = require('lualine.component'):extend()
|
||||
|
||||
local modules = require('lualine_require').lazy_require {
|
||||
utils = 'lualine.utils.utils',
|
||||
}
|
||||
|
||||
local default_options = {
|
||||
symbols = {
|
||||
modified = '[+]',
|
||||
readonly = '[-]',
|
||||
unnamed = '[No Name]',
|
||||
newfile = '[New]',
|
||||
},
|
||||
file_status = true,
|
||||
newfile_status = false,
|
||||
path = 0,
|
||||
shorting_target = 40,
|
||||
}
|
||||
|
||||
local function is_new_file()
|
||||
local filename = vim.fn.expand('%')
|
||||
return filename ~= '' and vim.bo.buftype == '' and vim.fn.filereadable(filename) == 0
|
||||
end
|
||||
|
||||
---shortens path by turning apple/orange -> a/orange
|
||||
---@param path string
|
||||
---@param sep string path separator
|
||||
---@param max_len integer maximum length of the full filename string
|
||||
---@return string
|
||||
local function shorten_path(path, sep, max_len)
|
||||
local len = #path
|
||||
if len <= max_len then
|
||||
return path
|
||||
end
|
||||
|
||||
local segments = vim.split(path, sep)
|
||||
for idx = 1, #segments - 1 do
|
||||
if len <= max_len then
|
||||
break
|
||||
end
|
||||
|
||||
local segment = segments[idx]
|
||||
local shortened = segment:sub(1, vim.startswith(segment, '.') and 2 or 1)
|
||||
segments[idx] = shortened
|
||||
len = len - (#segment - #shortened)
|
||||
end
|
||||
|
||||
return table.concat(segments, sep)
|
||||
end
|
||||
|
||||
local function filename_and_parent(path, sep)
|
||||
local segments = vim.split(path, sep)
|
||||
if #segments == 0 then
|
||||
return path
|
||||
elseif #segments == 1 then
|
||||
return segments[#segments]
|
||||
else
|
||||
return table.concat({ segments[#segments - 1], segments[#segments] }, sep)
|
||||
end
|
||||
end
|
||||
|
||||
M.init = function(self, options)
|
||||
M.super.init(self, options)
|
||||
self.options = vim.tbl_deep_extend('keep', self.options or {}, default_options)
|
||||
end
|
||||
|
||||
M.update_status = function(self)
|
||||
local path_separator = package.config:sub(1, 1)
|
||||
local data
|
||||
if self.options.path == 1 then
|
||||
-- relative path
|
||||
data = vim.fn.expand('%:~:.')
|
||||
elseif self.options.path == 2 then
|
||||
-- absolute path
|
||||
data = vim.fn.expand('%:p')
|
||||
elseif self.options.path == 3 then
|
||||
-- absolute path, with tilde
|
||||
data = vim.fn.expand('%:p:~')
|
||||
elseif self.options.path == 4 then
|
||||
-- filename and immediate parent
|
||||
data = filename_and_parent(vim.fn.expand('%:p:~'), path_separator)
|
||||
else
|
||||
-- just filename
|
||||
data = vim.fn.expand('%:t')
|
||||
end
|
||||
|
||||
if data == '' then
|
||||
data = self.options.symbols.unnamed
|
||||
end
|
||||
|
||||
if self.options.shorting_target ~= 0 then
|
||||
local windwidth = self.options.globalstatus and vim.go.columns or vim.fn.winwidth(0)
|
||||
local estimated_space_available = windwidth - self.options.shorting_target
|
||||
|
||||
data = shorten_path(data, path_separator, estimated_space_available)
|
||||
end
|
||||
|
||||
data = modules.utils.stl_escape(data)
|
||||
|
||||
local symbols = {}
|
||||
if self.options.file_status then
|
||||
if vim.bo.modified then
|
||||
table.insert(symbols, self.options.symbols.modified)
|
||||
end
|
||||
if vim.bo.modifiable == false or vim.bo.readonly == true then
|
||||
table.insert(symbols, self.options.symbols.readonly)
|
||||
end
|
||||
end
|
||||
|
||||
if self.options.newfile_status and is_new_file() then
|
||||
table.insert(symbols, self.options.symbols.newfile)
|
||||
end
|
||||
|
||||
return data .. (#symbols > 0 and ' ' .. table.concat(symbols, '') or '')
|
||||
end
|
||||
|
||||
return M
|
||||
@ -0,0 +1,25 @@
|
||||
-- Copyright (c) 2020-2021 shadmansaleh
|
||||
-- MIT license, see LICENSE for more details.
|
||||
local function filesize()
|
||||
local file = vim.fn.expand('%:p')
|
||||
if file == nil or #file == 0 then
|
||||
return ''
|
||||
end
|
||||
local size = vim.fn.getfsize(file)
|
||||
if size <= 0 then
|
||||
return ''
|
||||
end
|
||||
|
||||
local suffixes = { 'b', 'k', 'm', 'g' }
|
||||
|
||||
local i = 1
|
||||
while size > 1024 and i < #suffixes do
|
||||
size = size / 1024
|
||||
i = i + 1
|
||||
end
|
||||
|
||||
local format = i == 1 and '%d%s' or '%.1f%s'
|
||||
return string.format(format, size, suffixes[i])
|
||||
end
|
||||
|
||||
return filesize
|
||||
@ -0,0 +1,82 @@
|
||||
-- Copyright (c) 2020-2021 hoob3rt
|
||||
-- MIT license, see LICENSE for more details.
|
||||
local lualine_require = require('lualine_require')
|
||||
local modules = lualine_require.lazy_require {
|
||||
highlight = 'lualine.highlight',
|
||||
utils = 'lualine.utils.utils',
|
||||
}
|
||||
local M = lualine_require.require('lualine.component'):extend()
|
||||
|
||||
local default_options = {
|
||||
colored = true,
|
||||
icon_only = false,
|
||||
}
|
||||
|
||||
function M:init(options)
|
||||
M.super.init(self, options)
|
||||
self.options = vim.tbl_deep_extend('keep', self.options or {}, default_options)
|
||||
self.icon_hl_cache = {}
|
||||
end
|
||||
|
||||
function M.update_status()
|
||||
local ft = vim.bo.filetype or ''
|
||||
return modules.utils.stl_escape(ft)
|
||||
end
|
||||
|
||||
function M:apply_icon()
|
||||
if not self.options.icons_enabled then
|
||||
return
|
||||
end
|
||||
|
||||
local icon, icon_highlight_group
|
||||
local ok, devicons = pcall(require, 'nvim-web-devicons')
|
||||
if ok then
|
||||
icon, icon_highlight_group = devicons.get_icon(vim.fn.expand('%:t'))
|
||||
if icon == nil then
|
||||
icon, icon_highlight_group = devicons.get_icon_by_filetype(vim.bo.filetype)
|
||||
end
|
||||
|
||||
if icon == nil and icon_highlight_group == nil then
|
||||
icon = ''
|
||||
icon_highlight_group = 'DevIconDefault'
|
||||
end
|
||||
if icon then
|
||||
icon = icon .. ' '
|
||||
end
|
||||
if self.options.colored then
|
||||
local highlight_color = modules.utils.extract_highlight_colors(icon_highlight_group, 'fg')
|
||||
if highlight_color then
|
||||
local default_highlight = self:get_default_hl()
|
||||
local icon_highlight = self.icon_hl_cache[highlight_color]
|
||||
if not icon_highlight or not modules.highlight.highlight_exists(icon_highlight.name .. '_normal') then
|
||||
icon_highlight = self:create_hl({ fg = highlight_color }, icon_highlight_group)
|
||||
self.icon_hl_cache[highlight_color] = icon_highlight
|
||||
end
|
||||
|
||||
icon = self:format_hl(icon_highlight) .. icon .. default_highlight
|
||||
end
|
||||
end
|
||||
else
|
||||
ok = vim.fn.exists('*WebDevIconsGetFileTypeSymbol')
|
||||
if ok ~= 0 then
|
||||
icon = vim.fn.WebDevIconsGetFileTypeSymbol()
|
||||
if icon then
|
||||
icon = icon .. ' '
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if not icon then
|
||||
return
|
||||
end
|
||||
|
||||
if self.options.icon_only then
|
||||
self.status = icon
|
||||
elseif type(self.options.icon) == 'table' and self.options.icon.align == 'right' then
|
||||
self.status = self.status .. ' ' .. icon
|
||||
else
|
||||
self.status = icon .. self.status
|
||||
end
|
||||
end
|
||||
|
||||
return M
|
||||
@ -0,0 +1,11 @@
|
||||
-- Copyright (c) 2020-2021 hoob3rt
|
||||
-- MIT license, see LICENSE for more details.
|
||||
local modules = require('lualine_require').lazy_require {
|
||||
utils = 'lualine.utils.utils',
|
||||
}
|
||||
|
||||
local function hostname()
|
||||
return modules.utils.stl_escape(vim.loop.os_gethostname())
|
||||
end
|
||||
|
||||
return hostname
|
||||
@ -0,0 +1,9 @@
|
||||
-- Copyright (c) 2020-2021 hoob3rt
|
||||
-- MIT license, see LICENSE for more details.
|
||||
local function location()
|
||||
local line = vim.fn.line('.')
|
||||
local col = vim.fn.virtcol('.')
|
||||
return string.format('%3d:%-2d', line, col)
|
||||
end
|
||||
|
||||
return location
|
||||
@ -0,0 +1,4 @@
|
||||
-- Copyright (c) 2020-2021 hoob3rt
|
||||
-- MIT license, see LICENSE for more details.
|
||||
local get_mode = require('lualine.utils.mode').get_mode
|
||||
return get_mode
|
||||
@ -0,0 +1,15 @@
|
||||
-- Copyright (c) 2020-2021 hoob3rt
|
||||
-- MIT license, see LICENSE for more details.
|
||||
local function progress()
|
||||
local cur = vim.fn.line('.')
|
||||
local total = vim.fn.line('$')
|
||||
if cur == 1 then
|
||||
return 'Top'
|
||||
elseif cur == total then
|
||||
return 'Bot'
|
||||
else
|
||||
return string.format('%2d%%%%', math.floor(cur / total * 100))
|
||||
end
|
||||
end
|
||||
|
||||
return progress
|
||||
@ -0,0 +1,31 @@
|
||||
local M = require('lualine.component'):extend()
|
||||
|
||||
local default_options = {
|
||||
maxcount = 999,
|
||||
timeout = 500,
|
||||
}
|
||||
|
||||
-- Initializer
|
||||
function M:init(options)
|
||||
-- Run super()
|
||||
M.super.init(self, options)
|
||||
-- Apply default options
|
||||
self.options = vim.tbl_extend('keep', self.options or {}, default_options)
|
||||
end
|
||||
|
||||
-- Function that runs every time statusline is updated
|
||||
function M:update_status()
|
||||
if vim.v.hlsearch == 0 then
|
||||
return ''
|
||||
end
|
||||
|
||||
local ok, result = pcall(vim.fn.searchcount, { maxcount = self.options.maxcount, timeout = self.options.timeout })
|
||||
if not ok or next(result) == nil then
|
||||
return ''
|
||||
end
|
||||
|
||||
local denominator = math.min(result.total, result.maxcount)
|
||||
return string.format('[%d/%d]', result.current, denominator)
|
||||
end
|
||||
|
||||
return M
|
||||
@ -0,0 +1,16 @@
|
||||
local function selectioncount()
|
||||
local mode = vim.fn.mode(true)
|
||||
local line_start, col_start = vim.fn.line('v'), vim.fn.col('v')
|
||||
local line_end, col_end = vim.fn.line('.'), vim.fn.col('.')
|
||||
if mode:match('') then
|
||||
return string.format('%dx%d', math.abs(line_start - line_end) + 1, math.abs(col_start - col_end) + 1)
|
||||
elseif mode:match('V') or line_start ~= line_end then
|
||||
return math.abs(line_start - line_end) + 1
|
||||
elseif mode:match('v') then
|
||||
return math.abs(col_start - col_end) + 1
|
||||
else
|
||||
return ''
|
||||
end
|
||||
end
|
||||
|
||||
return selectioncount
|
||||
@ -0,0 +1,48 @@
|
||||
-- Copyright (c) 2020-2021 shadmansaleh
|
||||
-- MIT license, see LICENSE for more details.
|
||||
local M = require('lualine.component'):extend()
|
||||
|
||||
function M:update_status()
|
||||
local component = self.options[1]
|
||||
local ok, status
|
||||
if self.options.type == nil then
|
||||
ok, status = pcall(M.lua_eval, component)
|
||||
if not ok then
|
||||
status = M.vim_function(component)
|
||||
end
|
||||
else
|
||||
if self.options.type == 'lua_expr' then
|
||||
ok, status = pcall(M.lua_eval, component)
|
||||
if not ok then
|
||||
status = nil
|
||||
end
|
||||
elseif self.options.type == 'vim_fun' then
|
||||
status = M.vim_function(component)
|
||||
end
|
||||
end
|
||||
return status
|
||||
end
|
||||
|
||||
---evaluate the lua code and return it's result as string
|
||||
---@param code string
|
||||
---@return string
|
||||
function M.lua_eval(code)
|
||||
local result = loadstring('return ' .. code)()
|
||||
assert(result, 'String expected got nil')
|
||||
return tostring(result)
|
||||
end
|
||||
|
||||
---call vim function (name) and return it's result as string
|
||||
---@param name string
|
||||
---@return string
|
||||
function M.vim_function(name)
|
||||
-- vim function component
|
||||
local ok, return_val = pcall(vim.api.nvim_call_function, name, {})
|
||||
if not ok then
|
||||
return ''
|
||||
end -- function call failed
|
||||
ok, return_val = pcall(tostring, return_val)
|
||||
return ok and return_val or ''
|
||||
end
|
||||
|
||||
return M
|
||||
@ -0,0 +1,21 @@
|
||||
-- Copyright (c) 2020-2021 shadmansaleh
|
||||
-- MIT license, see LICENSE for more details.
|
||||
local M = require('lualine.component'):extend()
|
||||
|
||||
M.update_status = function(self, is_focused)
|
||||
-- 1st element in options table is the function provided by config
|
||||
local ok, retval
|
||||
ok, retval = pcall(self.options[1], self, is_focused)
|
||||
if not ok then
|
||||
return ''
|
||||
end
|
||||
if type(retval) ~= 'string' then
|
||||
ok, retval = pcall(tostring, retval)
|
||||
if not ok then
|
||||
return ''
|
||||
end
|
||||
end
|
||||
return retval
|
||||
end
|
||||
|
||||
return M
|
||||
@ -0,0 +1,37 @@
|
||||
-- Copyright (c) 2020-2021 shadmansaleh
|
||||
-- MIT license, see LICENSE for more details.
|
||||
local require = require('lualine_require').require
|
||||
local M = require('lualine.component'):extend()
|
||||
local utils = require('lualine.utils.utils')
|
||||
|
||||
function M:update_status()
|
||||
local component = self.options[1]
|
||||
-- vim variable 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 variable aren't present
|
||||
if not (scope and var_name) then
|
||||
return ''
|
||||
end
|
||||
-- Support accessing keys within dictionary
|
||||
-- https://github.com/nvim-lualine/lualine.nvim/issues/25#issuecomment-907374548
|
||||
local name_chunks = vim.split(var_name, '%.')
|
||||
local return_val = vim[scope][name_chunks[1]]
|
||||
for i = 2, #name_chunks do
|
||||
if return_val == nil then
|
||||
break
|
||||
end
|
||||
return_val = return_val[name_chunks[i]]
|
||||
end
|
||||
if return_val == nil then
|
||||
return ''
|
||||
end
|
||||
local ok
|
||||
ok, return_val = pcall(tostring, return_val)
|
||||
return ok and utils.stl_escape(return_val) or ''
|
||||
end
|
||||
|
||||
return M
|
||||
@ -0,0 +1,193 @@
|
||||
-- Copyright (c) 2020-2021 shadmansaleh
|
||||
-- MIT license, see LICENSE for more details.
|
||||
local require = require('lualine_require').require
|
||||
local Tab = require('lualine.components.tabs.tab')
|
||||
local M = require('lualine.component'):extend()
|
||||
local highlight = require('lualine.highlight')
|
||||
|
||||
local default_options = {
|
||||
max_length = 0,
|
||||
tab_max_length = 40,
|
||||
mode = 0,
|
||||
use_mode_colors = false,
|
||||
path = 0,
|
||||
tabs_color = {
|
||||
active = nil,
|
||||
inactive = nil,
|
||||
},
|
||||
show_modified_status = true,
|
||||
symbols = {
|
||||
modified = '[+]',
|
||||
},
|
||||
}
|
||||
|
||||
-- This function is duplicated in buffers
|
||||
---returns the proper hl for tab in section. Used for setting default highlights
|
||||
---@param section string name of section tabs component is in
|
||||
---@param is_active boolean
|
||||
---@return string hl name
|
||||
local function get_hl(section, is_active)
|
||||
local suffix = is_active and highlight.get_mode_suffix() or '_inactive'
|
||||
local section_redirects = {
|
||||
lualine_x = 'lualine_c',
|
||||
lualine_y = 'lualine_b',
|
||||
lualine_z = 'lualine_a',
|
||||
}
|
||||
if section_redirects[section] then
|
||||
section = highlight.highlight_exists(section .. suffix) and section or section_redirects[section]
|
||||
end
|
||||
return section .. suffix
|
||||
end
|
||||
|
||||
function M:init(options)
|
||||
M.super.init(self, options)
|
||||
-- if use_mode_colors is set, use a function so that the colors update
|
||||
local default_active = options.use_mode_colors
|
||||
and function()
|
||||
return get_hl('lualine_' .. options.self.section, true)
|
||||
end
|
||||
or get_hl('lualine_' .. options.self.section, true)
|
||||
default_options.tabs_color = {
|
||||
active = default_active,
|
||||
inactive = get_hl('lualine_' .. options.self.section, false),
|
||||
}
|
||||
self.options = vim.tbl_deep_extend('keep', self.options or {}, default_options)
|
||||
-- stylua: ignore
|
||||
self.highlights = {
|
||||
active = self:create_hl(self.options.tabs_color.active, 'active'),
|
||||
inactive = self:create_hl(self.options.tabs_color.inactive, 'inactive'),
|
||||
}
|
||||
end
|
||||
|
||||
function M:update_status()
|
||||
local data = {}
|
||||
local tabs = {}
|
||||
for nr, id in ipairs(vim.api.nvim_list_tabpages()) do
|
||||
tabs[#tabs + 1] = Tab { tabId = id, tabnr = nr, options = self.options, highlights = self.highlights }
|
||||
end
|
||||
-- mark the first, last, current, before current, after current tabpages
|
||||
-- for rendering
|
||||
local current = vim.fn.tabpagenr()
|
||||
tabs[1].first = true
|
||||
tabs[#tabs].last = true
|
||||
if tabs[current] then
|
||||
tabs[current].current = true
|
||||
end
|
||||
if tabs[current - 1] then
|
||||
tabs[current - 1].beforecurrent = true
|
||||
end
|
||||
if tabs[current + 1] then
|
||||
tabs[current + 1].aftercurrent = true
|
||||
end
|
||||
|
||||
local max_length = self.options.max_length
|
||||
if type(max_length) == 'function' then
|
||||
max_length = max_length(self)
|
||||
end
|
||||
|
||||
if max_length == 0 then
|
||||
max_length = math.floor(vim.o.columns / 3)
|
||||
end
|
||||
local total_length
|
||||
for i, tab in pairs(tabs) do
|
||||
if tab.current then
|
||||
current = i
|
||||
end
|
||||
end
|
||||
local current_tab = tabs[current]
|
||||
-- start drawing from current tab and draw left and right of it until
|
||||
-- all tabpages are drawn or max_length has been reached.
|
||||
if current_tab == nil then -- maybe redundant code
|
||||
local t = Tab {
|
||||
tabId = vim.api.nvim_get_current_tabpage(),
|
||||
tabnr = vim.fn.tabpagenr(),
|
||||
options = self.options,
|
||||
highlights = self.highlights,
|
||||
}
|
||||
t.current = true
|
||||
t.last = true
|
||||
data[#data + 1] = t:render()
|
||||
else
|
||||
data[#data + 1] = current_tab:render()
|
||||
total_length = current_tab.len
|
||||
local i = 0
|
||||
local before, after
|
||||
while true do
|
||||
i = i + 1
|
||||
before = tabs[current - i]
|
||||
after = tabs[current + i]
|
||||
local rendered_before, rendered_after
|
||||
if before == nil and after == nil then
|
||||
break
|
||||
end
|
||||
-- draw left most undrawn tab if fits in max_length
|
||||
if before then
|
||||
rendered_before = before:render()
|
||||
total_length = total_length + before.len
|
||||
if total_length > max_length then
|
||||
break
|
||||
end
|
||||
table.insert(data, 1, rendered_before)
|
||||
end
|
||||
-- draw right most undrawn tab if fits in max_length
|
||||
if after then
|
||||
rendered_after = after:render()
|
||||
total_length = total_length + after.len
|
||||
if total_length > max_length then
|
||||
break
|
||||
end
|
||||
data[#data + 1] = rendered_after
|
||||
end
|
||||
end
|
||||
-- draw ellipsis (...) on relevant sides if all tabs don't fit in max_length
|
||||
if total_length > max_length then
|
||||
if before ~= nil then
|
||||
before.ellipse = true
|
||||
before.first = true
|
||||
table.insert(data, 1, before:render())
|
||||
end
|
||||
if after ~= nil then
|
||||
after.ellipse = true
|
||||
after.last = true
|
||||
data[#data + 1] = after:render()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return table.concat(data)
|
||||
end
|
||||
|
||||
function M:draw()
|
||||
self.status = ''
|
||||
self.applied_separator = ''
|
||||
|
||||
if self.options.cond ~= nil and self.options.cond() ~= true then
|
||||
return self.status
|
||||
end
|
||||
local status = self:update_status()
|
||||
if type(status) == 'string' and #status > 0 then
|
||||
self.status = status
|
||||
self:apply_section_separators()
|
||||
self:apply_separator()
|
||||
end
|
||||
return self.status
|
||||
end
|
||||
|
||||
vim.cmd([[
|
||||
function! LualineSwitchTab(tabnr, mouseclicks, mousebutton, modifiers)
|
||||
execute a:tabnr . "tabnext"
|
||||
endfunction
|
||||
|
||||
function! LualineRenameTab(...)
|
||||
if a:0 == 1
|
||||
let t:tabname = a:1
|
||||
else
|
||||
unlet t:tabname
|
||||
end
|
||||
redrawtabline
|
||||
endfunction
|
||||
|
||||
command! -nargs=? LualineRenameTab call LualineRenameTab("<args>")
|
||||
]])
|
||||
|
||||
return M
|
||||
@ -0,0 +1,178 @@
|
||||
local Tab = require('lualine.utils.class'):extend()
|
||||
|
||||
local modules = require('lualine_require').lazy_require {
|
||||
highlight = 'lualine.highlight',
|
||||
utils = 'lualine.utils.utils',
|
||||
}
|
||||
|
||||
---initialize a new tab from opts
|
||||
---@param opts table
|
||||
function Tab:init(opts)
|
||||
assert(opts.tabnr, 'Cannot create Tab without tabnr')
|
||||
self.tabnr = opts.tabnr
|
||||
self.tabId = opts.tabId
|
||||
self.options = opts.options
|
||||
self.highlights = opts.highlights
|
||||
self.modified_icon = ''
|
||||
self:get_props()
|
||||
end
|
||||
|
||||
function Tab:get_props()
|
||||
local buflist = vim.fn.tabpagebuflist(self.tabnr)
|
||||
local winnr = vim.fn.tabpagewinnr(self.tabnr)
|
||||
local bufnr = buflist[winnr]
|
||||
self.file = modules.utils.stl_escape(vim.api.nvim_buf_get_name(bufnr))
|
||||
self.filetype = vim.api.nvim_buf_get_option(bufnr, 'filetype')
|
||||
self.buftype = vim.api.nvim_buf_get_option(bufnr, 'buftype')
|
||||
|
||||
if self.options.show_modified_status then
|
||||
for _, b in ipairs(buflist) do
|
||||
if vim.api.nvim_buf_get_option(b, 'modified') then
|
||||
self.modified_icon = self.options.symbols.modified or ''
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
---returns name for tab. Tabs name is the name of buffer in last active window
|
||||
--- of the tab.
|
||||
---@return string
|
||||
function Tab:label()
|
||||
local ok, custom_tabname = pcall(vim.api.nvim_tabpage_get_var, self.tabId, 'tabname')
|
||||
if not ok then
|
||||
custom_tabname = nil
|
||||
end
|
||||
if custom_tabname and custom_tabname ~= '' then
|
||||
return modules.utils.stl_escape(custom_tabname)
|
||||
end
|
||||
if self.filetype == 'fugitive' then
|
||||
return 'fugitive: ' .. vim.fn.fnamemodify(self.file, ':h:h:t')
|
||||
elseif self.buftype == 'help' then
|
||||
return 'help:' .. vim.fn.fnamemodify(self.file, ':t:r')
|
||||
elseif self.buftype == 'terminal' then
|
||||
local match = string.match(vim.split(self.file, ' ')[1], 'term:.*:(%a+)')
|
||||
return match ~= nil and match or vim.fn.fnamemodify(vim.env.SHELL, ':t')
|
||||
elseif self.file == '' then
|
||||
return '[No Name]'
|
||||
end
|
||||
if self.options.path == 1 then
|
||||
return vim.fn.fnamemodify(self.file, ':~:.')
|
||||
elseif self.options.path == 2 then
|
||||
return vim.fn.fnamemodify(self.file, ':p')
|
||||
elseif self.options.path == 3 then
|
||||
return vim.fn.fnamemodify(self.file, ':p:~')
|
||||
else
|
||||
return vim.fn.fnamemodify(self.file, ':t')
|
||||
end
|
||||
end
|
||||
|
||||
---shortens path by turning apple/orange -> a/orange
|
||||
---@param path string
|
||||
---@param sep string path separator
|
||||
---@param max_len integer maximum length of the full filename string
|
||||
---@return string
|
||||
local function shorten_path(path, sep, max_len)
|
||||
local len = #path
|
||||
if len <= max_len then
|
||||
return path
|
||||
end
|
||||
|
||||
local segments = vim.split(path, sep)
|
||||
for idx = 1, #segments - 1 do
|
||||
if len <= max_len then
|
||||
break
|
||||
end
|
||||
|
||||
local segment = segments[idx]
|
||||
local shortened = segment:sub(1, vim.startswith(segment, '.') and 2 or 1)
|
||||
segments[idx] = shortened
|
||||
len = len - (#segment - #shortened)
|
||||
end
|
||||
|
||||
return table.concat(segments, sep)
|
||||
end
|
||||
|
||||
---returns rendered tab
|
||||
---@return string
|
||||
function Tab:render()
|
||||
local name = self:label()
|
||||
if self.options.tab_max_length ~= 0 then
|
||||
local path_separator = package.config:sub(1, 1)
|
||||
name = shorten_path(name, path_separator, self.options.tab_max_length)
|
||||
end
|
||||
if self.options.fmt then
|
||||
name = self.options.fmt(name or '', self)
|
||||
end
|
||||
if self.ellipse then -- show ellipsis
|
||||
name = '...'
|
||||
else
|
||||
-- different formats for different modes
|
||||
if self.options.mode == 0 then
|
||||
name = tostring(self.tabnr)
|
||||
if self.modified_icon ~= '' then
|
||||
name = string.format('%s%s', name, self.modified_icon)
|
||||
end
|
||||
elseif self.options.mode == 1 then
|
||||
if self.modified_icon ~= '' then
|
||||
name = string.format('%s %s', self.modified_icon, name)
|
||||
end
|
||||
else
|
||||
name = string.format('%s%s %s', tostring(self.tabnr), self.modified_icon, name)
|
||||
end
|
||||
end
|
||||
|
||||
name = Tab.apply_padding(name, self.options.padding)
|
||||
self.len = vim.fn.strchars(name)
|
||||
|
||||
-- setup for mouse clicks
|
||||
local line = string.format('%%%s@LualineSwitchTab@%s%%T', self.tabnr, name)
|
||||
-- apply highlight
|
||||
line = modules.highlight.component_format_highlight(self.highlights[(self.current and 'active' or 'inactive')])
|
||||
.. line
|
||||
|
||||
-- apply separators
|
||||
if self.options.self.section < 'x' and not self.first then
|
||||
local sep_before = self:separator_before()
|
||||
line = sep_before .. line
|
||||
self.len = self.len + vim.fn.strchars(sep_before)
|
||||
elseif self.options.self.section >= 'x' and not self.last then
|
||||
local sep_after = self:separator_after()
|
||||
line = line .. sep_after
|
||||
self.len = self.len + vim.fn.strchars(sep_after)
|
||||
end
|
||||
return line
|
||||
end
|
||||
|
||||
---apply separator before current tab
|
||||
---@return string
|
||||
function Tab:separator_before()
|
||||
if self.current or self.aftercurrent then
|
||||
return '%Z{' .. self.options.section_separators.left .. '}'
|
||||
else
|
||||
return self.options.component_separators.left
|
||||
end
|
||||
end
|
||||
|
||||
---apply separator after current tab
|
||||
---@return string
|
||||
function Tab:separator_after()
|
||||
if self.current or self.beforecurrent then
|
||||
return '%z{' .. self.options.section_separators.right .. '}'
|
||||
else
|
||||
return self.options.component_separators.right
|
||||
end
|
||||
end
|
||||
|
||||
---adds spaces to left and right
|
||||
function Tab.apply_padding(str, padding)
|
||||
local l_padding, r_padding = 1, 1
|
||||
if type(padding) == 'number' then
|
||||
l_padding, r_padding = padding, padding
|
||||
elseif type(padding) == 'table' then
|
||||
l_padding, r_padding = padding.left or 0, padding.right or 0
|
||||
end
|
||||
return string.rep(' ', l_padding) .. str .. string.rep(' ', r_padding)
|
||||
end
|
||||
|
||||
return Tab
|
||||
@ -0,0 +1,64 @@
|
||||
local Window = require('lualine.components.windows.window')
|
||||
local M = require('lualine.components.buffers'):extend()
|
||||
|
||||
local default_options = {
|
||||
disabled_filetypes = {},
|
||||
disabled_buftypes = { 'quickfix', 'prompt' },
|
||||
}
|
||||
|
||||
function M:init(options)
|
||||
options.buffers_color = nil -- buffers_color isn't windows option.
|
||||
M.super.init(self, options)
|
||||
|
||||
self.options = vim.tbl_deep_extend('keep', self.options or {}, default_options)
|
||||
self.options.windows_color = vim.tbl_deep_extend('keep', self.options.windows_color or {}, self.options.buffers_color)
|
||||
self.options.buffers_color = nil -- this is the default value of colors generated by parent buffers component.
|
||||
|
||||
self.highlights = {
|
||||
active = self:create_hl(self.options.windows_color.active, 'active'),
|
||||
inactive = self:create_hl(self.options.windows_color.inactive, 'inactive'),
|
||||
}
|
||||
end
|
||||
|
||||
function M:new_buffer(winnr)
|
||||
winnr = winnr or vim.api.nvim_get_current_win()
|
||||
|
||||
return Window:new {
|
||||
winnr = winnr,
|
||||
options = self.options,
|
||||
highlights = self.highlights,
|
||||
}
|
||||
end
|
||||
|
||||
--- Override to only return buffers shown in the windows of the current tab
|
||||
function M:buffers()
|
||||
local tabnr = vim.api.nvim_get_current_tabpage()
|
||||
local buffers = {}
|
||||
|
||||
for _, winnr in ipairs(vim.api.nvim_tabpage_list_wins(tabnr)) do
|
||||
if not self:should_hide(winnr) then
|
||||
buffers[#buffers + 1] = self:new_buffer(winnr)
|
||||
end
|
||||
end
|
||||
|
||||
return buffers
|
||||
end
|
||||
|
||||
function M:should_hide(winnr)
|
||||
local bufnr = vim.api.nvim_win_get_buf(winnr)
|
||||
local filetype = vim.api.nvim_buf_get_option(bufnr, 'filetype')
|
||||
local buftype = vim.api.nvim_buf_get_option(bufnr, 'buftype')
|
||||
local is_filetype_disabled = vim.tbl_contains(self.options.disabled_filetypes, filetype)
|
||||
local is_buftype_disabled = vim.tbl_contains(self.options.disabled_buftypes, buftype)
|
||||
local is_floating = '' ~= vim.api.nvim_win_get_config(winnr).relative
|
||||
|
||||
return is_floating or is_buftype_disabled or is_filetype_disabled
|
||||
end
|
||||
|
||||
vim.cmd([[
|
||||
function! LualineSwitchWindow(win_number, mouseclicks, mousebutton, modifiers)
|
||||
execute a:win_number . 'wincmd w'
|
||||
endfunction
|
||||
]])
|
||||
|
||||
return M
|
||||
@ -0,0 +1,35 @@
|
||||
local Window = require('lualine.components.buffers.buffer'):extend()
|
||||
|
||||
---initialize a new buffer from opts
|
||||
---@param opts table
|
||||
function Window:init(opts)
|
||||
assert(opts.winnr, 'Cannot create Window without winnr')
|
||||
opts.bufnr = vim.api.nvim_win_get_buf(opts.winnr)
|
||||
|
||||
Window.super.init(self, opts)
|
||||
|
||||
self.winnr = opts.winnr
|
||||
self.win_number = vim.api.nvim_win_get_number(self.winnr)
|
||||
end
|
||||
|
||||
function Window:is_current()
|
||||
return vim.api.nvim_get_current_win() == self.winnr
|
||||
end
|
||||
|
||||
function Window:apply_mode(name)
|
||||
if self.options.mode == 0 then
|
||||
return string.format('%s%s%s', self.icon, name, self.modified_icon)
|
||||
end
|
||||
|
||||
if self.options.mode == 1 then
|
||||
return string.format('%s %s%s', self.win_number, self.icon, self.modified_icon)
|
||||
end
|
||||
|
||||
return string.format('%s %s%s%s', self.win_number, self.icon, name, self.modified_icon)
|
||||
end
|
||||
|
||||
function Window:configure_mouse_click(name)
|
||||
return string.format('%%%s@LualineSwitchWindow@%s%%T', self.win_number, name)
|
||||
end
|
||||
|
||||
return Window
|
||||
@ -0,0 +1,135 @@
|
||||
-- Copyright (c) 2020-2021 hoob3rt
|
||||
-- MIT license, see LICENSE for more details.
|
||||
local require = require('lualine_require').require
|
||||
local utils = require('lualine.utils.utils')
|
||||
local modules = require('lualine_require').lazy_require {
|
||||
utils_notices = 'lualine.utils.notices',
|
||||
}
|
||||
|
||||
local config = {
|
||||
options = {
|
||||
icons_enabled = true,
|
||||
theme = 'auto',
|
||||
component_separators = { left = '', right = '' },
|
||||
section_separators = { left = '', right = '' },
|
||||
disabled_filetypes = {
|
||||
statusline = {},
|
||||
winbar = {},
|
||||
},
|
||||
ignore_focus = {},
|
||||
always_divide_middle = true,
|
||||
globalstatus = vim.go.laststatus == 3,
|
||||
refresh = {
|
||||
statusline = 1000,
|
||||
tabline = 1000,
|
||||
winbar = 1000,
|
||||
},
|
||||
},
|
||||
sections = {
|
||||
lualine_a = { 'mode' },
|
||||
lualine_b = { 'branch', 'diff', 'diagnostics' },
|
||||
lualine_c = { 'filename' },
|
||||
lualine_x = { 'encoding', 'fileformat', 'filetype' },
|
||||
lualine_y = { 'progress' },
|
||||
lualine_z = { 'location' },
|
||||
},
|
||||
inactive_sections = {
|
||||
lualine_a = {},
|
||||
lualine_b = {},
|
||||
lualine_c = { 'filename' },
|
||||
lualine_x = { 'location' },
|
||||
lualine_y = {},
|
||||
lualine_z = {},
|
||||
},
|
||||
tabline = {},
|
||||
winbar = {},
|
||||
inactive_winbar = {},
|
||||
extensions = {},
|
||||
}
|
||||
|
||||
--- change separator format 'x' to {left='x', right='x'}
|
||||
---@param separators string|table
|
||||
---@return table
|
||||
local function fix_separators(separators)
|
||||
if separators ~= nil then
|
||||
if type(separators) == 'string' then
|
||||
return { left = separators, right = separators }
|
||||
end
|
||||
end
|
||||
return separators
|
||||
end
|
||||
|
||||
---copy raw disabled_filetypes to inner statusline & winbar tables.
|
||||
---@param disabled_filetypes table
|
||||
---@return table
|
||||
local function fix_disabled_filetypes(disabled_filetypes)
|
||||
if disabled_filetypes == nil then
|
||||
return
|
||||
end
|
||||
if disabled_filetypes.statusline == nil then
|
||||
disabled_filetypes.statusline = {}
|
||||
end
|
||||
if disabled_filetypes.winbar == nil then
|
||||
disabled_filetypes.winbar = {}
|
||||
end
|
||||
for k, disabled_ft in ipairs(disabled_filetypes) do
|
||||
table.insert(disabled_filetypes.statusline, disabled_ft)
|
||||
table.insert(disabled_filetypes.winbar, disabled_ft)
|
||||
disabled_filetypes[k] = nil
|
||||
end
|
||||
return disabled_filetypes
|
||||
end
|
||||
---extends config based on config_table
|
||||
---@param config_table table
|
||||
---@return table copy of config
|
||||
local function apply_configuration(config_table)
|
||||
if not config_table then
|
||||
return utils.deepcopy(config)
|
||||
end
|
||||
local function parse_sections(section_group_name)
|
||||
if config_table[section_group_name] == nil then
|
||||
return
|
||||
end
|
||||
if not next(config_table[section_group_name]) then
|
||||
config[section_group_name] = {}
|
||||
return
|
||||
end
|
||||
for section_name, section in pairs(config_table[section_group_name]) do
|
||||
if section_name == 'refresh' then
|
||||
config[section_group_name][section_name] =
|
||||
vim.tbl_deep_extend('force', config[section_group_name][section_name], utils.deepcopy(section))
|
||||
else
|
||||
config[section_group_name][section_name] = utils.deepcopy(section)
|
||||
end
|
||||
end
|
||||
end
|
||||
if vim.fn.has('nvim-0.8') == 0 and (next(config_table.winbar or {}) or next(config_table.inactive_winbar or {})) then
|
||||
modules.utils_notices.add_notice('### winbar\nSorry `winbar can only be used in neovim 0.8 or higher.\n')
|
||||
config_table.winbar = {}
|
||||
config_table.inactive_winbar = {}
|
||||
end
|
||||
parse_sections('options')
|
||||
parse_sections('sections')
|
||||
parse_sections('inactive_sections')
|
||||
parse_sections('tabline')
|
||||
parse_sections('winbar')
|
||||
parse_sections('inactive_winbar')
|
||||
if config_table.extensions then
|
||||
config.extensions = utils.deepcopy(config_table.extensions)
|
||||
end
|
||||
config.options.section_separators = fix_separators(config.options.section_separators)
|
||||
config.options.component_separators = fix_separators(config.options.component_separators)
|
||||
config.options.disabled_filetypes = fix_disabled_filetypes(config.options.disabled_filetypes)
|
||||
return utils.deepcopy(config)
|
||||
end
|
||||
|
||||
--- returns current active config
|
||||
---@return table a copy of config
|
||||
local function get_current_config()
|
||||
return utils.deepcopy(config)
|
||||
end
|
||||
|
||||
return {
|
||||
get_config = get_current_config,
|
||||
apply_configuration = apply_configuration,
|
||||
}
|
||||
@ -0,0 +1,9 @@
|
||||
-- MIT license, see LICENSE for more details.
|
||||
-- Extension for aerial.nvim
|
||||
local M = {}
|
||||
|
||||
M.sections = { lualine_a = { 'filetype' } }
|
||||
|
||||
M.filetypes = { 'aerial' }
|
||||
|
||||
return M
|
||||
@ -0,0 +1,11 @@
|
||||
-- Copyright (c) 2020-2021 hoob3rt
|
||||
-- MIT license, see LICENSE for more details.
|
||||
local nerdtree = require('lualine.extensions.nerdtree')
|
||||
|
||||
local M = {}
|
||||
|
||||
M.sections = vim.deepcopy(nerdtree.sections)
|
||||
|
||||
M.filetypes = { 'CHADTree' }
|
||||
|
||||
return M
|
||||
@ -0,0 +1,20 @@
|
||||
local M = {}
|
||||
|
||||
M.sections = {
|
||||
lualine_a = {
|
||||
function()
|
||||
return vim.fn['ctrlspace#context#Configuration']().Symbols.CS
|
||||
end,
|
||||
},
|
||||
lualine_b = { 'ctrlspace#api#StatuslineModeSegment' },
|
||||
lualine_y = { 'ctrlspace#api#StatuslineTabSegment' },
|
||||
lualine_z = {
|
||||
function()
|
||||
return 'CtrlSpace'
|
||||
end,
|
||||
},
|
||||
}
|
||||
|
||||
M.filetypes = { 'ctrlspace' }
|
||||
|
||||
return M
|
||||
@ -0,0 +1,11 @@
|
||||
-- MIT license, see LICENSE for more details.
|
||||
-- Extension for fern file explorer.
|
||||
local nerdtree = require('lualine.extensions.nerdtree')
|
||||
|
||||
local M = {}
|
||||
|
||||
M.sections = vim.deepcopy(nerdtree.sections)
|
||||
|
||||
M.filetypes = { 'fern' }
|
||||
|
||||
return M
|
||||
@ -0,0 +1,17 @@
|
||||
-- Copyright (c) 2020-2021 hoob3rt
|
||||
-- MIT license, see LICENSE for more details.
|
||||
local M = {}
|
||||
|
||||
local function fugitive_branch()
|
||||
local icon = '' -- e0a0
|
||||
return icon .. ' ' .. vim.fn.FugitiveHead()
|
||||
end
|
||||
|
||||
M.sections = {
|
||||
lualine_a = { fugitive_branch },
|
||||
lualine_z = { 'location' },
|
||||
}
|
||||
|
||||
M.filetypes = { 'fugitive' }
|
||||
|
||||
return M
|
||||
@ -0,0 +1,45 @@
|
||||
--[[
|
||||
lualine extension for fzf filetypes:
|
||||
works with both https://github.com/junegunn/fzf.vim and https://github.com/ibhagwan/fzf-lua
|
||||
|
||||
-- fzf-lua must be set-up in split mode
|
||||
]]
|
||||
|
||||
local function has_fzf()
|
||||
return pcall(require, 'fzf-lua')
|
||||
end
|
||||
|
||||
local function fzf_picker()
|
||||
if not has_fzf() then
|
||||
return ''
|
||||
end
|
||||
|
||||
local info_string = vim.inspect(require('fzf-lua').get_info()['fnc'])
|
||||
return info_string:gsub('"', '')
|
||||
end
|
||||
|
||||
local function fzf_element()
|
||||
if not has_fzf() then
|
||||
return ''
|
||||
end
|
||||
|
||||
local fzf = require('fzf-lua')
|
||||
local selected = fzf.get_info().selected
|
||||
return fzf.path.entry_to_file(selected).path
|
||||
end
|
||||
|
||||
local function fzf_statusline()
|
||||
return 'FZF'
|
||||
end
|
||||
|
||||
local M = {}
|
||||
|
||||
M.sections = {
|
||||
lualine_a = { fzf_statusline },
|
||||
lualine_y = { fzf_element },
|
||||
lualine_z = { fzf_picker },
|
||||
}
|
||||
|
||||
M.filetypes = { 'fzf' }
|
||||
|
||||
return M
|
||||
@ -0,0 +1,31 @@
|
||||
-- lualine extension for lazy.nvim
|
||||
|
||||
local ok, lazy = pcall(require, 'lazy')
|
||||
if not ok then
|
||||
return ''
|
||||
end
|
||||
|
||||
local M = {}
|
||||
|
||||
M.sections = {
|
||||
lualine_a = {
|
||||
function()
|
||||
return 'lazy 💤'
|
||||
end,
|
||||
},
|
||||
lualine_b = {
|
||||
function()
|
||||
return 'loaded: ' .. lazy.stats().loaded .. '/' .. lazy.stats().count
|
||||
end,
|
||||
},
|
||||
lualine_c = {
|
||||
{
|
||||
require('lazy.status').updates,
|
||||
cond = require('lazy.status').has_updates,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
M.filetypes = { 'lazy' }
|
||||
|
||||
return M
|
||||
@ -0,0 +1,16 @@
|
||||
local M = {}
|
||||
|
||||
M.sections = {
|
||||
lualine_a = {
|
||||
function()
|
||||
return 'MAN'
|
||||
end,
|
||||
},
|
||||
lualine_b = { { 'filename', file_status = false } },
|
||||
lualine_y = { 'progress' },
|
||||
lualine_z = { 'location' },
|
||||
}
|
||||
|
||||
M.filetypes = { 'man' }
|
||||
|
||||
return M
|
||||
@ -0,0 +1,29 @@
|
||||
-- lualine extension for mason.nvim
|
||||
|
||||
local mason_registry
|
||||
local function maybe_set_registry()
|
||||
local ok, registry = pcall(require, 'mason-registry')
|
||||
if ok then
|
||||
mason_registry = registry
|
||||
end
|
||||
end
|
||||
|
||||
local M = {}
|
||||
|
||||
M.sections = {
|
||||
lualine_a = {
|
||||
function()
|
||||
return 'Mason'
|
||||
end,
|
||||
},
|
||||
lualine_b = {
|
||||
function()
|
||||
maybe_set_registry()
|
||||
return 'Installed: ' .. #mason_registry.get_installed_packages() .. '/' .. #mason_registry.get_all_package_specs()
|
||||
end,
|
||||
},
|
||||
}
|
||||
|
||||
M.filetypes = { 'mason' }
|
||||
|
||||
return M
|
||||
@ -0,0 +1,19 @@
|
||||
local M = {}
|
||||
|
||||
M.sections = {
|
||||
lualine_a = {
|
||||
function()
|
||||
local ft = vim.opt_local.filetype:get()
|
||||
return (ft == 'Mundo') and 'Change tree' or (ft == 'MundoDiff') and 'Change diff'
|
||||
end,
|
||||
},
|
||||
lualine_y = { 'progress' },
|
||||
lualine_z = { 'location' },
|
||||
}
|
||||
|
||||
M.filetypes = {
|
||||
'Mundo',
|
||||
'MundoDiff',
|
||||
}
|
||||
|
||||
return M
|
||||
@ -0,0 +1,11 @@
|
||||
-- Copyright (c) 2020-2021 hoob3rt
|
||||
-- MIT license, see LICENSE for more details.
|
||||
local nerdtree = require('lualine.extensions.nerdtree')
|
||||
|
||||
local M = {}
|
||||
|
||||
M.sections = vim.deepcopy(nerdtree.sections)
|
||||
|
||||
M.filetypes = { 'neo-tree' }
|
||||
|
||||
return M
|
||||
@ -0,0 +1,15 @@
|
||||
-- Copyright (c) 2020-2021 hoob3rt
|
||||
-- MIT license, see LICENSE for more details.
|
||||
local function get_short_cwd()
|
||||
return vim.fn.fnamemodify(vim.fn.getcwd(), ':~')
|
||||
end
|
||||
|
||||
local M = {}
|
||||
|
||||
M.sections = {
|
||||
lualine_a = { get_short_cwd },
|
||||
}
|
||||
|
||||
M.filetypes = { 'nerdtree' }
|
||||
|
||||
return M
|
||||
@ -0,0 +1,18 @@
|
||||
-- MIT license, see LICENSE for more details.
|
||||
-- Extension for nvim-dap-ui
|
||||
local M = {}
|
||||
|
||||
M.sections = {
|
||||
lualine_a = { { 'filename', file_status = false } },
|
||||
}
|
||||
|
||||
M.filetypes = {
|
||||
'dap-repl',
|
||||
'dapui_console',
|
||||
'dapui_watches',
|
||||
'dapui_stacks',
|
||||
'dapui_breakpoints',
|
||||
'dapui_scopes',
|
||||
}
|
||||
|
||||
return M
|
||||
@ -0,0 +1,11 @@
|
||||
-- Copyright (c) 2020-2021 hoob3rt
|
||||
-- MIT license, see LICENSE for more details.
|
||||
local nerdtree = require('lualine.extensions.nerdtree')
|
||||
|
||||
local M = {}
|
||||
|
||||
M.sections = vim.deepcopy(nerdtree.sections)
|
||||
|
||||
M.filetypes = { 'NvimTree' }
|
||||
|
||||
return M
|
||||
@ -0,0 +1,20 @@
|
||||
-- Extension for oil.nvim
|
||||
|
||||
local M = {}
|
||||
|
||||
M.sections = {
|
||||
lualine_a = {
|
||||
function()
|
||||
local ok, oil = pcall(require, 'oil')
|
||||
if ok then
|
||||
return vim.fn.fnamemodify(oil.get_current_dir(), ':~')
|
||||
else
|
||||
return ''
|
||||
end
|
||||
end,
|
||||
},
|
||||
}
|
||||
|
||||
M.filetypes = { 'oil' }
|
||||
|
||||
return M
|
||||
@ -0,0 +1,16 @@
|
||||
-- Copyright (c) 2020-2021 hoob3rt
|
||||
-- MIT license, see LICENSE for more details.
|
||||
|
||||
local M = {}
|
||||
|
||||
M.sections = {
|
||||
lualine_a = {
|
||||
function()
|
||||
return 'OverseerList'
|
||||
end,
|
||||
},
|
||||
}
|
||||
|
||||
M.filetypes = { 'OverseerList' }
|
||||
|
||||
return M
|
||||
@ -0,0 +1,34 @@
|
||||
-- Copyright (c) 2020-2021 hoob3rt
|
||||
-- MIT license, see LICENSE for more details.
|
||||
--
|
||||
local function is_loclist()
|
||||
return vim.fn.getloclist(0, { filewinid = 1 }).filewinid ~= 0
|
||||
end
|
||||
|
||||
local function label()
|
||||
return is_loclist() and 'Location List' or 'Quickfix List'
|
||||
end
|
||||
|
||||
local function title()
|
||||
if is_loclist() then
|
||||
return vim.fn.getloclist(0, { title = 0 }).title
|
||||
end
|
||||
return vim.fn.getqflist({ title = 0 }).title
|
||||
end
|
||||
|
||||
local M = {}
|
||||
|
||||
function M.init()
|
||||
-- Make sure ft wf doesn't create a custom statusline
|
||||
vim.g.qf_disable_statusline = true
|
||||
end
|
||||
|
||||
M.sections = {
|
||||
lualine_a = { label },
|
||||
lualine_b = { title },
|
||||
lualine_z = { 'location' },
|
||||
}
|
||||
|
||||
M.filetypes = { 'qf' }
|
||||
|
||||
return M
|
||||
@ -0,0 +1,9 @@
|
||||
-- Copyright (c) 2020-2021 hoob3rt
|
||||
-- MIT license, see LICENSE for more details.
|
||||
local M = {}
|
||||
|
||||
M.sections = { lualine_a = { 'filetype' } }
|
||||
|
||||
M.filetypes = { 'Outline' }
|
||||
|
||||
return M
|
||||
@ -0,0 +1,16 @@
|
||||
-- Copyright (c) 2020-2021 hoob3rt
|
||||
-- MIT license, see LICENSE for more details.
|
||||
|
||||
local function toggleterm_statusline()
|
||||
return 'ToggleTerm #' .. vim.b.toggle_number
|
||||
end
|
||||
|
||||
local M = {}
|
||||
|
||||
M.sections = {
|
||||
lualine_a = { toggleterm_statusline },
|
||||
}
|
||||
|
||||
M.filetypes = { 'toggleterm' }
|
||||
|
||||
return M
|
||||
@ -0,0 +1,22 @@
|
||||
local M = {}
|
||||
|
||||
local function get_trouble_mode()
|
||||
local opts = require('trouble.config').options
|
||||
|
||||
local words = vim.split(opts.mode, '[%W]')
|
||||
for i, word in ipairs(words) do
|
||||
words[i] = word:sub(1, 1):upper() .. word:sub(2)
|
||||
end
|
||||
|
||||
return table.concat(words, ' ')
|
||||
end
|
||||
|
||||
M.sections = {
|
||||
lualine_a = {
|
||||
get_trouble_mode,
|
||||
},
|
||||
}
|
||||
|
||||
M.filetypes = { 'Trouble' }
|
||||
|
||||
return M
|
||||
@ -0,0 +1,494 @@
|
||||
-- Copyright (c) 2020-2021 hoob3rt
|
||||
-- MIT license, see LICENSE for more details.
|
||||
local M = {}
|
||||
local lualine_require = require('lualine_require')
|
||||
local require = lualine_require.require
|
||||
local modules = lualine_require.lazy_require {
|
||||
utils = 'lualine.utils.utils',
|
||||
color_utils = 'lualine.utils.color_utils',
|
||||
}
|
||||
|
||||
local section_highlight_map = { x = 'c', y = 'b', z = 'a' }
|
||||
local active_theme = nil
|
||||
local theme_hls = {}
|
||||
local create_cterm_colors = false
|
||||
|
||||
-- table to store the highlight names created by lualine
|
||||
local loaded_highlights = {}
|
||||
|
||||
-- table to map mode to highlight suffixes
|
||||
local mode_to_highlight = {
|
||||
['VISUAL'] = '_visual',
|
||||
['V-BLOCK'] = '_visual',
|
||||
['V-LINE'] = '_visual',
|
||||
['SELECT'] = '_visual',
|
||||
['S-LINE'] = '_visual',
|
||||
['S-BLOCK'] = '_visual',
|
||||
['REPLACE'] = '_replace',
|
||||
['V-REPLACE'] = '_replace',
|
||||
['INSERT'] = '_insert',
|
||||
['COMMAND'] = '_command',
|
||||
['EX'] = '_command',
|
||||
['MORE'] = '_command',
|
||||
['CONFIRM'] = '_command',
|
||||
['TERMINAL'] = '_terminal',
|
||||
}
|
||||
|
||||
--- Get highlight suffix for current mode, or inactive if not focused
|
||||
---@return string mode_suffix
|
||||
function M.get_mode_suffix()
|
||||
local mode = require('lualine.utils.mode').get_mode()
|
||||
return mode_to_highlight[mode] or '_normal'
|
||||
end
|
||||
|
||||
--- determine if an highlight exist and isn't cleared
|
||||
---@param highlight_name string
|
||||
---@return boolean whether hl_group was defined with highlight_name
|
||||
function M.highlight_exists(highlight_name)
|
||||
return loaded_highlights[highlight_name] or false
|
||||
end
|
||||
|
||||
--- clears loaded_highlights table and highlights
|
||||
local function clear_highlights()
|
||||
for highlight_name, _ in pairs(loaded_highlights) do
|
||||
vim.cmd('highlight clear ' .. highlight_name)
|
||||
end
|
||||
loaded_highlights = {}
|
||||
end
|
||||
|
||||
---converts cterm, color_name type colors to #rrggbb format
|
||||
---@param color string|number
|
||||
---@return string
|
||||
local function sanitize_color(color)
|
||||
if color == nil or color == '' or (type(color) == 'string' and color:lower() == 'none') then
|
||||
return 'None'
|
||||
end
|
||||
if type(color) == 'string' then
|
||||
if color:sub(1, 1) == '#' then
|
||||
return color
|
||||
end -- RGB value
|
||||
return modules.color_utils.color_name2rgb(color)
|
||||
elseif type(color) == 'number' then
|
||||
if color > 255 then
|
||||
error("What's this it can't be higher then 255 and you've given " .. color)
|
||||
end
|
||||
return modules.color_utils.cterm2rgb(color)
|
||||
end
|
||||
end
|
||||
|
||||
---converts color_name type colors to cterm format and let cterm color pass through
|
||||
---@param color string|number
|
||||
---@return string
|
||||
local function sanitize_color_for_cterm(color)
|
||||
if type(color) == 'number' then
|
||||
if color > 255 then
|
||||
error("What's this it can't be higher then 255 and you've given " .. color)
|
||||
end
|
||||
return color
|
||||
end
|
||||
return modules.color_utils.rgb2cterm(sanitize_color(color))
|
||||
end
|
||||
|
||||
function M.get_lualine_hl(name)
|
||||
local hl = loaded_highlights[name]
|
||||
if hl and not hl.empty then
|
||||
if hl.link then
|
||||
return modules.utils.extract_highlight_colors(hl.link)
|
||||
end
|
||||
local hl_def = {
|
||||
fg = hl.fg ~= 'None' and vim.deepcopy(hl.fg) or nil,
|
||||
bg = hl.bg ~= 'None' and vim.deepcopy(hl.bg) or nil,
|
||||
sp = hl.sp ~= 'None' and vim.deepcopy(hl.sp) or nil,
|
||||
}
|
||||
if hl.gui then
|
||||
for _, flag in ipairs(vim.split(hl.gui, ',')) do
|
||||
if flag ~= 'None' then
|
||||
hl_def[flag] = true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return hl_def
|
||||
end
|
||||
end
|
||||
|
||||
--- Define a hl_group
|
||||
---@param name string
|
||||
---@param foreground string|number: color
|
||||
---@param background string|number: color
|
||||
---@param gui table cterm/gui options like bold/italic etc.
|
||||
---@param link string hl_group name to link new hl to
|
||||
function M.highlight(name, foreground, background, gui, link)
|
||||
local command = { 'highlight!' }
|
||||
if link and #link > 0 then
|
||||
if loaded_highlights[name] and loaded_highlights[name].link == link then
|
||||
return
|
||||
end
|
||||
vim.list_extend(command, { 'link', name, link })
|
||||
else
|
||||
local foreground_rgb = sanitize_color(foreground)
|
||||
local background_rgb = sanitize_color(background)
|
||||
gui = (gui ~= nil and gui ~= '') and gui or 'None'
|
||||
if
|
||||
loaded_highlights[name]
|
||||
and loaded_highlights[name].fg == foreground_rgb
|
||||
and loaded_highlights[name].bg == background_rgb
|
||||
and loaded_highlights[name].gui == gui
|
||||
then
|
||||
return -- color is already defined why are we doing this anyway ?
|
||||
end
|
||||
table.insert(command, name)
|
||||
table.insert(command, 'guifg=' .. foreground_rgb)
|
||||
table.insert(command, 'guibg=' .. background_rgb)
|
||||
table.insert(command, 'gui=' .. gui)
|
||||
if create_cterm_colors then
|
||||
-- Not setting color from xxxground_rgb to let possible user 256 number through
|
||||
table.insert(command, 'ctermfg=' .. sanitize_color_for_cterm(foreground))
|
||||
table.insert(command, 'ctermbg=' .. sanitize_color_for_cterm(background))
|
||||
table.insert(command, 'cterm=' .. gui)
|
||||
end
|
||||
end
|
||||
vim.cmd(table.concat(command, ' '))
|
||||
|
||||
-- update attached hl groups
|
||||
local old_hl_def = loaded_highlights[name]
|
||||
if old_hl_def and next(old_hl_def.attached) then
|
||||
-- Update attached hl groups as they announced to depend on hl_group 'name'
|
||||
-- 'hl' being in 'name's attached table means 'hl'
|
||||
-- depends of 'name'.
|
||||
-- 'hl' key in attached table will contain a table that
|
||||
-- defines the relation between 'hl' & 'name'.
|
||||
-- name.attached.hl = { bg = 'fg' } means
|
||||
-- hl's fg is same as 'names' bg . So 'hl's fg should
|
||||
-- be updated when ever 'name' changes it's 'bg'
|
||||
local bg_changed = old_hl_def.bg ~= background
|
||||
local fg_changed = old_hl_def.bg ~= foreground
|
||||
local gui_changed = old_hl_def.gui ~= gui
|
||||
for attach_name, attach_desc in pairs(old_hl_def.attached) do
|
||||
if bg_changed and attach_desc.bg and loaded_highlights[attach_name] then
|
||||
M.highlight(
|
||||
attach_name,
|
||||
attach_desc.bg == 'fg' and background or loaded_highlights[attach_name].fg,
|
||||
attach_desc.bg == 'bg' and background or loaded_highlights[attach_name].bg,
|
||||
loaded_highlights[attach_name].gui,
|
||||
loaded_highlights[attach_name].link
|
||||
)
|
||||
end
|
||||
if fg_changed and attach_desc.fg and loaded_highlights[attach_name] then
|
||||
M.highlight(
|
||||
attach_name,
|
||||
attach_desc.fg == 'fg' and foreground or loaded_highlights[attach_name].fg,
|
||||
attach_desc.fg == 'bg' and foreground or loaded_highlights[attach_name].bg,
|
||||
loaded_highlights[attach_name].gui,
|
||||
loaded_highlights[attach_name].link
|
||||
)
|
||||
end
|
||||
if gui_changed and attach_desc.gui and loaded_highlights[attach_name] then
|
||||
M.highlight(
|
||||
attach_name,
|
||||
loaded_highlights[attach_name].fg,
|
||||
loaded_highlights[attach_name].bg,
|
||||
gui,
|
||||
loaded_highlights[attach_name].link
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
-- store current hl state
|
||||
loaded_highlights[name] = {
|
||||
fg = foreground,
|
||||
bg = background,
|
||||
gui = gui,
|
||||
link = link,
|
||||
attached = old_hl_def and old_hl_def.attached or {},
|
||||
}
|
||||
end
|
||||
|
||||
---Attach a hl to another, so the attached auto updates on change to hl that it's attached too.
|
||||
---@param provider string the hl receiver is getting attached to
|
||||
---@param receiver string the hl that will be auto updated upon change to provider
|
||||
---@param provider_el_type string (fg/bg) what element receiver relates to of provider
|
||||
---@param receiver_el_type string (fg/bg) what element provider relates to of receiver
|
||||
local function attach_hl(provider, receiver, provider_el_type, receiver_el_type)
|
||||
if loaded_highlights[provider] == nil then
|
||||
loaded_highlights[provider] = { empty = true, attached = {} }
|
||||
end
|
||||
loaded_highlights[provider].attached[receiver] = { [provider_el_type] = receiver_el_type }
|
||||
end
|
||||
---define hl_groups for a theme
|
||||
---@param theme table
|
||||
function M.create_highlight_groups(theme)
|
||||
clear_highlights()
|
||||
active_theme = theme
|
||||
theme_hls = {}
|
||||
local psudo_options = { self = { section = 'a' } }
|
||||
create_cterm_colors = not vim.go.termguicolors
|
||||
for mode, sections in pairs(theme) do
|
||||
theme_hls[mode] = {}
|
||||
for section, color in pairs(sections) do
|
||||
local hl_tag = mode
|
||||
psudo_options.self.section = section
|
||||
theme_hls[mode][section] = M.create_component_highlight_group(color, hl_tag, psudo_options, true)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
---@description: adds '_mode' at end of highlight_group
|
||||
---@param highlight_group string name of highlight group
|
||||
---@return string highlight group name with mode
|
||||
local function append_mode(highlight_group, is_focused)
|
||||
if is_focused == nil then
|
||||
is_focused = modules.utils.is_focused()
|
||||
end
|
||||
if is_focused == false then
|
||||
return highlight_group .. '_inactive'
|
||||
end
|
||||
return highlight_group .. M.get_mode_suffix()
|
||||
end
|
||||
|
||||
-- Helper function for create component highlight
|
||||
---Handles fall back of colors when creating highlight group
|
||||
---@param hl_name string name of highlight that we are setting default values for
|
||||
---@param mode string mode which default component color should be given.
|
||||
---@param section string the lualine section component is in.
|
||||
---@param color table color passed for creating component highlight
|
||||
---@param options table Options table of component this is first fall back
|
||||
local function get_default_component_color(hl_name, mode, section, color, options)
|
||||
local default_theme_color
|
||||
if active_theme[mode] and active_theme[mode][section] then
|
||||
default_theme_color = active_theme[mode][section]
|
||||
elseif section >= 'c' and active_theme[mode] and active_theme[mode][section_highlight_map[section]] then
|
||||
default_theme_color = active_theme[mode][section_highlight_map[section]]
|
||||
elseif section >= 'c' and active_theme.normal[section_highlight_map[section]] then
|
||||
default_theme_color = active_theme.normal[section_highlight_map[section]]
|
||||
else
|
||||
default_theme_color = active_theme.normal[section]
|
||||
end
|
||||
|
||||
local ret = { fg = color.fg, bg = color.bg, gui = color.gui }
|
||||
if ret.fg and ret.bg then
|
||||
return ret
|
||||
end
|
||||
|
||||
local function apply_default(def_color, def_name)
|
||||
if type(def_color) == 'function' and loaded_highlights[def_name] and not loaded_highlights[def_name].empty then
|
||||
if loaded_highlights[def_name].link then
|
||||
def_color = loaded_highlights[def_name].link
|
||||
else
|
||||
def_color = loaded_highlights[def_name]
|
||||
end
|
||||
end
|
||||
if type(def_color) == 'function' then
|
||||
def_color = def_color { section = section }
|
||||
end
|
||||
if type(def_color) == 'string' then
|
||||
def_color = modules.utils.extract_highlight_colors(def_color)
|
||||
end
|
||||
if type(def_color) == 'table' then
|
||||
if not ret.fg then
|
||||
ret.fg = def_color.fg
|
||||
attach_hl(def_name, hl_name, 'fg', 'fg')
|
||||
end
|
||||
if not ret.bg then
|
||||
ret.bg = def_color.bg
|
||||
attach_hl(def_name, hl_name, 'bg', 'bg')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if
|
||||
options.color
|
||||
and options.color_highlight
|
||||
and options.color_highlight.name
|
||||
and options.color_highlight.name .. '_' .. mode ~= hl_name
|
||||
then
|
||||
apply_default(options.color, options.color_highlight.name .. '_' .. mode)
|
||||
end
|
||||
|
||||
if not ret.fg or not ret.bg then
|
||||
apply_default(default_theme_color, string.format('lualine_%s_%s', section, mode))
|
||||
end
|
||||
ret.fg = sanitize_color(ret.fg)
|
||||
ret.bg = sanitize_color(ret.bg)
|
||||
return ret
|
||||
end
|
||||
|
||||
---Create highlight group with fg bg and gui from theme
|
||||
---@param color table has to be { fg = "#rrggbb", bg="#rrggbb" gui = "effect" }
|
||||
--- all the color elements are optional if fg or bg is not given options
|
||||
--- must be provided So fg and bg can default the themes colors
|
||||
---@param highlight_tag string is unique tag for highlight group
|
||||
---returns the name of highlight group
|
||||
---@param options table is parameter of component.init() function
|
||||
---@return table that can be used by component_format_highlight
|
||||
--- to retrieve highlight group
|
||||
function M.create_component_highlight_group(color, highlight_tag, options, apply_no_default)
|
||||
local section = options.self.section
|
||||
local tag_id = 0
|
||||
while
|
||||
M.highlight_exists(table.concat({ 'lualine', section, highlight_tag }, '_'))
|
||||
or (section and M.highlight_exists(table.concat({ 'lualine', section, highlight_tag, 'normal' }, '_')))
|
||||
do
|
||||
highlight_tag = highlight_tag .. '_' .. tostring(tag_id)
|
||||
tag_id = tag_id + 1
|
||||
end
|
||||
|
||||
if type(color) == 'string' then
|
||||
local highlight_group_name = table.concat({ 'lualine', section, highlight_tag }, '_')
|
||||
M.highlight(highlight_group_name, nil, nil, nil, color) -- l8nk to group
|
||||
return {
|
||||
name = highlight_group_name,
|
||||
fn = nil,
|
||||
no_mode = true,
|
||||
link = true,
|
||||
section = section,
|
||||
options = options,
|
||||
no_default = apply_no_default,
|
||||
}
|
||||
end
|
||||
|
||||
if type(color) ~= 'function' and (apply_no_default or (color.bg and color.fg)) then
|
||||
-- When bg and fg are both present we don't need to set highlights for
|
||||
-- each mode as they will surely look the same. So we can work without options
|
||||
local highlight_group_name = table.concat({ 'lualine', section, highlight_tag }, '_')
|
||||
M.highlight(highlight_group_name, color.fg, color.bg, color.gui, nil)
|
||||
return {
|
||||
name = highlight_group_name,
|
||||
fn = nil,
|
||||
no_mode = true,
|
||||
section = section,
|
||||
options = options,
|
||||
no_default = apply_no_default,
|
||||
}
|
||||
end
|
||||
|
||||
local modes = {
|
||||
'normal',
|
||||
'insert',
|
||||
'visual',
|
||||
'replace',
|
||||
'command',
|
||||
'terminal',
|
||||
'inactive',
|
||||
}
|
||||
for _, mode in ipairs(modes) do
|
||||
local hl_name = table.concat({ 'lualine', section, highlight_tag, mode }, '_')
|
||||
local cl = color
|
||||
if type(color) == 'function' then
|
||||
cl = color { section = section } or {}
|
||||
end
|
||||
if type(cl) == 'string' then
|
||||
cl = { link = cl }
|
||||
else
|
||||
cl = get_default_component_color(hl_name, mode, section, cl, options)
|
||||
end
|
||||
M.highlight(hl_name, cl.fg, cl.bg, cl.gui, cl.link)
|
||||
end
|
||||
return {
|
||||
name = table.concat({ 'lualine', section, highlight_tag }, '_'),
|
||||
fn = type(color) == 'function' and color,
|
||||
no_mode = false,
|
||||
link = false,
|
||||
section = section,
|
||||
options = options,
|
||||
no_default = apply_no_default,
|
||||
}
|
||||
end
|
||||
|
||||
---@description: retrieve highlight_groups for components
|
||||
---@param highlight table return value of create_component_highlight_group
|
||||
--- return value of create_component_highlight_group is to be passed in
|
||||
--- this parameter to receive highlight that was created
|
||||
---@return string formatted highlight group name
|
||||
function M.component_format_highlight(highlight, is_focused)
|
||||
if not highlight.fn then
|
||||
local highlight_group = highlight.name
|
||||
if highlight.no_mode then
|
||||
return '%#' .. highlight_group .. '#'
|
||||
end
|
||||
highlight_group = append_mode(highlight_group, is_focused)
|
||||
return '%#' .. highlight_group .. '#'
|
||||
else
|
||||
local color = highlight.fn { section = highlight.section } or {}
|
||||
local hl_name = highlight.name
|
||||
if type(color) == 'string' then
|
||||
M.highlight(hl_name .. M.get_mode_suffix(), nil, nil, nil, color)
|
||||
return '%#' .. hl_name .. M.get_mode_suffix() .. '#'
|
||||
elseif type(color) == 'table' then
|
||||
if not highlight.no_default and not (color.fg and color.bg) then
|
||||
hl_name = append_mode(highlight.name, is_focused)
|
||||
color =
|
||||
get_default_component_color(hl_name, M.get_mode_suffix():sub(2), highlight.section, color, highlight.options)
|
||||
end
|
||||
M.highlight(hl_name, color.fg, color.bg, color.gui, color.link)
|
||||
return '%#' .. hl_name .. '#', color
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
---@description: retrieve highlight_groups for section
|
||||
---@param section string highlight group name without mode
|
||||
--- return value of create_component_highlight_group is to be passed in
|
||||
--- this parameter to receive highlight that was created
|
||||
---@param is_focused boolean
|
||||
---@return string formatted highlight group name
|
||||
function M.format_highlight(section, is_focused)
|
||||
local mode = append_mode('', is_focused):sub(2)
|
||||
local ret = ''
|
||||
|
||||
if theme_hls[mode] and theme_hls[mode][section] then
|
||||
ret = M.component_format_highlight(theme_hls[mode][section], is_focused)
|
||||
elseif theme_hls[mode] and section > 'c' and theme_hls[mode][section_highlight_map[section]] then
|
||||
ret = M.component_format_highlight(theme_hls[mode][section_highlight_map[section]], is_focused)
|
||||
elseif theme_hls['normal'] and theme_hls['normal'][section] then
|
||||
ret = M.component_format_highlight(theme_hls['normal'][section], is_focused)
|
||||
elseif theme_hls['normal'] and section > 'c' and theme_hls['normal'][section_highlight_map[section]] then
|
||||
ret = M.component_format_highlight(theme_hls['normal'][section_highlight_map[section]], is_focused)
|
||||
end
|
||||
|
||||
return ret
|
||||
end
|
||||
|
||||
---@description : Provides transitional highlights for section separators.
|
||||
---@param left_hl string this highlights bg is used for fg of transitional hl
|
||||
---@param right_hl string this highlights bg is used for bg of transitional hl
|
||||
--- '▶️' and '◀️' ' needs reverse colors so the caller should swap left and right
|
||||
---@return string formatted highlight group name
|
||||
function M.get_transitional_highlights(left_hl, right_hl)
|
||||
-- When both left and right highlights are same or one is absent
|
||||
-- nothing to transition to.
|
||||
if left_hl == nil or right_hl == nil or left_hl == right_hl then
|
||||
return nil
|
||||
end
|
||||
|
||||
-- construct the name of highlight group
|
||||
local highlight_name = table.concat({ 'lualine_transitional', left_hl, 'to', right_hl }, '_')
|
||||
if not M.highlight_exists(highlight_name) then
|
||||
-- Create the highlight_group if needed
|
||||
-- Get colors from highlights
|
||||
local fg = modules.utils.extract_highlight_colors(left_hl, 'bg')
|
||||
local bg = modules.utils.extract_highlight_colors(right_hl, 'bg')
|
||||
if not fg and not bg then
|
||||
return nil -- Color retrieval failed
|
||||
end
|
||||
if bg == fg then
|
||||
return nil -- Separator won't be visible anyway
|
||||
end
|
||||
M.highlight(highlight_name, fg, bg, nil, nil)
|
||||
attach_hl(left_hl, highlight_name, 'bg', 'fg')
|
||||
attach_hl(right_hl, highlight_name, 'bg', 'bg')
|
||||
end
|
||||
return '%#' .. highlight_name .. '#'
|
||||
end
|
||||
|
||||
function M.get_stl_default_hl(focused)
|
||||
if focused == 3 then
|
||||
return 'TabLineFill'
|
||||
elseif not focused then
|
||||
return 'StatusLineNC'
|
||||
else
|
||||
return 'StatusLine'
|
||||
end
|
||||
end
|
||||
|
||||
return M
|
||||
@ -0,0 +1,38 @@
|
||||
-- Copyright (c) 2020-2021 shadmansaleh
|
||||
-- MIT license, see LICENSE for more details.
|
||||
-- Credit itchyny, jackno (lightline)
|
||||
-- stylua: ignore
|
||||
local colors = {
|
||||
black = '#000000',
|
||||
maroon = '#800000',
|
||||
green = '#008000',
|
||||
olive = '#808000',
|
||||
navy = '#000080',
|
||||
purple = '#800080',
|
||||
teal = '#008080',
|
||||
silver = '#c0c0c0',
|
||||
gray = '#808080',
|
||||
red = '#ff0000',
|
||||
lime = '#00ff00',
|
||||
yellow = '#ffff00',
|
||||
blue = '#0000ff',
|
||||
fuchsia = '#ff00ff',
|
||||
aqua = '#00ffff',
|
||||
white = '#ffffff',
|
||||
}
|
||||
|
||||
return {
|
||||
normal = {
|
||||
a = { fg = colors.white, bg = colors.blue, gui = 'bold' },
|
||||
b = { fg = colors.white, bg = colors.gray },
|
||||
c = { fg = colors.silver, bg = colors.black },
|
||||
},
|
||||
insert = { a = { fg = colors.white, bg = colors.green, gui = 'bold' } },
|
||||
visual = { a = { fg = colors.white, bg = colors.purple, gui = 'bold' } },
|
||||
replace = { a = { fg = colors.white, bg = colors.red, gui = 'bold' } },
|
||||
inactive = {
|
||||
a = { fg = colors.silver, bg = colors.gray, gui = 'bold' },
|
||||
b = { fg = colors.gray, bg = colors.black },
|
||||
c = { fg = colors.silver, bg = colors.black },
|
||||
},
|
||||
}
|
||||
@ -0,0 +1,43 @@
|
||||
-- Copyright (c) 2020-2021 shadmansaleh
|
||||
-- MIT license, see LICENSE for more details.
|
||||
-- Generated by lightline to lualine theme converter
|
||||
-- https://gist.github.com/shadmansaleh/000871c9a608a012721c6acc6d7a19b9
|
||||
-- stylua: ignore
|
||||
local colors = {
|
||||
color0 = '#ffffff',
|
||||
color1 = '#99c794',
|
||||
color2 = '#65737e',
|
||||
color3 = '#343d46',
|
||||
color4 = '#6699cc',
|
||||
color5 = '#d8dee9',
|
||||
color6 = '#f99157',
|
||||
color7 = '#ec5f67',
|
||||
}
|
||||
|
||||
return {
|
||||
insert = {
|
||||
a = { fg = colors.color0, bg = colors.color1, gui = 'bold' },
|
||||
b = { fg = colors.color0, bg = colors.color2 },
|
||||
c = { fg = colors.color0, bg = colors.color3 },
|
||||
},
|
||||
normal = {
|
||||
a = { fg = colors.color0, bg = colors.color4, gui = 'bold' },
|
||||
b = { fg = colors.color0, bg = colors.color2 },
|
||||
c = { fg = colors.color0, bg = colors.color3 },
|
||||
},
|
||||
inactive = {
|
||||
a = { fg = colors.color5, bg = colors.color2, gui = 'bold' },
|
||||
b = { fg = colors.color5, bg = colors.color3 },
|
||||
c = { fg = colors.color2, bg = colors.color3 },
|
||||
},
|
||||
visual = {
|
||||
a = { fg = colors.color0, bg = colors.color6, gui = 'bold' },
|
||||
b = { fg = colors.color0, bg = colors.color2 },
|
||||
c = { fg = colors.color0, bg = colors.color3 },
|
||||
},
|
||||
replace = {
|
||||
a = { fg = colors.color0, bg = colors.color7, gui = 'bold' },
|
||||
b = { fg = colors.color0, bg = colors.color2 },
|
||||
c = { fg = colors.color0, bg = colors.color3 },
|
||||
},
|
||||
}
|
||||
@ -0,0 +1,6 @@
|
||||
-- Copyright (c) 2020-2021 shadmansaleh
|
||||
-- MIT license, see LICENSE for more details.
|
||||
-- Credit: itchyny(lightline)
|
||||
local background = vim.opt.background:get()
|
||||
|
||||
return require('lualine.themes.papercolor_' .. background)
|
||||
@ -0,0 +1,43 @@
|
||||
-- Copyright (c) 2020-2021 shadmansaleh
|
||||
-- MIT license, see LICENSE for more details.
|
||||
-- Generated by lightline to lualine theme converter
|
||||
-- https://gist.github.com/shadmansaleh/000871c9a608a012721c6acc6d7a19b9
|
||||
-- stylua: ignore
|
||||
local colors = {
|
||||
color14 = '#718c00',
|
||||
color0 = '#666666',
|
||||
color1 = '#c8c8c8',
|
||||
color2 = '#808080',
|
||||
color3 = '#fafafa',
|
||||
color4 = '#4271ae',
|
||||
color5 = '#4d4d4c',
|
||||
color6 = '#b4b4b4',
|
||||
color7 = '#555555',
|
||||
color8 = '#8959a8',
|
||||
color11 = '#f5871f',
|
||||
}
|
||||
|
||||
return {
|
||||
inactive = {
|
||||
a = { fg = colors.color0, bg = colors.color1, gui = 'bold' },
|
||||
b = { fg = colors.color2, bg = colors.color3 },
|
||||
c = { fg = colors.color0, bg = colors.color1 },
|
||||
},
|
||||
normal = {
|
||||
a = { fg = colors.color1, bg = colors.color4, gui = 'bold' },
|
||||
b = { fg = colors.color5, bg = colors.color6 },
|
||||
c = { fg = colors.color7, bg = colors.color1 },
|
||||
},
|
||||
visual = {
|
||||
a = { fg = colors.color1, bg = colors.color8, gui = 'bold' },
|
||||
b = { fg = colors.color5, bg = colors.color6 },
|
||||
},
|
||||
replace = {
|
||||
a = { fg = colors.color1, bg = colors.color11, gui = 'bold' },
|
||||
b = { fg = colors.color5, bg = colors.color6 },
|
||||
},
|
||||
insert = {
|
||||
a = { fg = colors.color1, bg = colors.color14, gui = 'bold' },
|
||||
b = { fg = colors.color5, bg = colors.color6 },
|
||||
},
|
||||
}
|
||||
@ -0,0 +1,172 @@
|
||||
-- Copyright (c) 2020-2021 shadmansaleh
|
||||
-- MIT license, see LICENSE for more details.
|
||||
local utils = require('lualine.utils.utils')
|
||||
local loader = require('lualine.utils.loader')
|
||||
|
||||
local color_name = vim.g.colors_name
|
||||
if color_name then
|
||||
-- All base16 colorschemes share the same theme
|
||||
if 'base16' == color_name:sub(1, 6) then
|
||||
color_name = 'base16'
|
||||
end
|
||||
|
||||
-- Check if there's a theme for current colorscheme
|
||||
-- If there is load that instead of generating a new one
|
||||
local ok, theme = pcall(loader.load_theme, color_name)
|
||||
if ok and theme then
|
||||
return theme
|
||||
end
|
||||
end
|
||||
|
||||
---------------
|
||||
-- Constants --
|
||||
---------------
|
||||
-- fg and bg must have this much contrast range 0 < contrast_threshold < 0.5
|
||||
local contrast_threshold = 0.3
|
||||
-- how much brightness is changed in percentage for light and dark themes
|
||||
local brightness_modifier_parameter = 10
|
||||
|
||||
-- Turns #rrggbb -> { red, green, blue }
|
||||
local function rgb_str2num(rgb_color_str)
|
||||
if rgb_color_str:find('#') == 1 then
|
||||
rgb_color_str = rgb_color_str:sub(2, #rgb_color_str)
|
||||
end
|
||||
local red = tonumber(rgb_color_str:sub(1, 2), 16)
|
||||
local green = tonumber(rgb_color_str:sub(3, 4), 16)
|
||||
local blue = tonumber(rgb_color_str:sub(5, 6), 16)
|
||||
return { red = red, green = green, blue = blue }
|
||||
end
|
||||
|
||||
-- Turns { red, green, blue } -> #rrggbb
|
||||
local function rgb_num2str(rgb_color_num)
|
||||
local rgb_color_str = string.format('#%02x%02x%02x', rgb_color_num.red, rgb_color_num.green, rgb_color_num.blue)
|
||||
return rgb_color_str
|
||||
end
|
||||
|
||||
-- Returns brightness level of color in range 0 to 1
|
||||
-- arbitrary value it's basically an weighted average
|
||||
local function get_color_brightness(rgb_color)
|
||||
local color = rgb_str2num(rgb_color)
|
||||
local brightness = (color.red * 2 + color.green * 3 + color.blue) / 6
|
||||
return brightness / 256
|
||||
end
|
||||
|
||||
-- returns average of colors in range 0 to 1
|
||||
-- used to determine contrast level
|
||||
local function get_color_avg(rgb_color)
|
||||
local color = rgb_str2num(rgb_color)
|
||||
return (color.red + color.green + color.blue) / 3 / 256
|
||||
end
|
||||
|
||||
-- Clamps the val between left and right
|
||||
local function clamp(val, left, right)
|
||||
if val > right then
|
||||
return right
|
||||
end
|
||||
if val < left then
|
||||
return left
|
||||
end
|
||||
return val
|
||||
end
|
||||
|
||||
-- Changes brightness of rgb_color by percentage
|
||||
local function brightness_modifier(rgb_color, percentage)
|
||||
local color = rgb_str2num(rgb_color)
|
||||
color.red = clamp(color.red + (color.red * percentage / 100), 0, 255)
|
||||
color.green = clamp(color.green + (color.green * percentage / 100), 0, 255)
|
||||
color.blue = clamp(color.blue + (color.blue * percentage / 100), 0, 255)
|
||||
return rgb_num2str(color)
|
||||
end
|
||||
|
||||
-- Changes contrast of rgb_color by amount
|
||||
local function contrast_modifier(rgb_color, amount)
|
||||
local color = rgb_str2num(rgb_color)
|
||||
color.red = clamp(color.red + amount, 0, 255)
|
||||
color.green = clamp(color.green + amount, 0, 255)
|
||||
color.blue = clamp(color.blue + amount, 0, 255)
|
||||
return rgb_num2str(color)
|
||||
end
|
||||
|
||||
-- Changes brightness of foreground color to achieve contrast
|
||||
-- without changing the color
|
||||
local function apply_contrast(highlight)
|
||||
local highlight_bg_avg = get_color_avg(highlight.bg)
|
||||
local contrast_threshold_config = clamp(contrast_threshold, 0, 0.5)
|
||||
local contrast_change_step = 5
|
||||
if highlight_bg_avg > 0.5 then
|
||||
contrast_change_step = -contrast_change_step
|
||||
end
|
||||
|
||||
-- Don't waste too much time here max 25 iteration should be more than enough
|
||||
local iteration_count = 1
|
||||
while math.abs(get_color_avg(highlight.fg) - highlight_bg_avg) < contrast_threshold_config and iteration_count < 25 do
|
||||
highlight.fg = contrast_modifier(highlight.fg, contrast_change_step)
|
||||
iteration_count = iteration_count + 1
|
||||
end
|
||||
end
|
||||
|
||||
-- Get the colors to create theme
|
||||
-- stylua: ignore
|
||||
local colors = {
|
||||
normal = utils.extract_color_from_hllist('bg', { 'PmenuSel', 'PmenuThumb', 'TabLineSel' }, '#000000'),
|
||||
insert = utils.extract_color_from_hllist('fg', { 'String', 'MoreMsg' }, '#000000'),
|
||||
replace = utils.extract_color_from_hllist('fg', { 'Number', 'Type' }, '#000000'),
|
||||
visual = utils.extract_color_from_hllist('fg', { 'Special', 'Boolean', 'Constant' }, '#000000'),
|
||||
command = utils.extract_color_from_hllist('fg', { 'Identifier' }, '#000000'),
|
||||
back1 = utils.extract_color_from_hllist('bg', { 'Normal', 'StatusLineNC' }, '#000000'),
|
||||
fore = utils.extract_color_from_hllist('fg', { 'Normal', 'StatusLine' }, '#000000'),
|
||||
back2 = utils.extract_color_from_hllist('bg', { 'StatusLine' }, '#000000'),
|
||||
}
|
||||
|
||||
-- Change brightness of colors
|
||||
-- Darken if light theme (or) Lighten if dark theme
|
||||
local normal_color = utils.extract_highlight_colors('Normal', 'bg')
|
||||
if normal_color ~= nil then
|
||||
if get_color_brightness(normal_color) > 0.5 then
|
||||
brightness_modifier_parameter = -brightness_modifier_parameter
|
||||
end
|
||||
for name, color in pairs(colors) do
|
||||
colors[name] = brightness_modifier(color, brightness_modifier_parameter)
|
||||
end
|
||||
end
|
||||
|
||||
-- Basic theme definition
|
||||
local M = {
|
||||
normal = {
|
||||
a = { bg = colors.normal, fg = colors.back1, gui = 'bold' },
|
||||
b = { bg = colors.back1, fg = colors.normal },
|
||||
c = { bg = colors.back2, fg = colors.fore },
|
||||
},
|
||||
insert = {
|
||||
a = { bg = colors.insert, fg = colors.back1, gui = 'bold' },
|
||||
b = { bg = colors.back1, fg = colors.insert },
|
||||
c = { bg = colors.back2, fg = colors.fore },
|
||||
},
|
||||
replace = {
|
||||
a = { bg = colors.replace, fg = colors.back1, gui = 'bold' },
|
||||
b = { bg = colors.back1, fg = colors.replace },
|
||||
c = { bg = colors.back2, fg = colors.fore },
|
||||
},
|
||||
visual = {
|
||||
a = { bg = colors.visual, fg = colors.back1, gui = 'bold' },
|
||||
b = { bg = colors.back1, fg = colors.visual },
|
||||
c = { bg = colors.back2, fg = colors.fore },
|
||||
},
|
||||
command = {
|
||||
a = { bg = colors.command, fg = colors.back1, gui = 'bold' },
|
||||
b = { bg = colors.back1, fg = colors.command },
|
||||
c = { bg = colors.back2, fg = colors.fore },
|
||||
},
|
||||
}
|
||||
|
||||
M.terminal = M.command
|
||||
M.inactive = M.normal
|
||||
|
||||
-- Apply proper contrast so text is readable
|
||||
for _, section in pairs(M) do
|
||||
for _, highlight in pairs(section) do
|
||||
apply_contrast(highlight)
|
||||
end
|
||||
end
|
||||
|
||||
return M
|
||||
@ -0,0 +1,8 @@
|
||||
-- Copyright (c) 2020-2021 shadmansaleh
|
||||
-- MIT license, see LICENSE for more details.
|
||||
-- Credit: itchyny(lightline)
|
||||
-- License: MIT License
|
||||
local background = vim.opt.background:get()
|
||||
local style = vim.g.ayucolor or ((background == 'dark') and vim.g.ayuprefermirage and 'mirage' or background)
|
||||
|
||||
return require('lualine.themes.ayu_' .. style)
|
||||
@ -0,0 +1,40 @@
|
||||
-- Copyright (c) 2020-2021 shadmansaleh
|
||||
-- MIT license, see LICENSE for more details.
|
||||
-- Generated by lightline to lualine theme converter
|
||||
-- https://gist.github.com/shadmansaleh/000871c9a608a012721c6acc6d7a19b9
|
||||
-- stylua: ignore
|
||||
local colors = {
|
||||
color2 = '#0f1419',
|
||||
color3 = '#ffee99',
|
||||
color4 = '#e6e1cf',
|
||||
color5 = '#14191f',
|
||||
color13 = '#b8cc52',
|
||||
color10 = '#36a3d9',
|
||||
color8 = '#f07178',
|
||||
color9 = '#3e4b59',
|
||||
}
|
||||
|
||||
return {
|
||||
visual = {
|
||||
a = { fg = colors.color2, bg = colors.color3, gui = 'bold' },
|
||||
b = { fg = colors.color4, bg = colors.color5 },
|
||||
},
|
||||
replace = {
|
||||
a = { fg = colors.color2, bg = colors.color8, gui = 'bold' },
|
||||
b = { fg = colors.color4, bg = colors.color5 },
|
||||
},
|
||||
inactive = {
|
||||
c = { fg = colors.color4, bg = colors.color2 },
|
||||
a = { fg = colors.color4, bg = colors.color5, gui = 'bold' },
|
||||
b = { fg = colors.color4, bg = colors.color5 },
|
||||
},
|
||||
normal = {
|
||||
c = { fg = colors.color9, bg = colors.color2 },
|
||||
a = { fg = colors.color2, bg = colors.color10, gui = 'bold' },
|
||||
b = { fg = colors.color4, bg = colors.color5 },
|
||||
},
|
||||
insert = {
|
||||
a = { fg = colors.color2, bg = colors.color13, gui = 'bold' },
|
||||
b = { fg = colors.color4, bg = colors.color5 },
|
||||
},
|
||||
}
|
||||
@ -0,0 +1,40 @@
|
||||
-- Copyright (c) 2020-2021 shadmansaleh
|
||||
-- MIT license, see LICENSE for more details.
|
||||
-- Generated by lightline to lualine theme converter
|
||||
-- https://gist.github.com/shadmansaleh/000871c9a608a012721c6acc6d7a19b9
|
||||
-- stylua: ignore
|
||||
local colors = {
|
||||
color2 = '#f3f3f3',
|
||||
color3 = '#A37ACC',
|
||||
color4 = '#5C6773',
|
||||
color5 = '#d3d3d3',
|
||||
color13 = '#86B300',
|
||||
color10 = '#59c2ff',
|
||||
color8 = '#f07178',
|
||||
color9 = '#828C99',
|
||||
}
|
||||
|
||||
return {
|
||||
visual = {
|
||||
a = { fg = colors.color2, bg = colors.color3, gui = 'bold' },
|
||||
b = { fg = colors.color4, bg = colors.color5 },
|
||||
},
|
||||
replace = {
|
||||
a = { fg = colors.color2, bg = colors.color8, gui = 'bold' },
|
||||
b = { fg = colors.color4, bg = colors.color5 },
|
||||
},
|
||||
inactive = {
|
||||
c = { fg = colors.color4, bg = colors.color2 },
|
||||
a = { fg = colors.color4, bg = colors.color5, gui = 'bold' },
|
||||
b = { fg = colors.color4, bg = colors.color5 },
|
||||
},
|
||||
normal = {
|
||||
c = { fg = colors.color9, bg = colors.color2 },
|
||||
a = { fg = colors.color2, bg = colors.color10, gui = 'bold' },
|
||||
b = { fg = colors.color4, bg = colors.color5 },
|
||||
},
|
||||
insert = {
|
||||
a = { fg = colors.color2, bg = colors.color13, gui = 'bold' },
|
||||
b = { fg = colors.color4, bg = colors.color5 },
|
||||
},
|
||||
}
|
||||
@ -0,0 +1,40 @@
|
||||
-- Copyright (c) 2020-2021 shadmansaleh
|
||||
-- MIT license, see LICENSE for more details.
|
||||
-- Generated by lightline to lualine theme converter
|
||||
-- https://gist.github.com/shadmansaleh/000871c9a608a012721c6acc6d7a19b9
|
||||
-- stylua: ignore
|
||||
local colors = {
|
||||
color2 = '#242b38',
|
||||
color3 = '#d4bfff',
|
||||
color4 = '#d9d7ce',
|
||||
color5 = '#272d38',
|
||||
color13 = '#bbe67e',
|
||||
color10 = '#59c2ff',
|
||||
color8 = '#f07178',
|
||||
color9 = '#607080',
|
||||
}
|
||||
|
||||
return {
|
||||
visual = {
|
||||
a = { fg = colors.color2, bg = colors.color3, gui = 'bold' },
|
||||
b = { fg = colors.color4, bg = colors.color5 },
|
||||
},
|
||||
replace = {
|
||||
a = { fg = colors.color2, bg = colors.color8, gui = 'bold' },
|
||||
b = { fg = colors.color4, bg = colors.color5 },
|
||||
},
|
||||
inactive = {
|
||||
c = { fg = colors.color4, bg = colors.color2 },
|
||||
a = { fg = colors.color4, bg = colors.color5, gui = 'bold' },
|
||||
b = { fg = colors.color4, bg = colors.color5 },
|
||||
},
|
||||
normal = {
|
||||
c = { fg = colors.color9, bg = colors.color2 },
|
||||
a = { fg = colors.color2, bg = colors.color10, gui = 'bold' },
|
||||
b = { fg = colors.color4, bg = colors.color5 },
|
||||
},
|
||||
insert = {
|
||||
a = { fg = colors.color2, bg = colors.color13, gui = 'bold' },
|
||||
b = { fg = colors.color4, bg = colors.color5 },
|
||||
},
|
||||
}
|
||||
@ -0,0 +1,112 @@
|
||||
local modules = require('lualine_require').lazy_require { notices = 'lualine.utils.notices' }
|
||||
|
||||
local function add_notice(notice)
|
||||
modules.notices.add_notice('theme(base16): ' .. notice)
|
||||
end
|
||||
|
||||
local function setup(colors)
|
||||
local theme = {
|
||||
normal = {
|
||||
a = { fg = colors.bg, bg = colors.normal },
|
||||
b = { fg = colors.light_fg, bg = colors.alt_bg },
|
||||
c = { fg = colors.fg, bg = colors.bg },
|
||||
},
|
||||
replace = {
|
||||
a = { fg = colors.bg, bg = colors.replace },
|
||||
b = { fg = colors.light_fg, bg = colors.alt_bg },
|
||||
},
|
||||
insert = {
|
||||
a = { fg = colors.bg, bg = colors.insert },
|
||||
b = { fg = colors.light_fg, bg = colors.alt_bg },
|
||||
},
|
||||
visual = {
|
||||
a = { fg = colors.bg, bg = colors.visual },
|
||||
b = { fg = colors.light_fg, bg = colors.alt_bg },
|
||||
},
|
||||
inactive = {
|
||||
a = { fg = colors.dark_fg, bg = colors.bg },
|
||||
b = { fg = colors.dark_fg, bg = colors.bg },
|
||||
c = { fg = colors.dark_fg, bg = colors.bg },
|
||||
},
|
||||
}
|
||||
|
||||
theme.command = theme.normal
|
||||
theme.terminal = theme.insert
|
||||
|
||||
return theme
|
||||
end
|
||||
|
||||
local function setup_default()
|
||||
return setup {
|
||||
bg = '#282a2e',
|
||||
alt_bg = '#373b41',
|
||||
dark_fg = '#969896',
|
||||
fg = '#b4b7b4',
|
||||
light_fg = '#c5c8c6',
|
||||
normal = '#81a2be',
|
||||
insert = '#b5bd68',
|
||||
visual = '#b294bb',
|
||||
replace = '#de935f',
|
||||
}
|
||||
end
|
||||
|
||||
local function setup_base16_nvim()
|
||||
-- Continue to load nvim-base16
|
||||
local loaded, base16 = pcall(require, 'base16-colorscheme')
|
||||
|
||||
if not loaded then
|
||||
add_notice(
|
||||
'nvim-base16 is not currently present in your runtimepath, make sure it is properly installed,'
|
||||
.. ' fallback to default colors.'
|
||||
)
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
if not base16.colors and not vim.env.BASE16_THEME then
|
||||
add_notice(
|
||||
'nvim-base16 is not loaded yet, you should update your configuration to load it before lualine'
|
||||
.. ' so that the colors from your colorscheme can be used, fallback to "tomorrow-night" theme.'
|
||||
)
|
||||
elseif not base16.colors and not base16.colorschemes[vim.env.BASE16_THEME] then
|
||||
add_notice(
|
||||
'The colorscheme "%s" defined by the environment variable "BASE16_THEME" is not handled by'
|
||||
.. ' nvim-base16, fallback to "tomorrow-night" theme.'
|
||||
)
|
||||
end
|
||||
|
||||
local colors = base16.colors or base16.colorschemes[vim.env.BASE16_THEME or 'tomorrow-night']
|
||||
|
||||
return setup {
|
||||
bg = colors.base01,
|
||||
alt_bg = colors.base02,
|
||||
dark_fg = colors.base03,
|
||||
fg = colors.base04,
|
||||
light_fg = colors.base05,
|
||||
normal = colors.base0D,
|
||||
insert = colors.base0B,
|
||||
visual = colors.base0E,
|
||||
replace = colors.base09,
|
||||
}
|
||||
end
|
||||
|
||||
local function setup_base16_vim()
|
||||
-- Check if tinted-theming/base16-vim is already loaded
|
||||
if vim.g.base16_gui00 and vim.g.base16_gui0F then
|
||||
return setup {
|
||||
bg = vim.g.base16_gui01,
|
||||
alt_bg = vim.g.base16_gui02,
|
||||
dark_fg = vim.g.base16_gui03,
|
||||
fg = vim.g.base16_gui04,
|
||||
light_fg = vim.g.base16_gui05,
|
||||
normal = vim.g.base16_gui0D,
|
||||
insert = vim.g.base16_gui0B,
|
||||
visual = vim.g.base16_gui0E,
|
||||
replace = vim.g.base16_gui09,
|
||||
}
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
return setup_base16_vim() or setup_base16_nvim() or setup_default()
|
||||
@ -0,0 +1,38 @@
|
||||
-- Copyright (c) 2020-2021 Shatur95
|
||||
-- MIT license, see LICENSE for more details.
|
||||
-- stylua: ignore
|
||||
local colors = {
|
||||
gray = '#3C3C3C',
|
||||
lightred = '#D16969',
|
||||
blue = '#569CD6',
|
||||
pink = '#C586C0',
|
||||
black = '#262626',
|
||||
white = '#D4D4D4',
|
||||
green = '#608B4E',
|
||||
}
|
||||
|
||||
return {
|
||||
normal = {
|
||||
b = { fg = colors.green, bg = colors.black },
|
||||
a = { fg = colors.black, bg = colors.green, gui = 'bold' },
|
||||
c = { fg = colors.white, bg = colors.black },
|
||||
},
|
||||
visual = {
|
||||
b = { fg = colors.pink, bg = colors.black },
|
||||
a = { fg = colors.black, bg = colors.pink, gui = 'bold' },
|
||||
},
|
||||
inactive = {
|
||||
b = { fg = colors.black, bg = colors.blue },
|
||||
a = { fg = colors.white, bg = colors.gray, gui = 'bold' },
|
||||
},
|
||||
replace = {
|
||||
b = { fg = colors.lightred, bg = colors.black },
|
||||
a = { fg = colors.black, bg = colors.lightred, gui = 'bold' },
|
||||
c = { fg = colors.white, bg = colors.black },
|
||||
},
|
||||
insert = {
|
||||
b = { fg = colors.blue, bg = colors.black },
|
||||
a = { fg = colors.black, bg = colors.blue, gui = 'bold' },
|
||||
c = { fg = colors.white, bg = colors.black },
|
||||
},
|
||||
}
|
||||
@ -0,0 +1,48 @@
|
||||
-- Copyright (c) 2020-2021 shadmansaleh
|
||||
-- MIT license, see LICENSE for more details.
|
||||
-- Credit itchyny, jackno (lightline)
|
||||
-- stylua: ignore
|
||||
local colors = {
|
||||
gray = '#44475a',
|
||||
lightgray = '#5f6a8e',
|
||||
orange = '#ffb86c',
|
||||
purple = '#bd93f9',
|
||||
red = '#ff5555',
|
||||
yellow = '#f1fa8c',
|
||||
green = '#50fa7b',
|
||||
white = '#f8f8f2',
|
||||
black = '#282a36',
|
||||
}
|
||||
|
||||
return {
|
||||
normal = {
|
||||
a = { bg = colors.purple, fg = colors.black, gui = 'bold' },
|
||||
b = { bg = colors.lightgray, fg = colors.white },
|
||||
c = { bg = colors.gray, fg = colors.white },
|
||||
},
|
||||
insert = {
|
||||
a = { bg = colors.green, fg = colors.black, gui = 'bold' },
|
||||
b = { bg = colors.lightgray, fg = colors.white },
|
||||
c = { bg = colors.gray, fg = colors.white },
|
||||
},
|
||||
visual = {
|
||||
a = { bg = colors.yellow, fg = colors.black, gui = 'bold' },
|
||||
b = { bg = colors.lightgray, fg = colors.white },
|
||||
c = { bg = colors.gray, fg = colors.white },
|
||||
},
|
||||
replace = {
|
||||
a = { bg = colors.red, fg = colors.black, gui = 'bold' },
|
||||
b = { bg = colors.lightgray, fg = colors.white },
|
||||
c = { bg = colors.gray, fg = colors.white },
|
||||
},
|
||||
command = {
|
||||
a = { bg = colors.orange, fg = colors.black, gui = 'bold' },
|
||||
b = { bg = colors.lightgray, fg = colors.white },
|
||||
c = { bg = colors.gray, fg = colors.white },
|
||||
},
|
||||
inactive = {
|
||||
a = { bg = colors.gray, fg = colors.white, gui = 'bold' },
|
||||
b = { bg = colors.lightgray, fg = colors.white },
|
||||
c = { bg = colors.gray, fg = colors.white },
|
||||
},
|
||||
}
|
||||
@ -0,0 +1,53 @@
|
||||
-- Copyright (c) 2020-2021 gnuyent
|
||||
-- MIT license, see LICENSE for more details.
|
||||
-- stylua: ignore
|
||||
local colors = {
|
||||
bg0 = '#323d43',
|
||||
bg1 = '#3c474d',
|
||||
bg3 = '#505a60',
|
||||
fg = '#d8caac',
|
||||
aqua = '#87c095',
|
||||
green = '#a7c080',
|
||||
orange = '#e39b7b',
|
||||
purple = '#d39bb6',
|
||||
red = '#e68183',
|
||||
grey1 = '#868d80',
|
||||
}
|
||||
|
||||
return {
|
||||
normal = {
|
||||
a = { bg = colors.green, fg = colors.bg0, gui = 'bold' },
|
||||
b = { bg = colors.bg3, fg = colors.fg },
|
||||
c = { bg = colors.bg1, fg = colors.fg },
|
||||
},
|
||||
insert = {
|
||||
a = { bg = colors.fg, fg = colors.bg0, gui = 'bold' },
|
||||
b = { bg = colors.bg3, fg = colors.fg },
|
||||
c = { bg = colors.bg1, fg = colors.fg },
|
||||
},
|
||||
visual = {
|
||||
a = { bg = colors.red, fg = colors.bg0, gui = 'bold' },
|
||||
b = { bg = colors.bg3, fg = colors.fg },
|
||||
c = { bg = colors.bg1, fg = colors.fg },
|
||||
},
|
||||
replace = {
|
||||
a = { bg = colors.orange, fg = colors.bg0, gui = 'bold' },
|
||||
b = { bg = colors.bg3, fg = colors.fg },
|
||||
c = { bg = colors.bg1, fg = colors.fg },
|
||||
},
|
||||
command = {
|
||||
a = { bg = colors.aqua, fg = colors.bg0, gui = 'bold' },
|
||||
b = { bg = colors.bg3, fg = colors.fg },
|
||||
c = { bg = colors.bg1, fg = colors.fg },
|
||||
},
|
||||
terminal = {
|
||||
a = { bg = colors.purple, fg = colors.bg0, gui = 'bold' },
|
||||
b = { bg = colors.bg3, fg = colors.fg },
|
||||
c = { bg = colors.bg1, fg = colors.fg },
|
||||
},
|
||||
inactive = {
|
||||
a = { bg = colors.bg1, fg = colors.grey1, gui = 'bold' },
|
||||
b = { bg = colors.bg1, fg = colors.grey1 },
|
||||
c = { bg = colors.bg1, fg = colors.grey1 },
|
||||
},
|
||||
}
|
||||
@ -0,0 +1,29 @@
|
||||
-- Copyright (c) 2020-2021 shadmansaleh
|
||||
-- MIT license, see LICENSE for more details.
|
||||
-- stylua: ignore
|
||||
local colors = {
|
||||
fg1 = '#282828',
|
||||
color2 = '#504945',
|
||||
fg2 = '#ddc7a1',
|
||||
color3 = '#32302f',
|
||||
color4 = '#a89984',
|
||||
color5 = '#7daea3',
|
||||
color6 = '#a9b665',
|
||||
color7 = '#d8a657',
|
||||
color8 = '#d3869b',
|
||||
color9 = '#ea6962',
|
||||
}
|
||||
|
||||
return {
|
||||
normal = {
|
||||
a = { fg = colors.fg1, bg = colors.color4, gui = 'bold' },
|
||||
b = { fg = colors.fg2, bg = colors.color2 },
|
||||
c = { fg = colors.fg2, bg = colors.color3 },
|
||||
},
|
||||
command = { a = { fg = colors.fg1, bg = colors.color5, gui = 'bold' } },
|
||||
inactive = { a = { fg = colors.fg2, bg = colors.color2 } },
|
||||
insert = { a = { fg = colors.fg1, bg = colors.color6, gui = 'bold' } },
|
||||
replace = { a = { fg = colors.fg1, bg = colors.color7, gui = 'bold' } },
|
||||
terminal = { a = { fg = colors.fg1, bg = colors.color8, gui = 'bold' } },
|
||||
visual = { a = { fg = colors.fg1, bg = colors.color9, gui = 'bold' } },
|
||||
}
|
||||
@ -0,0 +1,7 @@
|
||||
-- Copyright (c) 2020-2021 shadmansaleh
|
||||
-- MIT license, see LICENSE for more details.
|
||||
-- Credit: itchyny(lightline)
|
||||
-- License: MIT License
|
||||
local background = vim.opt.background:get()
|
||||
|
||||
return require('lualine.themes.gruvbox_' .. background)
|
||||
@ -0,0 +1,48 @@
|
||||
-- Copyright (c) 2020-2021 hoob3rt
|
||||
-- MIT license, see LICENSE for more details.
|
||||
-- stylua: ignore
|
||||
local colors = {
|
||||
black = '#282828',
|
||||
white = '#ebdbb2',
|
||||
red = '#fb4934',
|
||||
green = '#b8bb26',
|
||||
blue = '#83a598',
|
||||
yellow = '#fe8019',
|
||||
gray = '#a89984',
|
||||
darkgray = '#3c3836',
|
||||
lightgray = '#504945',
|
||||
inactivegray = '#7c6f64',
|
||||
}
|
||||
|
||||
return {
|
||||
normal = {
|
||||
a = { bg = colors.gray, fg = colors.black, gui = 'bold' },
|
||||
b = { bg = colors.lightgray, fg = colors.white },
|
||||
c = { bg = colors.darkgray, fg = colors.gray },
|
||||
},
|
||||
insert = {
|
||||
a = { bg = colors.blue, fg = colors.black, gui = 'bold' },
|
||||
b = { bg = colors.lightgray, fg = colors.white },
|
||||
c = { bg = colors.lightgray, fg = colors.white },
|
||||
},
|
||||
visual = {
|
||||
a = { bg = colors.yellow, fg = colors.black, gui = 'bold' },
|
||||
b = { bg = colors.lightgray, fg = colors.white },
|
||||
c = { bg = colors.inactivegray, fg = colors.black },
|
||||
},
|
||||
replace = {
|
||||
a = { bg = colors.red, fg = colors.black, gui = 'bold' },
|
||||
b = { bg = colors.lightgray, fg = colors.white },
|
||||
c = { bg = colors.black, fg = colors.white },
|
||||
},
|
||||
command = {
|
||||
a = { bg = colors.green, fg = colors.black, gui = 'bold' },
|
||||
b = { bg = colors.lightgray, fg = colors.white },
|
||||
c = { bg = colors.inactivegray, fg = colors.black },
|
||||
},
|
||||
inactive = {
|
||||
a = { bg = colors.darkgray, fg = colors.gray, gui = 'bold' },
|
||||
b = { bg = colors.darkgray, fg = colors.gray },
|
||||
c = { bg = colors.darkgray, fg = colors.gray },
|
||||
},
|
||||
}
|
||||
@ -0,0 +1,47 @@
|
||||
-- Copyright (c) 2020-2021 shadmansaleh
|
||||
-- MIT license, see LICENSE for more details.
|
||||
-- stylua: ignore
|
||||
local colors = {
|
||||
black = '#3c3836',
|
||||
white = '#f9f5d7',
|
||||
orange = '#af3a03',
|
||||
green = '#427b58',
|
||||
blue = '#076678',
|
||||
gray = '#d5c4a1',
|
||||
darkgray = '#7c6f64',
|
||||
lightgray = '#ebdbb2',
|
||||
inactivegray = '#a89984'
|
||||
}
|
||||
|
||||
return {
|
||||
normal = {
|
||||
a = { bg = colors.darkgray, fg = colors.white, gui = 'bold' },
|
||||
b = { bg = colors.gray, fg = colors.darkgray },
|
||||
c = { bg = colors.lightgray, fg = colors.darkgray },
|
||||
},
|
||||
insert = {
|
||||
a = { bg = colors.blue, fg = colors.white, gui = 'bold' },
|
||||
b = { bg = colors.gray, fg = colors.darkgray },
|
||||
c = { bg = colors.gray, fg = colors.black },
|
||||
},
|
||||
visual = {
|
||||
a = { bg = colors.orange, fg = colors.white, gui = 'bold' },
|
||||
b = { bg = colors.gray, fg = colors.darkgray },
|
||||
c = { bg = colors.darkgray, fg = colors.white },
|
||||
},
|
||||
replace = {
|
||||
a = { bg = colors.green, fg = colors.white, gui = 'bold' },
|
||||
b = { bg = colors.gray, fg = colors.darkgray },
|
||||
c = { bg = colors.gray, fg = colors.black },
|
||||
},
|
||||
command = {
|
||||
a = { bg = colors.darkgray, fg = colors.white, gui = 'bold' },
|
||||
b = { bg = colors.gray, fg = colors.darkgray },
|
||||
c = { bg = colors.lightgray, fg = colors.darkgray },
|
||||
},
|
||||
inactive = {
|
||||
a = { bg = colors.lightgray, fg = colors.inactivegray },
|
||||
b = { bg = colors.lightgray, fg = colors.inactivegray },
|
||||
c = { bg = colors.lightgray, fg = colors.inactivegray },
|
||||
},
|
||||
}
|
||||
@ -0,0 +1,48 @@
|
||||
-- Copyright (c) 2021 Jnhtr
|
||||
-- MIT license, see LICENSE for more details.
|
||||
-- stylua: ignore
|
||||
local colors = {
|
||||
black = '#1c1e26',
|
||||
white = '#6C6F93',
|
||||
red = '#F43E5C',
|
||||
green = '#09F7A0',
|
||||
blue = '#25B2BC',
|
||||
yellow = '#F09383',
|
||||
gray = '#E95678',
|
||||
darkgray = '#1A1C23',
|
||||
lightgray = '#2E303E',
|
||||
inactivegray = '#1C1E26',
|
||||
}
|
||||
|
||||
return {
|
||||
normal = {
|
||||
a = { bg = colors.gray, fg = colors.black, gui = 'bold' },
|
||||
b = { bg = colors.lightgray, fg = colors.white },
|
||||
c = { bg = colors.darkgray, fg = colors.white },
|
||||
},
|
||||
insert = {
|
||||
a = { bg = colors.blue, fg = colors.black, gui = 'bold' },
|
||||
b = { bg = colors.lightgray, fg = colors.white },
|
||||
c = { bg = colors.darkgray, fg = colors.white },
|
||||
},
|
||||
visual = {
|
||||
a = { bg = colors.yellow, fg = colors.black, gui = 'bold' },
|
||||
b = { bg = colors.lightgray, fg = colors.white },
|
||||
c = { bg = colors.darkgray, fg = colors.white },
|
||||
},
|
||||
replace = {
|
||||
a = { bg = colors.red, fg = colors.black, gui = 'bold' },
|
||||
b = { bg = colors.lightgray, fg = colors.white },
|
||||
c = { bg = colors.darkgray, fg = colors.white },
|
||||
},
|
||||
command = {
|
||||
a = { bg = colors.green, fg = colors.black, gui = 'bold' },
|
||||
b = { bg = colors.lightgray, fg = colors.white },
|
||||
c = { bg = colors.darkgray, fg = colors.white },
|
||||
},
|
||||
inactive = {
|
||||
a = { bg = colors.inactivegray, fg = colors.lightgray, gui = 'bold' },
|
||||
b = { bg = colors.inactivegray, fg = colors.lightgray },
|
||||
c = { bg = colors.inactivegray, fg = colors.lightgray },
|
||||
},
|
||||
}
|
||||
@ -0,0 +1,7 @@
|
||||
-- Copyright (c) 2020-2021 shadmansaleh
|
||||
-- MIT license, see LICENSE for more details.
|
||||
-- Credit: itchyny(lightline)
|
||||
-- License: MIT License
|
||||
local background = vim.opt.background:get()
|
||||
|
||||
return require('lualine.themes.iceberg_' .. background)
|
||||
@ -0,0 +1,42 @@
|
||||
-- Copyright (c) 2020-2021 shadmansaleh
|
||||
-- MIT license, see LICENSE for more details.
|
||||
-- Generated by lightline to lualine theme converter
|
||||
-- https://gist.github.com/shadmansaleh/000871c9a608a012721c6acc6d7a19b9
|
||||
-- stylua: ignore
|
||||
local colors = {
|
||||
color2 = '#161821',
|
||||
color3 = '#b4be82',
|
||||
color4 = '#c6c8d1',
|
||||
color5 = '#2e313f',
|
||||
color8 = '#e2a478',
|
||||
color9 = '#3e445e',
|
||||
color10 = '#0f1117',
|
||||
color11 = '#17171b',
|
||||
color12 = '#818596',
|
||||
color15 = '#84a0c6',
|
||||
}
|
||||
|
||||
return {
|
||||
visual = {
|
||||
a = { fg = colors.color2, bg = colors.color3, gui = 'bold' },
|
||||
b = { fg = colors.color4, bg = colors.color5 },
|
||||
},
|
||||
replace = {
|
||||
a = { fg = colors.color2, bg = colors.color8, gui = 'bold' },
|
||||
b = { fg = colors.color4, bg = colors.color5 },
|
||||
},
|
||||
inactive = {
|
||||
a = { fg = colors.color9, bg = colors.color10, gui = 'bold' },
|
||||
b = { fg = colors.color9, bg = colors.color10 },
|
||||
c = { fg = colors.color9, bg = colors.color10 },
|
||||
},
|
||||
normal = {
|
||||
a = { fg = colors.color11, bg = colors.color12, gui = 'bold' },
|
||||
b = { fg = colors.color4, bg = colors.color5 },
|
||||
c = { fg = colors.color4, bg = colors.color10 },
|
||||
},
|
||||
insert = {
|
||||
a = { fg = colors.color2, bg = colors.color15, gui = 'bold' },
|
||||
b = { fg = colors.color4, bg = colors.color5 },
|
||||
},
|
||||
}
|
||||
@ -0,0 +1,40 @@
|
||||
-- Copyright (c) 2020-2021 shadmansaleh
|
||||
-- MIT license, see LICENSE for more details.
|
||||
-- Generated by lightline to lualine theme converter
|
||||
-- https://gist.github.com/shadmansaleh/000871c9a608a012721c6acc6d7a19b9
|
||||
-- stylua: ignore
|
||||
local colors = {
|
||||
color5 = '#668e3d',
|
||||
color8 = '#757ca3',
|
||||
color9 = '#8b98b6',
|
||||
color10 = '#cad0de',
|
||||
color11 = '#2d539e',
|
||||
color0 = '#e8e9ec',
|
||||
color1 = '#9fa6c0',
|
||||
color2 = '#c57339',
|
||||
}
|
||||
|
||||
return {
|
||||
replace = {
|
||||
b = { fg = colors.color0, bg = colors.color1 },
|
||||
a = { fg = colors.color0, bg = colors.color2, gui = 'bold' },
|
||||
},
|
||||
visual = {
|
||||
b = { fg = colors.color0, bg = colors.color1 },
|
||||
a = { fg = colors.color0, bg = colors.color5, gui = 'bold' },
|
||||
},
|
||||
normal = {
|
||||
b = { fg = colors.color0, bg = colors.color1 },
|
||||
a = { fg = colors.color0, bg = colors.color8, gui = 'bold' },
|
||||
c = { fg = colors.color9, bg = colors.color10 },
|
||||
},
|
||||
inactive = {
|
||||
b = { fg = colors.color9, bg = colors.color10 },
|
||||
a = { fg = colors.color9, bg = colors.color10, gui = 'bold' },
|
||||
c = { fg = colors.color9, bg = colors.color10 },
|
||||
},
|
||||
insert = {
|
||||
b = { fg = colors.color0, bg = colors.color1 },
|
||||
a = { fg = colors.color0, bg = colors.color11, gui = 'bold' },
|
||||
},
|
||||
}
|
||||
@ -0,0 +1,41 @@
|
||||
-- Copyright (c) 2020-2021 shadmansaleh
|
||||
-- MIT license, see LICENSE for more details.
|
||||
-- Generated by lightline to lualine theme converter
|
||||
-- https://gist.github.com/shadmansaleh/000871c9a608a012721c6acc6d7a19b9
|
||||
-- stylua: ignore
|
||||
local colors = {
|
||||
color2 = '#30302c',
|
||||
color3 = '#f0a0c0',
|
||||
color4 = '#e8e8d3',
|
||||
color5 = '#4e4e43',
|
||||
color8 = '#cf6a4c',
|
||||
color9 = '#666656',
|
||||
color10 = '#808070',
|
||||
color11 = '#8197bf',
|
||||
color14 = '#99ad6a',
|
||||
}
|
||||
|
||||
return {
|
||||
visual = {
|
||||
a = { fg = colors.color2, bg = colors.color3, gui = 'bold' },
|
||||
b = { fg = colors.color4, bg = colors.color5 },
|
||||
},
|
||||
replace = {
|
||||
a = { fg = colors.color2, bg = colors.color8, gui = 'bold' },
|
||||
b = { fg = colors.color4, bg = colors.color5 },
|
||||
},
|
||||
inactive = {
|
||||
c = { fg = colors.color9, bg = colors.color2 },
|
||||
a = { fg = colors.color10, bg = colors.color2, gui = 'bold' },
|
||||
b = { fg = colors.color9, bg = colors.color2 },
|
||||
},
|
||||
normal = {
|
||||
c = { fg = colors.color10, bg = colors.color2 },
|
||||
a = { fg = colors.color2, bg = colors.color11, gui = 'bold' },
|
||||
b = { fg = colors.color4, bg = colors.color5 },
|
||||
},
|
||||
insert = {
|
||||
a = { fg = colors.color2, bg = colors.color14, gui = 'bold' },
|
||||
b = { fg = colors.color4, bg = colors.color5 },
|
||||
},
|
||||
}
|
||||
@ -0,0 +1,42 @@
|
||||
-- Copyright (c) 2020-2021 shadmansaleh
|
||||
-- MIT license, see LICENSE for more details.
|
||||
-- Credit: Lokesh Krishna(lightline)
|
||||
-- stylua: ignore
|
||||
local colors = {
|
||||
fg = '#eeffff',
|
||||
bg = '#263238',
|
||||
blue = '#82aaff',
|
||||
green = '#c3e88d',
|
||||
purple = '#c792ea',
|
||||
red1 = '#f07178',
|
||||
red2 = '#ff5370',
|
||||
yellow = '#ffcb6b',
|
||||
gray1 = '#314549',
|
||||
gray2 = '#2E3C43',
|
||||
gray3 = '#515559',
|
||||
}
|
||||
|
||||
return {
|
||||
normal = {
|
||||
a = { fg = colors.bg, bg = colors.blue, gui = 'bold' },
|
||||
b = { fg = colors.fg, bg = colors.gray3 },
|
||||
c = { fg = colors.fg, bg = colors.gray2 },
|
||||
},
|
||||
insert = {
|
||||
a = { fg = colors.bg, bg = colors.green, gui = 'bold' },
|
||||
b = { fg = colors.fg, bg = colors.gray3 },
|
||||
},
|
||||
visual = {
|
||||
a = { fg = colors.bg, bg = colors.purple, gui = 'bold' },
|
||||
b = { fg = colors.fg, bg = colors.gray3 },
|
||||
},
|
||||
replace = {
|
||||
a = { fg = colors.bg, bg = colors.red1, gui = 'bold' },
|
||||
b = { fg = colors.fg, bg = colors.gray3 },
|
||||
},
|
||||
inactive = {
|
||||
a = { fg = colors.fg, bg = colors.bg, gui = 'bold' },
|
||||
b = { fg = colors.fg, bg = colors.bg },
|
||||
c = { fg = colors.fg, bg = colors.gray2 },
|
||||
},
|
||||
}
|
||||
@ -0,0 +1,48 @@
|
||||
-- Copyright (c) 2020-2021 ronniedroid
|
||||
-- MIT license, see LICENSE for more details.
|
||||
-- stylua: ignore
|
||||
local colors = {
|
||||
black = '#000000',
|
||||
white = '#eeeeee',
|
||||
red = '#ffa0a0',
|
||||
green = '#88cf88',
|
||||
blue = '#92baff',
|
||||
magenta = '#feacd0',
|
||||
cyan = '#a0bfdf',
|
||||
gray = '#2f2f2f',
|
||||
darkgray = '#202020',
|
||||
lightgray = '#434343'
|
||||
}
|
||||
|
||||
return {
|
||||
normal = {
|
||||
a = { bg = colors.blue, fg = colors.lightgray, gui = 'bold' },
|
||||
b = { bg = colors.lightgray, fg = colors.blue },
|
||||
c = { bg = colors.gray, fg = colors.white },
|
||||
},
|
||||
insert = {
|
||||
a = { bg = colors.cyan, fg = colors.lightgray, gui = 'bold' },
|
||||
b = { bg = colors.lightgray, fg = colors.cyan },
|
||||
c = { bg = colors.gray, fg = colors.white },
|
||||
},
|
||||
visual = {
|
||||
a = { bg = colors.magenta, fg = colors.lightgray, gui = 'bold' },
|
||||
b = { bg = colors.lightgray, fg = colors.magenta },
|
||||
c = { bg = colors.gray, fg = colors.white },
|
||||
},
|
||||
replace = {
|
||||
a = { bg = colors.red, fg = colors.lightgray, gui = 'bold' },
|
||||
b = { bg = colors.lightgray, fg = colors.red },
|
||||
c = { bg = colors.gray, fg = colors.white },
|
||||
},
|
||||
command = {
|
||||
a = { bg = colors.green, fg = colors.lightgray, gui = 'bold' },
|
||||
b = { bg = colors.lightgray, fg = colors.green },
|
||||
c = { bg = colors.gray, fg = colors.white },
|
||||
},
|
||||
inactive = {
|
||||
a = { bg = colors.darkgray, fg = colors.lightgray, gui = 'bold' },
|
||||
b = { bg = colors.darkgray, fg = colors.lightgray },
|
||||
c = { bg = colors.darkgray, fg = colors.lightgray },
|
||||
},
|
||||
}
|
||||
@ -0,0 +1,31 @@
|
||||
-- Copyright (c) 2020-2021 shadmansaleh
|
||||
-- MIT license, see LICENSE for more details.
|
||||
-- Credit: challsted(lightline)
|
||||
-- stylua: ignore
|
||||
local colors = {
|
||||
black = '#232526',
|
||||
gray = '#808080',
|
||||
white = '#f8f8f2',
|
||||
cyan = '#66d9ef',
|
||||
green = '#a6e22e',
|
||||
orange = '#ef5939',
|
||||
pink = '#f92672',
|
||||
red = '#ff0000',
|
||||
yellow = '#e6db74',
|
||||
}
|
||||
|
||||
return {
|
||||
normal = {
|
||||
a = { fg = colors.black, bg = colors.cyan, gui = 'bold' },
|
||||
b = { fg = colors.black, bg = colors.pink },
|
||||
c = { fg = colors.orange, bg = colors.black },
|
||||
},
|
||||
insert = { a = { fg = colors.black, bg = colors.green, gui = 'bold' } },
|
||||
visual = { a = { fg = colors.black, bg = colors.yellow, gui = 'bold' } },
|
||||
replace = { a = { fg = colors.black, bg = colors.red, gui = 'bold' } },
|
||||
inactive = {
|
||||
a = { fg = colors.pink, bg = colors.black, gui = 'bold' },
|
||||
b = { fg = colors.white, bg = colors.pink },
|
||||
c = { fg = colors.gray, bg = colors.black },
|
||||
},
|
||||
}
|
||||
@ -0,0 +1,40 @@
|
||||
-- moonfly color scheme for lualine
|
||||
--
|
||||
-- URL: github.com/bluz71/vim-moonfly-colors
|
||||
-- License: MIT (https://opensource.org/licenses/MIT)
|
||||
|
||||
-- stylua: ignore
|
||||
local colors = {
|
||||
color3 = '#303030',
|
||||
color6 = '#9e9e9e',
|
||||
color7 = '#80a0ff',
|
||||
color8 = '#ae81ff',
|
||||
color0 = '#1c1c1c',
|
||||
color1 = '#ff5189',
|
||||
color2 = '#c6c6c6',
|
||||
}
|
||||
|
||||
return {
|
||||
replace = {
|
||||
a = { fg = colors.color0, bg = colors.color1, gui = 'bold' },
|
||||
b = { fg = colors.color2, bg = colors.color3 },
|
||||
},
|
||||
inactive = {
|
||||
a = { fg = colors.color6, bg = colors.color3, gui = 'bold' },
|
||||
b = { fg = colors.color6, bg = colors.color3 },
|
||||
c = { fg = colors.color6, bg = colors.color3 },
|
||||
},
|
||||
normal = {
|
||||
a = { fg = colors.color0, bg = colors.color7, gui = 'bold' },
|
||||
b = { fg = colors.color2, bg = colors.color3 },
|
||||
c = { fg = colors.color2, bg = colors.color3 },
|
||||
},
|
||||
visual = {
|
||||
a = { fg = colors.color0, bg = colors.color8, gui = 'bold' },
|
||||
b = { fg = colors.color2, bg = colors.color3 },
|
||||
},
|
||||
insert = {
|
||||
a = { fg = colors.color0, bg = colors.color2, gui = 'bold' },
|
||||
b = { fg = colors.color2, bg = colors.color3 },
|
||||
},
|
||||
}
|
||||
@ -0,0 +1,37 @@
|
||||
-- Copyright (c) 2020-2021 shadmansaleh
|
||||
-- MIT license, see LICENSE for more details.
|
||||
-- stylua: ignore
|
||||
local colors = {
|
||||
color3 = '#2c3043',
|
||||
color6 = '#a1aab8',
|
||||
color7 = '#82aaff',
|
||||
color8 = '#ae81ff',
|
||||
color0 = '#092236',
|
||||
color1 = '#ff5874',
|
||||
color2 = '#c3ccdc',
|
||||
}
|
||||
|
||||
return {
|
||||
replace = {
|
||||
a = { fg = colors.color0, bg = colors.color1, gui = 'bold' },
|
||||
b = { fg = colors.color2, bg = colors.color3 },
|
||||
},
|
||||
inactive = {
|
||||
a = { fg = colors.color6, bg = colors.color3, gui = 'bold' },
|
||||
b = { fg = colors.color6, bg = colors.color3 },
|
||||
c = { fg = colors.color6, bg = colors.color3 },
|
||||
},
|
||||
normal = {
|
||||
a = { fg = colors.color0, bg = colors.color7, gui = 'bold' },
|
||||
b = { fg = colors.color2, bg = colors.color3 },
|
||||
c = { fg = colors.color2, bg = colors.color3 },
|
||||
},
|
||||
visual = {
|
||||
a = { fg = colors.color0, bg = colors.color8, gui = 'bold' },
|
||||
b = { fg = colors.color2, bg = colors.color3 },
|
||||
},
|
||||
insert = {
|
||||
a = { fg = colors.color0, bg = colors.color2, gui = 'bold' },
|
||||
b = { fg = colors.color2, bg = colors.color3 },
|
||||
},
|
||||
}
|
||||
@ -0,0 +1,28 @@
|
||||
-- Copyright (c) 2020-2021 shadmansaleh
|
||||
-- MIT license, see LICENSE for more details.
|
||||
-- stylua: ignore
|
||||
local colors = {
|
||||
nord1 = '#3B4252',
|
||||
nord3 = '#4C566A',
|
||||
nord5 = '#E5E9F0',
|
||||
nord6 = '#ECEFF4',
|
||||
nord7 = '#8FBCBB',
|
||||
nord8 = '#88C0D0',
|
||||
nord13 = '#EBCB8B',
|
||||
}
|
||||
|
||||
return {
|
||||
normal = {
|
||||
a = { fg = colors.nord1, bg = colors.nord8, gui = 'bold' },
|
||||
b = { fg = colors.nord5, bg = colors.nord1 },
|
||||
c = { fg = colors.nord5, bg = colors.nord3 },
|
||||
},
|
||||
insert = { a = { fg = colors.nord1, bg = colors.nord6, gui = 'bold' } },
|
||||
visual = { a = { fg = colors.nord1, bg = colors.nord7, gui = 'bold' } },
|
||||
replace = { a = { fg = colors.nord1, bg = colors.nord13, gui = 'bold' } },
|
||||
inactive = {
|
||||
a = { fg = colors.nord1, bg = colors.nord8, gui = 'bold' },
|
||||
b = { fg = colors.nord5, bg = colors.nord1 },
|
||||
c = { fg = colors.nord5, bg = colors.nord1 },
|
||||
},
|
||||
}
|
||||
@ -0,0 +1,36 @@
|
||||
-- Copyright (c) 2020-2021 shadmansaleh
|
||||
-- MIT license, see LICENSE for more details.
|
||||
-- Credit: Zoltan Dalmadi(lightline)
|
||||
-- stylua: ignore
|
||||
local colors = {
|
||||
blue = '#61afef',
|
||||
green = '#98c379',
|
||||
purple = '#c678dd',
|
||||
cyan = '#56b6c2',
|
||||
red1 = '#e06c75',
|
||||
red2 = '#be5046',
|
||||
yellow = '#e5c07b',
|
||||
fg = '#abb2bf',
|
||||
bg = '#282c34',
|
||||
gray1 = '#828997',
|
||||
gray2 = '#2c323c',
|
||||
gray3 = '#3e4452',
|
||||
}
|
||||
|
||||
return {
|
||||
normal = {
|
||||
a = { fg = colors.bg, bg = colors.green, gui = 'bold' },
|
||||
b = { fg = colors.fg, bg = colors.gray3 },
|
||||
c = { fg = colors.fg, bg = colors.gray2 },
|
||||
},
|
||||
command = { a = { fg = colors.bg, bg = colors.yellow, gui = 'bold' } },
|
||||
insert = { a = { fg = colors.bg, bg = colors.blue, gui = 'bold' } },
|
||||
visual = { a = { fg = colors.bg, bg = colors.purple, gui = 'bold' } },
|
||||
terminal = { a = { fg = colors.bg, bg = colors.cyan, gui = 'bold' } },
|
||||
replace = { a = { fg = colors.bg, bg = colors.red1, gui = 'bold' } },
|
||||
inactive = {
|
||||
a = { fg = colors.gray1, bg = colors.bg, gui = 'bold' },
|
||||
b = { fg = colors.gray1, bg = colors.bg },
|
||||
c = { fg = colors.gray1, bg = colors.gray2 },
|
||||
},
|
||||
}
|
||||
@ -0,0 +1,34 @@
|
||||
-- Copyright (c) 2020-2021 shadmansaleh
|
||||
-- MIT license, see LICENSE for more details.
|
||||
-- Credit: Zoltan Dalmadi(lightline)
|
||||
-- stylua: ignore
|
||||
local colors = {
|
||||
blue = '#4078f2',
|
||||
green = '#50a14f',
|
||||
purple = '#a626a4',
|
||||
red1 = '#e45649',
|
||||
red2 = '#ca1243',
|
||||
yellow = '#c18401',
|
||||
fg = '#494b53',
|
||||
bg = '#fafafa',
|
||||
gray1 = '#696c77',
|
||||
gray2 = '#f0f0f0',
|
||||
gray3 = '#d0d0d0',
|
||||
}
|
||||
|
||||
return {
|
||||
normal = {
|
||||
a = { fg = colors.bg, bg = colors.green, gui = 'bold' },
|
||||
b = { fg = colors.fg, bg = colors.gray3 },
|
||||
c = { fg = colors.fg, bg = colors.gray2 },
|
||||
},
|
||||
command = { a = { fg = colors.bg, bg = colors.yellow, gui = 'bold' } },
|
||||
insert = { a = { fg = colors.bg, bg = colors.blue, gui = 'bold' } },
|
||||
visual = { a = { fg = colors.bg, bg = colors.purple, gui = 'bold' } },
|
||||
replace = { a = { fg = colors.bg, bg = colors.red1, gui = 'bold' } },
|
||||
inactive = {
|
||||
a = { fg = colors.bg, bg = colors.gray3, gui = 'bold' },
|
||||
b = { fg = colors.bg, bg = colors.gray3 },
|
||||
c = { fg = colors.gray3, bg = colors.gray2 },
|
||||
},
|
||||
}
|
||||
@ -0,0 +1,47 @@
|
||||
-- Copyright (c) 2020-2021 IGI-111
|
||||
-- MIT license, see LICENSE for more details.
|
||||
-- stylua: ignore
|
||||
local colors = {
|
||||
vertsplit = '#181A1F',
|
||||
special_grey = '#3B4048',
|
||||
menu_grey = '#3E4452',
|
||||
cursor_grey = '#2C323C',
|
||||
gutter_fg_grey = '#4B5263',
|
||||
blue = '#82b1ff',
|
||||
dark_red = '#BE5046',
|
||||
white = '#bfc7d5',
|
||||
green = '#C3E88D',
|
||||
purple = '#c792ea',
|
||||
yellow = '#ffcb6b',
|
||||
light_red = '#ff869a',
|
||||
red = '#ff5370',
|
||||
dark_yellow = '#F78C6C',
|
||||
cyan = '#89DDFF',
|
||||
comment_grey = '#697098',
|
||||
black = '#292D3E',
|
||||
}
|
||||
|
||||
return {
|
||||
normal = {
|
||||
a = { fg = colors.black, bg = colors.purple, gui = 'bold' },
|
||||
b = { fg = colors.purple, bg = colors.menu_grey },
|
||||
c = { fg = colors.comment_grey, bg = colors.black },
|
||||
},
|
||||
insert = {
|
||||
a = { fg = colors.black, bg = colors.blue, gui = 'bold' },
|
||||
b = { fg = colors.blue, bg = colors.menu_grey },
|
||||
},
|
||||
visual = {
|
||||
a = { fg = colors.black, bg = colors.cyan, gui = 'bold' },
|
||||
b = { fg = colors.cyan, bg = colors.menu_grey },
|
||||
},
|
||||
replace = {
|
||||
a = { fg = colors.black, bg = colors.green, gui = 'bold' },
|
||||
b = { fg = colors.green, bg = colors.menu_grey },
|
||||
},
|
||||
inactive = {
|
||||
a = { fg = colors.black, bg = colors.menu_grey, gui = 'bold' },
|
||||
b = { fg = colors.black, bg = colors.menu_grey },
|
||||
c = { fg = colors.black, bg = colors.menu_grey },
|
||||
},
|
||||
}
|
||||
@ -0,0 +1,42 @@
|
||||
-- Copyright (c) 2020-2021 shadmansaleh
|
||||
-- MIT license, see LICENSE for more details.
|
||||
-- Credit: TKNGUE(lightline)
|
||||
-- stylua: ignore
|
||||
local colors = {
|
||||
red = '#df0000',
|
||||
green = '#008700',
|
||||
blue = '#00afaf',
|
||||
pink = '#afdf00',
|
||||
olive = '#dfaf5f',
|
||||
navy = '#df875f',
|
||||
orange = '#d75f00',
|
||||
purple = '#8959a8',
|
||||
aqua = '#3e999f',
|
||||
foreground = '#d0d0d0',
|
||||
background = '#444444',
|
||||
window = '#efefef',
|
||||
status = '#c6c6c6',
|
||||
error = '#5f0000',
|
||||
statusline_active_fg = '#1c1c1c',
|
||||
statusline_active_bg = '#5f8787',
|
||||
statusline_inactive_fg = '#c6c6c6',
|
||||
statusline_inactive_bg = '#444444',
|
||||
visual_fg = '#000000',
|
||||
visual_bg = '#8787af',
|
||||
}
|
||||
|
||||
return {
|
||||
normal = {
|
||||
a = { fg = colors.foreground, bg = colors.background, gui = 'bold' },
|
||||
b = { fg = colors.statusline_active_fg, bg = colors.status },
|
||||
c = { fg = colors.statusline_active_fg, bg = colors.statusline_active_bg },
|
||||
},
|
||||
insert = { a = { fg = colors.background, bg = colors.blue, gui = 'bold' } },
|
||||
visual = { a = { fg = colors.visual_fg, bg = colors.visual_bg, gui = 'bold' } },
|
||||
replace = { a = { fg = colors.background, bg = colors.pink, gui = 'bold' } },
|
||||
inactive = {
|
||||
a = { fg = colors.foreground, bg = colors.background, gui = 'bold' },
|
||||
b = { fg = colors.foreground, bg = colors.background },
|
||||
c = { fg = colors.foreground, bg = colors.background },
|
||||
},
|
||||
}
|
||||
@ -0,0 +1,40 @@
|
||||
-- Copyright (c) 2020-2021 shadmansaleh
|
||||
-- MIT license, see LICENSE for more details.
|
||||
-- Credit: TKNGUE(lightline)
|
||||
-- stylua: ignore
|
||||
local colors = {
|
||||
red = '#df0000',
|
||||
green = '#008700',
|
||||
blue = '#4271ae',
|
||||
pink = '#d7005f',
|
||||
olive = '#718c00',
|
||||
navy = '#005f87',
|
||||
orange = '#d75f00',
|
||||
purple = '#8959a8',
|
||||
aqua = '#3e999f',
|
||||
foreground = '#4d4d4c',
|
||||
background = '#F5F5F5',
|
||||
window = '#efefef',
|
||||
status = '#3e999f',
|
||||
error = '#ffafdf',
|
||||
statusline_active_fg = '#efefef',
|
||||
statusline_active_bg = '#005f87',
|
||||
statusline_inactive_fg = '#4d4d4c',
|
||||
statusline_inactive_bg = '#dadada',
|
||||
}
|
||||
|
||||
return {
|
||||
normal = {
|
||||
a = { fg = colors.foreground, bg = colors.background, gui = 'bold' },
|
||||
b = { fg = colors.statusline_active_fg, bg = colors.status },
|
||||
c = { fg = colors.statusline_active_fg, bg = colors.statusline_active_bg },
|
||||
},
|
||||
insert = { a = { fg = colors.blue, bg = colors.background, gui = 'bold' } },
|
||||
visual = { a = { fg = colors.background, bg = colors.orange, gui = 'bold' } },
|
||||
replace = { a = { fg = colors.background, bg = colors.pink, gui = 'bold' } },
|
||||
inactive = {
|
||||
a = { fg = colors.foreground, bg = colors.background, gui = 'bold' },
|
||||
b = { fg = colors.foreground, bg = colors.background },
|
||||
c = { fg = colors.foreground, bg = colors.background },
|
||||
},
|
||||
}
|
||||
@ -0,0 +1,44 @@
|
||||
-- Copyright (c) 2020-2021 shadmansaleh
|
||||
-- MIT license, see LICENSE for more details.
|
||||
-- stylua: ignore
|
||||
local Colors = {
|
||||
white = '#ffffff',
|
||||
darkestgreen = '#005f00',
|
||||
brightgreen = '#afdf00',
|
||||
darkestcyan = '#005f5f',
|
||||
mediumcyan = '#87dfff',
|
||||
darkestblue = '#005f87',
|
||||
darkred = '#870000',
|
||||
brightred = '#df0000',
|
||||
brightorange = '#ff8700',
|
||||
gray1 = '#262626',
|
||||
gray2 = '#303030',
|
||||
gray4 = '#585858',
|
||||
gray5 = '#606060',
|
||||
gray7 = '#9e9e9e',
|
||||
gray10 = '#f0f0f0',
|
||||
}
|
||||
|
||||
local M = {
|
||||
normal = {
|
||||
a = { fg = Colors.darkestgreen, bg = Colors.brightgreen, gui = 'bold' },
|
||||
b = { fg = Colors.gray10, bg = Colors.gray5 },
|
||||
c = { fg = Colors.gray7, bg = Colors.gray2 },
|
||||
},
|
||||
insert = {
|
||||
a = { fg = Colors.darkestcyan, bg = Colors.white, gui = 'bold' },
|
||||
b = { fg = Colors.darkestcyan, bg = Colors.mediumcyan },
|
||||
c = { fg = Colors.mediumcyan, bg = Colors.darkestblue },
|
||||
},
|
||||
visual = { a = { fg = Colors.darkred, bg = Colors.brightorange, gui = 'bold' } },
|
||||
replace = { a = { fg = Colors.white, bg = Colors.brightred, gui = 'bold' } },
|
||||
inactive = {
|
||||
a = { fg = Colors.gray1, bg = Colors.gray5, gui = 'bold' },
|
||||
b = { fg = Colors.gray1, bg = Colors.gray5 },
|
||||
c = { bg = Colors.gray1, fg = Colors.gray5 },
|
||||
},
|
||||
}
|
||||
|
||||
M.terminal = M.insert
|
||||
|
||||
return M
|
||||
@ -0,0 +1,60 @@
|
||||
-- Copyright (c) 2021 Ashish Panigrahi
|
||||
-- MIT license, see LICENSE for more details.
|
||||
-- stylua: ignore
|
||||
local colors = {
|
||||
black = '#202020',
|
||||
neon = '#DFFF00',
|
||||
white = '#FFFFFF',
|
||||
green = '#00D700',
|
||||
purple = '#5F005F',
|
||||
blue = '#00DFFF',
|
||||
darkblue = '#00005F',
|
||||
navyblue = '#000080',
|
||||
brightgreen = '#9CFFD3',
|
||||
gray = '#444444',
|
||||
darkgray = '#3c3836',
|
||||
lightgray = '#504945',
|
||||
inactivegray = '#7c6f64',
|
||||
orange = '#FFAF00',
|
||||
red = '#5F0000',
|
||||
brightorange = '#C08A20',
|
||||
brightred = '#AF0000',
|
||||
cyan = '#00DFFF',
|
||||
}
|
||||
|
||||
local M = {
|
||||
normal = {
|
||||
a = { bg = colors.neon, fg = colors.black, gui = 'bold' },
|
||||
b = { bg = colors.gray, fg = colors.white },
|
||||
c = { bg = colors.black, fg = colors.brightgreen },
|
||||
},
|
||||
insert = {
|
||||
a = { bg = colors.blue, fg = colors.darkblue, gui = 'bold' },
|
||||
b = { bg = colors.navyblue, fg = colors.white },
|
||||
c = { bg = colors.purple, fg = colors.white },
|
||||
},
|
||||
visual = {
|
||||
a = { bg = colors.orange, fg = colors.black, gui = 'bold' },
|
||||
b = { bg = colors.darkgray, fg = colors.white },
|
||||
c = { bg = colors.red, fg = colors.white },
|
||||
},
|
||||
replace = {
|
||||
a = { bg = colors.brightred, fg = colors.white, gui = 'bold' },
|
||||
b = { bg = colors.cyan, fg = colors.darkblue },
|
||||
c = { bg = colors.navyblue, fg = colors.white },
|
||||
},
|
||||
command = {
|
||||
a = { bg = colors.green, fg = colors.black, gui = 'bold' },
|
||||
b = { bg = colors.darkgray, fg = colors.white },
|
||||
c = { bg = colors.black, fg = colors.brightgreen },
|
||||
},
|
||||
inactive = {
|
||||
a = { bg = colors.darkgray, fg = colors.gray, gui = 'bold' },
|
||||
b = { bg = colors.darkgray, fg = colors.gray },
|
||||
c = { bg = colors.darkgray, fg = colors.gray },
|
||||
},
|
||||
}
|
||||
|
||||
M.terminal = M.insert
|
||||
|
||||
return M
|
||||
@ -0,0 +1,50 @@
|
||||
-- Copyright (c) 2020-2021 shadmansaleh
|
||||
-- MIT license, see LICENSE for more details.
|
||||
|
||||
local lualine_require = require('lualine_require')
|
||||
local modules = lualine_require.lazy_require {
|
||||
utils_notices = 'lualine.utils.notices',
|
||||
}
|
||||
local sep = package.config:sub(1, 1)
|
||||
local wal_colors_path = table.concat({ os.getenv('HOME'), '.cache', 'wal', 'colors.sh' }, sep)
|
||||
local wal_colors_file = io.open(wal_colors_path, 'r')
|
||||
|
||||
if wal_colors_file == nil then
|
||||
modules.utils_notices.add_notice('lualine.nvim: ' .. wal_colors_path .. ' not found')
|
||||
error('')
|
||||
end
|
||||
|
||||
local ok, wal_colors_text = pcall(wal_colors_file.read, wal_colors_file, '*a')
|
||||
wal_colors_file:close()
|
||||
|
||||
if not ok then
|
||||
modules.utils_notices.add_notice('lualine.nvim: ' .. wal_colors_path .. ' could not be read: ' .. wal_colors_text)
|
||||
error('')
|
||||
end
|
||||
|
||||
local colors = {}
|
||||
|
||||
for line in vim.gsplit(wal_colors_text, '\n') do
|
||||
if line:match("^[a-z0-9]+='#[a-fA-F0-9]+'$") ~= nil then
|
||||
local i = line:find('=')
|
||||
local key = line:sub(0, i - 1)
|
||||
local value = line:sub(i + 2, #line - 1)
|
||||
colors[key] = value
|
||||
end
|
||||
end
|
||||
|
||||
return {
|
||||
normal = {
|
||||
a = { fg = colors.background, bg = colors.color4, gui = 'bold' },
|
||||
b = { fg = colors.foreground, bg = colors.color8 },
|
||||
c = { fg = colors.foreground, bg = colors.background },
|
||||
},
|
||||
insert = { a = { fg = colors.background, bg = colors.color2, gui = 'bold' } },
|
||||
visual = { a = { fg = colors.background, bg = colors.color3, gui = 'bold' } },
|
||||
replace = { a = { fg = colors.background, bg = colors.color1, gui = 'bold' } },
|
||||
inactive = {
|
||||
a = { fg = colors.foreground, bg = colors.background, gui = 'bold' },
|
||||
b = { fg = colors.foreground, bg = colors.background },
|
||||
c = { fg = colors.foreground, bg = colors.background },
|
||||
},
|
||||
}
|
||||
@ -0,0 +1,41 @@
|
||||
-- Copyright (c) 2020-2021 shadmansaleh
|
||||
-- MIT license, see LICENSE for more details.
|
||||
-- Generated by lightline to lualine theme converter
|
||||
-- https://gist.github.com/shadmansaleh/000871c9a608a012721c6acc6d7a19b9
|
||||
-- stylua: ignore
|
||||
local colors = {
|
||||
color5 = '#d7afaf',
|
||||
color6 = '#666656',
|
||||
color7 = '#808070',
|
||||
color10 = '#87af87',
|
||||
color13 = '#df5f87',
|
||||
color14 = '#87afaf',
|
||||
color0 = '#e8e8d3',
|
||||
color1 = '#4e4e43',
|
||||
color4 = '#30302c',
|
||||
}
|
||||
|
||||
return {
|
||||
visual = {
|
||||
b = { fg = colors.color0, bg = colors.color1 },
|
||||
a = { fg = colors.color4, bg = colors.color5, gui = 'bold' },
|
||||
},
|
||||
inactive = {
|
||||
b = { fg = colors.color6, bg = colors.color4 },
|
||||
c = { fg = colors.color6, bg = colors.color4 },
|
||||
a = { fg = colors.color7, bg = colors.color4, gui = 'bold' },
|
||||
},
|
||||
insert = {
|
||||
b = { fg = colors.color0, bg = colors.color1 },
|
||||
a = { fg = colors.color4, bg = colors.color10, gui = 'bold' },
|
||||
},
|
||||
replace = {
|
||||
b = { fg = colors.color0, bg = colors.color1 },
|
||||
a = { fg = colors.color4, bg = colors.color13, gui = 'bold' },
|
||||
},
|
||||
normal = {
|
||||
b = { fg = colors.color0, bg = colors.color1 },
|
||||
c = { fg = colors.color7, bg = colors.color4 },
|
||||
a = { fg = colors.color4, bg = colors.color14, gui = 'bold' },
|
||||
},
|
||||
}
|
||||
@ -0,0 +1,7 @@
|
||||
-- Copyright (c) 2020-2021 shadmansaleh
|
||||
-- MIT license, see LICENSE for more details.
|
||||
-- Credit: itchyny(lightline)
|
||||
-- License: MIT License
|
||||
local background = vim.opt.background:get()
|
||||
|
||||
return require('lualine.themes.solarized_' .. background)
|
||||
@ -0,0 +1,38 @@
|
||||
-- Copyright (c) 2020-2021 shadmansaleh
|
||||
-- MIT license, see LICENSE for more details.
|
||||
-- Credit: itchyny(lightline)
|
||||
-- stylua: ignore
|
||||
local colors = {
|
||||
base03 = '#002b36',
|
||||
base02 = '#073642',
|
||||
base01 = '#586e75',
|
||||
base00 = '#657b83',
|
||||
base0 = '#839496',
|
||||
base1 = '#93a1a1',
|
||||
base2 = '#eee8d5',
|
||||
base3 = '#fdf6e3',
|
||||
yellow = '#b58900',
|
||||
orange = '#cb4b16',
|
||||
red = '#dc322f',
|
||||
magenta = '#d33682',
|
||||
violet = '#6c71c4',
|
||||
blue = '#268bd2',
|
||||
cyan = '#2aa198',
|
||||
green = '#859900',
|
||||
}
|
||||
|
||||
return {
|
||||
normal = {
|
||||
a = { fg = colors.base03, bg = colors.blue, gui = 'bold' },
|
||||
b = { fg = colors.base03, bg = colors.base1 },
|
||||
c = { fg = colors.base1, bg = colors.base02 },
|
||||
},
|
||||
insert = { a = { fg = colors.base03, bg = colors.green, gui = 'bold' } },
|
||||
visual = { a = { fg = colors.base03, bg = colors.magenta, gui = 'bold' } },
|
||||
replace = { a = { fg = colors.base03, bg = colors.red, gui = 'bold' } },
|
||||
inactive = {
|
||||
a = { fg = colors.base0, bg = colors.base02, gui = 'bold' },
|
||||
b = { fg = colors.base03, bg = colors.base00 },
|
||||
c = { fg = colors.base01, bg = colors.base02 },
|
||||
},
|
||||
}
|
||||
@ -0,0 +1,38 @@
|
||||
-- Copyright (c) 2020-2021 shadmansaleh
|
||||
-- MIT license, see LICENSE for more details.
|
||||
-- Credit: itchyny(lightline)
|
||||
-- stylua: ignore
|
||||
local colors = {
|
||||
base3 = '#002b36',
|
||||
base2 = '#073642',
|
||||
base1 = '#586e75',
|
||||
base0 = '#657b83',
|
||||
base00 = '#839496',
|
||||
base01 = '#93a1a1',
|
||||
base02 = '#eee8d5',
|
||||
base03 = '#fdf6e3',
|
||||
yellow = '#b58900',
|
||||
orange = '#cb4b16',
|
||||
red = '#dc322f',
|
||||
magenta = '#d33682',
|
||||
violet = '#6c71c4',
|
||||
blue = '#268bd2',
|
||||
cyan = '#2aa198',
|
||||
green = '#859900',
|
||||
}
|
||||
|
||||
return {
|
||||
normal = {
|
||||
a = { fg = colors.base03, bg = colors.blue, gui = 'bold' },
|
||||
b = { fg = colors.base03, bg = colors.base1 },
|
||||
c = { fg = colors.base1, bg = colors.base02 },
|
||||
},
|
||||
insert = { a = { fg = colors.base03, bg = colors.green, gui = 'bold' } },
|
||||
visual = { a = { fg = colors.base03, bg = colors.magenta, gui = 'bold' } },
|
||||
replace = { a = { fg = colors.base03, bg = colors.red, gui = 'bold' } },
|
||||
inactive = {
|
||||
a = { fg = colors.base0, bg = colors.base02, gui = 'bold' },
|
||||
b = { fg = colors.base03, bg = colors.base00 },
|
||||
c = { fg = colors.base01, bg = colors.base02 },
|
||||
},
|
||||
}
|
||||
@ -0,0 +1,38 @@
|
||||
-- Copyright (c) 2020-2021 shadmansaleh
|
||||
-- MIT license, see LICENSE for more details.
|
||||
-- Credit: itchyny(lightline)
|
||||
-- stylua: ignore
|
||||
local colors = {
|
||||
base03 = '#242424',
|
||||
base023 = '#353535',
|
||||
base02 = '#444444',
|
||||
base01 = '#585858',
|
||||
base00 = '#666666',
|
||||
base0 = '#808080',
|
||||
base1 = '#969696',
|
||||
base2 = '#a8a8a8',
|
||||
base3 = '#d0d0d0',
|
||||
yellow = '#cae682',
|
||||
orange = '#e5786d',
|
||||
red = '#e5786d',
|
||||
magenta = '#f2c68a',
|
||||
blue = '#8ac6f2',
|
||||
cyan = '#8ac6f2',
|
||||
green = '#95e454',
|
||||
}
|
||||
|
||||
return {
|
||||
normal = {
|
||||
a = { fg = colors.base02, bg = colors.blue, gui = 'bold' },
|
||||
b = { fg = colors.base02, bg = colors.base0 },
|
||||
c = { fg = colors.base2, bg = colors.base02 },
|
||||
},
|
||||
insert = { a = { fg = colors.base02, bg = colors.green, gui = 'bold' } },
|
||||
visual = { a = { fg = colors.base02, bg = colors.magenta, gui = 'bold' } },
|
||||
replace = { a = { fg = colors.base023, bg = colors.red, gui = 'bold' } },
|
||||
inactive = {
|
||||
a = { fg = colors.base1, bg = colors.base02, gui = 'bold' },
|
||||
b = { fg = colors.base023, bg = colors.base01 },
|
||||
c = { fg = colors.base1, bg = colors.base023 },
|
||||
},
|
||||
}
|
||||
@ -0,0 +1,43 @@
|
||||
-- Adapted from https://github.com/rxi/classic/blob/master/classic.lua
|
||||
local Object = {}
|
||||
|
||||
Object.__index = Object
|
||||
|
||||
-- luacheck: push no unused args
|
||||
---Initializer
|
||||
function Object:init(...) end
|
||||
-- luacheck: pop
|
||||
|
||||
---Extend base class to create a child class
|
||||
function Object:extend()
|
||||
local cls = {}
|
||||
for k, v in pairs(self) do
|
||||
if k:find('__') == 1 then
|
||||
cls[k] = v
|
||||
end
|
||||
end
|
||||
cls.__index = cls
|
||||
cls.super = self
|
||||
setmetatable(cls, self)
|
||||
return cls
|
||||
end
|
||||
|
||||
-- luacheck: push no unused args
|
||||
function Object:__tostring()
|
||||
return 'Object'
|
||||
end
|
||||
-- luacheck: pop
|
||||
|
||||
---Creates a new object
|
||||
function Object:new(...)
|
||||
local obj = setmetatable({}, self)
|
||||
obj:init(...)
|
||||
return obj
|
||||
end
|
||||
|
||||
---Creates a new object
|
||||
function Object:__call(...)
|
||||
return self:new(...)
|
||||
end
|
||||
|
||||
return Object
|
||||
@ -0,0 +1,331 @@
|
||||
-- Copyright (c) 2020-2021 shadmansaleh
|
||||
-- MIT license, see LICENSE for more details.
|
||||
local M = {}
|
||||
|
||||
-- stylua: ignore start
|
||||
-- color conversion
|
||||
local color_table = {
|
||||
-- lookup table for cterm colors
|
||||
-- format {'color_code', {r,g,b}}
|
||||
|
||||
-- Primary 3-bit (8 colors). Unique representation!
|
||||
{'00', { 0, 0, 0 }},
|
||||
{'01', { 128, 0, 0 }},
|
||||
{'02', { 0, 128, 0 }},
|
||||
{'03', { 128, 128, 0 }},
|
||||
{'04', { 0, 0, 128 }},
|
||||
{'05', { 128, 0, 128 }},
|
||||
{'06', { 0, 128, 128 }},
|
||||
{'07', { 192, 192, 192 }},
|
||||
|
||||
-- equivalent "bright" versions of original 8 colors.
|
||||
{'08', { 128, 128, 128 }},
|
||||
{'09', { 255, 0, 0 }},
|
||||
{'10', { 0, 255, 0 }},
|
||||
{'11', { 255, 255, 0 }},
|
||||
{'12', { 0, 0, 255 }},
|
||||
{'13', { 255, 0, 255 }},
|
||||
{'14', { 0, 255, 255 }},
|
||||
{'15', { 255, 255, 255 }},
|
||||
|
||||
-- Strictly ascending.
|
||||
{'16', { 0, 0, 0 }},
|
||||
{'17', { 0, 0, 95 }},
|
||||
{'18', { 0, 0, 135 }},
|
||||
{'19', { 0, 0, 175 }},
|
||||
{'20', { 0, 0, 215 }},
|
||||
{'21', { 0, 0, 255 }},
|
||||
{'22', { 0, 95, 0 }},
|
||||
{'23', { 0, 95, 95 }},
|
||||
{'24', { 0, 95, 135 }},
|
||||
{'25', { 0, 95, 175 }},
|
||||
{'26', { 0, 95, 215 }},
|
||||
{'27', { 0, 95, 255 }},
|
||||
{'28', { 0, 135, 0 }},
|
||||
{'29', { 0, 135, 95 }},
|
||||
{'30', { 0, 135, 135 }},
|
||||
{'31', { 0, 135, 175 }},
|
||||
{'32', { 0, 135, 215 }},
|
||||
{'33', { 0, 135, 255 }},
|
||||
{'34', { 0, 175, 0 }},
|
||||
{'35', { 0, 175, 95 }},
|
||||
{'36', { 0, 175, 135 }},
|
||||
{'37', { 0, 175, 175 }},
|
||||
{'38', { 0, 175, 215 }},
|
||||
{'39', { 0, 175, 255 }},
|
||||
{'40', { 0, 215, 0 }},
|
||||
{'41', { 0, 215, 95 }},
|
||||
{'42', { 0, 215, 135 }},
|
||||
{'43', { 0, 215, 175 }},
|
||||
{'44', { 0, 215, 215 }},
|
||||
{'45', { 0, 215, 255 }},
|
||||
{'46', { 0, 255, 0 }},
|
||||
{'47', { 0, 255, 95 }},
|
||||
{'48', { 0, 255, 135 }},
|
||||
{'49', { 0, 255, 175 }},
|
||||
{'50', { 0, 255, 215 }},
|
||||
{'51', { 0, 255, 255 }},
|
||||
{'52', { 95, 0, 0 }},
|
||||
{'53', { 95, 0, 95 }},
|
||||
{'54', { 95, 0, 135 }},
|
||||
{'55', { 95, 0, 175 }},
|
||||
{'56', { 95, 0, 215 }},
|
||||
{'57', { 95, 0, 255 }},
|
||||
{'58', { 95, 95, 0 }},
|
||||
{'59', { 95, 95, 95 }},
|
||||
{'60', { 95, 95, 135 }},
|
||||
{'61', { 95, 95, 175 }},
|
||||
{'62', { 95, 95, 215 }},
|
||||
{'63', { 95, 95, 255 }},
|
||||
{'64', { 95, 135, 0 }},
|
||||
{'65', { 95, 135, 95 }},
|
||||
{'66', { 95, 135, 135 }},
|
||||
{'67', { 95, 135, 175 }},
|
||||
{'68', { 95, 135, 215 }},
|
||||
{'69', { 95, 135, 255 }},
|
||||
{'70', { 95, 175, 0 }},
|
||||
{'71', { 95, 175, 95 }},
|
||||
{'72', { 95, 175, 135 }},
|
||||
{'73', { 95, 175, 175 }},
|
||||
{'74', { 95, 175, 215 }},
|
||||
{'75', { 95, 175, 255 }},
|
||||
{'76', { 95, 215, 0 }},
|
||||
{'77', { 95, 215, 95 }},
|
||||
{'78', { 95, 215, 135 }},
|
||||
{'79', { 95, 215, 175 }},
|
||||
{'80', { 95, 215, 215 }},
|
||||
{'81', { 95, 215, 255 }},
|
||||
{'82', { 95, 255, 0 }},
|
||||
{'83', { 95, 255, 95 }},
|
||||
{'84', { 95, 255, 135 }},
|
||||
{'85', { 95, 255, 175 }},
|
||||
{'86', { 95, 255, 215 }},
|
||||
{'87', { 95, 255, 255 }},
|
||||
{'88', { 135, 0, 0 }},
|
||||
{'89', { 135, 0, 95 }},
|
||||
{'90', { 135, 0, 135 }},
|
||||
{'91', { 135, 0, 175 }},
|
||||
{'92', { 135, 0, 215 }},
|
||||
{'93', { 135, 0, 255 }},
|
||||
{'94', { 135, 95, 0 }},
|
||||
{'95', { 135, 95, 95 }},
|
||||
{'96', { 135, 95, 135 }},
|
||||
{'97', { 135, 95, 175 }},
|
||||
{'98', { 135, 95, 215 }},
|
||||
{'99', { 135, 95, 255 }},
|
||||
{'100', { 135, 135, 0 }},
|
||||
{'101', { 135, 135, 95 }},
|
||||
{'102', { 135, 135, 135 }},
|
||||
{'103', { 135, 135, 175 }},
|
||||
{'104', { 135, 135, 215 }},
|
||||
{'105', { 135, 135, 255 }},
|
||||
{'106', { 135, 175, 0 }},
|
||||
{'107', { 135, 175, 95 }},
|
||||
{'108', { 135, 175, 135 }},
|
||||
{'109', { 135, 175, 175 }},
|
||||
{'110', { 135, 175, 215 }},
|
||||
{'111', { 135, 175, 255 }},
|
||||
{'112', { 135, 215, 0 }},
|
||||
{'113', { 135, 215, 95 }},
|
||||
{'114', { 135, 215, 135 }},
|
||||
{'115', { 135, 215, 175 }},
|
||||
{'116', { 135, 215, 215 }},
|
||||
{'117', { 135, 215, 255 }},
|
||||
{'118', { 135, 255, 0 }},
|
||||
{'119', { 135, 255, 95 }},
|
||||
{'120', { 135, 255, 135 }},
|
||||
{'121', { 135, 255, 175 }},
|
||||
{'122', { 135, 255, 215 }},
|
||||
{'123', { 135, 255, 255 }},
|
||||
{'124', { 175, 0, 0 }},
|
||||
{'125', { 175, 0, 95 }},
|
||||
{'126', { 175, 0, 135 }},
|
||||
{'127', { 175, 0, 175 }},
|
||||
{'128', { 175, 0, 215 }},
|
||||
{'129', { 175, 0, 255 }},
|
||||
{'130', { 175, 95, 0 }},
|
||||
{'131', { 175, 95, 95 }},
|
||||
{'132', { 175, 95, 135 }},
|
||||
{'133', { 175, 95, 175 }},
|
||||
{'134', { 175, 95, 215 }},
|
||||
{'135', { 175, 95, 255 }},
|
||||
{'136', { 175, 135, 0 }},
|
||||
{'137', { 175, 135, 95 }},
|
||||
{'138', { 175, 135, 135 }},
|
||||
{'139', { 175, 135, 175 }},
|
||||
{'140', { 175, 135, 215 }},
|
||||
{'141', { 175, 135, 255 }},
|
||||
{'142', { 175, 175, 0 }},
|
||||
{'143', { 175, 175, 95 }},
|
||||
{'144', { 175, 175, 135 }},
|
||||
{'145', { 175, 175, 175 }},
|
||||
{'146', { 175, 175, 215 }},
|
||||
{'147', { 175, 175, 255 }},
|
||||
{'148', { 175, 215, 0 }},
|
||||
{'149', { 175, 215, 95 }},
|
||||
{'150', { 175, 215, 135 }},
|
||||
{'151', { 175, 215, 175 }},
|
||||
{'152', { 175, 215, 215 }},
|
||||
{'153', { 175, 215, 255 }},
|
||||
{'154', { 175, 255, 0 }},
|
||||
{'155', { 175, 255, 95 }},
|
||||
{'156', { 175, 255, 135 }},
|
||||
{'157', { 175, 255, 175 }},
|
||||
{'158', { 175, 255, 215 }},
|
||||
{'159', { 175, 255, 255 }},
|
||||
{'160', { 215, 0, 0 }},
|
||||
{'161', { 215, 0, 95 }},
|
||||
{'162', { 215, 0, 135 }},
|
||||
{'163', { 215, 0, 175 }},
|
||||
{'164', { 215, 0, 215 }},
|
||||
{'165', { 215, 0, 255 }},
|
||||
{'166', { 215, 95, 0 }},
|
||||
{'167', { 215, 95, 95 }},
|
||||
{'168', { 215, 95, 135 }},
|
||||
{'169', { 215, 95, 175 }},
|
||||
{'170', { 215, 95, 215 }},
|
||||
{'171', { 215, 95, 255 }},
|
||||
{'172', { 215, 135, 0 }},
|
||||
{'173', { 215, 135, 95 }},
|
||||
{'174', { 215, 135, 135 }},
|
||||
{'175', { 215, 135, 175 }},
|
||||
{'176', { 215, 135, 215 }},
|
||||
{'177', { 215, 135, 255 }},
|
||||
{'178', { 215, 175, 0 }},
|
||||
{'179', { 215, 175, 95 }},
|
||||
{'180', { 215, 175, 135 }},
|
||||
{'181', { 215, 175, 175 }},
|
||||
{'182', { 215, 175, 215 }},
|
||||
{'183', { 215, 175, 255 }},
|
||||
{'184', { 215, 215, 0 }},
|
||||
{'185', { 215, 215, 95 }},
|
||||
{'186', { 215, 215, 135 }},
|
||||
{'187', { 215, 215, 175 }},
|
||||
{'188', { 215, 215, 215 }},
|
||||
{'189', { 215, 215, 255 }},
|
||||
{'190', { 215, 255, 0 }},
|
||||
{'191', { 215, 255, 95 }},
|
||||
{'192', { 215, 255, 135 }},
|
||||
{'193', { 215, 255, 175 }},
|
||||
{'194', { 215, 255, 215 }},
|
||||
{'195', { 215, 255, 255 }},
|
||||
{'196', { 255, 0, 0 }},
|
||||
{'197', { 255, 0, 95 }},
|
||||
{'198', { 255, 0, 135 }},
|
||||
{'199', { 255, 0, 175 }},
|
||||
{'200', { 255, 0, 215 }},
|
||||
{'201', { 255, 0, 255 }},
|
||||
{'202', { 255, 95, 0 }},
|
||||
{'203', { 255, 95, 95 }},
|
||||
{'204', { 255, 95, 135 }},
|
||||
{'205', { 255, 95, 175 }},
|
||||
{'206', { 255, 95, 215 }},
|
||||
{'207', { 255, 95, 255 }},
|
||||
{'208', { 255, 135, 0 }},
|
||||
{'209', { 255, 135, 95 }},
|
||||
{'210', { 255, 135, 135 }},
|
||||
{'211', { 255, 135, 175 }},
|
||||
{'212', { 255, 135, 215 }},
|
||||
{'213', { 255, 135, 255 }},
|
||||
{'214', { 255, 175, 0 }},
|
||||
{'215', { 255, 175, 95 }},
|
||||
{'216', { 255, 175, 135 }},
|
||||
{'217', { 255, 175, 175 }},
|
||||
{'218', { 255, 175, 215 }},
|
||||
{'219', { 255, 175, 255 }},
|
||||
{'220', { 255, 215, 0 }},
|
||||
{'221', { 255, 215, 95 }},
|
||||
{'222', { 255, 215, 135 }},
|
||||
{'223', { 255, 215, 175 }},
|
||||
{'224', { 255, 215, 215 }},
|
||||
{'225', { 255, 215, 255 }},
|
||||
{'226', { 255, 255, 0 }},
|
||||
{'227', { 255, 255, 95 }},
|
||||
{'228', { 255, 255, 135 }},
|
||||
{'229', { 255, 255, 175 }},
|
||||
{'230', { 255, 255, 215 }},
|
||||
{'231', { 255, 255, 255 }},
|
||||
|
||||
-- Gray-scale range.
|
||||
{'232', { 8, 8, 8 }},
|
||||
{'233', { 18, 18, 18 }},
|
||||
{'234', { 28, 28, 28 }},
|
||||
{'235', { 38, 38, 38 }},
|
||||
{'236', { 48, 48, 48 }},
|
||||
{'237', { 58, 58, 58 }},
|
||||
{'238', { 68, 68, 68 }},
|
||||
{'239', { 78, 78, 78 }},
|
||||
{'240', { 88, 88, 88 }},
|
||||
{'241', { 98, 98, 98 }},
|
||||
{'242', { 108, 108, 108 }},
|
||||
{'243', { 118, 118, 118 }},
|
||||
{'244', { 128, 128, 128 }},
|
||||
{'245', { 138, 138, 138 }},
|
||||
{'246', { 148, 148, 148 }},
|
||||
{'247', { 158, 158, 158 }},
|
||||
{'248', { 168, 168, 168 }},
|
||||
{'249', { 178, 178, 178 }},
|
||||
{'250', { 188, 188, 188 }},
|
||||
{'251', { 198, 198, 198 }},
|
||||
{'252', { 208, 208, 208 }},
|
||||
{'253', { 218, 218, 218 }},
|
||||
{'254', { 228, 228, 228 }},
|
||||
{'255', { 238, 238, 238 }},
|
||||
}
|
||||
-- stylua: ignore end
|
||||
|
||||
---converts #rrggbb formatted color to cterm ('0'-'255') color
|
||||
---@param hex_color string
|
||||
---@return string
|
||||
function M.rgb2cterm(hex_color)
|
||||
if hex_color == 'None' then
|
||||
return 'None'
|
||||
end
|
||||
local function get_color_distance(color1, color2)
|
||||
-- returns how much color2 deviates from color1
|
||||
local dr = math.abs(color1[1] - color2[1]) / (color1[1] + 1) * 100
|
||||
local dg = math.abs(color1[2] - color2[2]) / (color1[2] + 1) * 100
|
||||
local db = math.abs(color1[3] - color2[3]) / (color1[3] + 1) * 100
|
||||
return (dr + dg + db)
|
||||
end
|
||||
|
||||
local r = tonumber(hex_color:sub(2, 3), 16)
|
||||
local g = tonumber(hex_color:sub(4, 5), 16)
|
||||
local b = tonumber(hex_color:sub(6, 7), 16)
|
||||
|
||||
-- check which cterm color is closest to hex colors in terms of rgb values
|
||||
local closest_cterm_color = 0
|
||||
local min_distance = 10000
|
||||
for _, color in ipairs(color_table) do
|
||||
local current_distance = get_color_distance(color[2], { r, g, b })
|
||||
if current_distance < min_distance then
|
||||
min_distance = current_distance
|
||||
closest_cterm_color = color[1]
|
||||
end
|
||||
end
|
||||
return closest_cterm_color
|
||||
end
|
||||
|
||||
---converts color name (only ones supported by neovim) formatted colors to #rrggbb
|
||||
---@param name string like red,green,grey
|
||||
---@return string
|
||||
function M.color_name2rgb(name)
|
||||
local color_val = vim.api.nvim_get_color_by_name(name)
|
||||
if color_val == -1 then
|
||||
return '#' .. name -- Assuming it's 'rrggbb' without # not rad instead of red
|
||||
end
|
||||
return string.format('#%06x', color_val)
|
||||
end
|
||||
|
||||
---converts cterm(0-255) to #rrggbb
|
||||
---@param color number
|
||||
---@return string
|
||||
function M.cterm2rgb(color)
|
||||
local color_data = color_table[color + 1]
|
||||
if color_data ~= nil then
|
||||
color_data = color_data[2]
|
||||
return string.format('#%02x%02x%02x', color_data[1], color_data[2], color_data[3])
|
||||
end
|
||||
end
|
||||
|
||||
return M
|
||||
@ -0,0 +1,38 @@
|
||||
local M = {}
|
||||
local fns = {}
|
||||
|
||||
---Store fn with id in fns so it can be later called
|
||||
---@param id integer component id (for now we are only doing one fn per component)
|
||||
---@param fn function the actual function to store.
|
||||
---@return number same id that was provided.
|
||||
function M.register_fn(id, fn)
|
||||
vim.validate {
|
||||
id = { id, 'n' },
|
||||
fn = { fn, 'f' },
|
||||
}
|
||||
fns[id] = fn
|
||||
return id
|
||||
end
|
||||
|
||||
---Get the function with id
|
||||
---@param id number id of the fn to retrieve
|
||||
---@return function
|
||||
function M.get_fn(id)
|
||||
vim.validate { id = { id, 'n' } }
|
||||
return fns[id] or function() end
|
||||
end
|
||||
|
||||
---Call the function of id with args
|
||||
---@param id number
|
||||
---@param ... any
|
||||
---@return any
|
||||
function M.call_fn(id, ...)
|
||||
return M.get_fn(id)(...)
|
||||
end
|
||||
|
||||
---Clear the fns table
|
||||
function M.clear_fns()
|
||||
fns = {}
|
||||
end
|
||||
|
||||
return M
|
||||
@ -0,0 +1,54 @@
|
||||
-- Copyright (c) 2020-2021 shadmansaleh
|
||||
-- MIT license, see LICENSE for more details.
|
||||
|
||||
--- wrapper around job api
|
||||
--- creates a job handler when called
|
||||
local Job = setmetatable({
|
||||
--- start the job
|
||||
start = function(self)
|
||||
self.job_id = vim.fn.jobstart(self.args.cmd, self.args)
|
||||
return self.job_id > 0
|
||||
end,
|
||||
--- stop the job. Also immediately disables io from the job.
|
||||
stop = function(self)
|
||||
if self.killed then
|
||||
return
|
||||
end
|
||||
if self.job_id and self.job_id > 0 then
|
||||
vim.fn.jobstop(self.job_id)
|
||||
end
|
||||
self.job_id = 0
|
||||
self.killed = true
|
||||
end,
|
||||
-- Wraps callbacks so they are only called when job is alive
|
||||
-- This avoids race conditions
|
||||
wrap_cb_alive = function(self, name)
|
||||
local original_cb = self.args[name]
|
||||
if original_cb then
|
||||
self.args[name] = function(...)
|
||||
if not self.killed then
|
||||
return original_cb(...)
|
||||
end
|
||||
end
|
||||
end
|
||||
end,
|
||||
}, {
|
||||
---create new job handler
|
||||
---@param self table base job table
|
||||
---@param args table same args as jobstart except cmd is also passed in part of it
|
||||
---@return table new job handler
|
||||
__call = function(self, args)
|
||||
args = vim.deepcopy(args or {})
|
||||
if type(args.cmd) == 'string' then
|
||||
args.cmd = vim.split(args.cmd, ' ')
|
||||
end
|
||||
self.__index = self
|
||||
local job = setmetatable({ args = args }, self)
|
||||
job:wrap_cb_alive('on_stdout')
|
||||
job:wrap_cb_alive('on_stderr')
|
||||
job:wrap_cb_alive('on_stdin')
|
||||
return job
|
||||
end,
|
||||
})
|
||||
|
||||
return Job
|
||||
@ -0,0 +1,257 @@
|
||||
-- Copyright (c) 2020-2021 hoob3rt
|
||||
-- MIT license, see LICENSE for more details.
|
||||
|
||||
local lualine_require = require('lualine_require')
|
||||
local require = lualine_require.require
|
||||
local modules = lualine_require.lazy_require {
|
||||
utils = 'lualine.utils.utils',
|
||||
notice = 'lualine.utils.notices',
|
||||
fn_store = 'lualine.utils.fn_store',
|
||||
}
|
||||
local is_valid_filename = lualine_require.is_valid_filename
|
||||
local sep = lualine_require.sep
|
||||
|
||||
--- function that loads specific type of component
|
||||
local component_types = {
|
||||
-- loads custom component
|
||||
custom = function(component)
|
||||
return component[1](component)
|
||||
end,
|
||||
--- loads lua functions as component
|
||||
lua_fun = function(component)
|
||||
return require('lualine.components.special.function_component')(component)
|
||||
end,
|
||||
--- loads lua modules as components (ones in /lua/lualine/components/)
|
||||
mod = function(component)
|
||||
local ok, loaded_component = pcall(require, 'lualine.components.' .. component[1])
|
||||
if ok then
|
||||
component.component_name = component[1]
|
||||
if type(loaded_component) == 'table' then
|
||||
loaded_component = loaded_component(component)
|
||||
elseif type(loaded_component) == 'function' then
|
||||
component[1] = loaded_component
|
||||
loaded_component = require('lualine.components.special.function_component')(component)
|
||||
end
|
||||
return loaded_component
|
||||
end
|
||||
end,
|
||||
--- loads builtin statusline patterns as component
|
||||
stl = function(component)
|
||||
local stl_expr = component[1] -- Vim's %p %l statusline elements
|
||||
component[1] = function()
|
||||
return stl_expr
|
||||
end
|
||||
return require('lualine.components.special.function_component')(component)
|
||||
end,
|
||||
--- loads variables & options (g:,go:,b:,bo:...) as components
|
||||
var = function(component)
|
||||
return require('lualine.components.special.vim_var_component')(component)
|
||||
end,
|
||||
--- loads vim functions and lua expressions as components
|
||||
['_'] = function(component)
|
||||
return require('lualine.components.special.eval_func_component')(component)
|
||||
end,
|
||||
}
|
||||
|
||||
---load a component from component config
|
||||
---@param component table component + component options
|
||||
---@return table the loaded & initialized component
|
||||
local function component_loader(component)
|
||||
if type(component[1]) == 'function' then
|
||||
return component_types.lua_fun(component)
|
||||
elseif type(component[1]) == 'string' then
|
||||
-- load the component
|
||||
if component.type ~= nil then
|
||||
if component_types[component.type] and component.type ~= 'lua_fun' then
|
||||
return component_types[component.type](component)
|
||||
elseif component.type == 'vim_fun' or component.type == 'lua_expr' then
|
||||
return component_types['_'](component)
|
||||
else
|
||||
modules.notice.add_notice(string.format(
|
||||
[[
|
||||
### component.type
|
||||
|
||||
component type '%s' isn't recognised. Check if spelling is correct.]],
|
||||
component.type
|
||||
))
|
||||
end
|
||||
end
|
||||
local loaded_component = component_types.mod(component)
|
||||
if loaded_component then
|
||||
return loaded_component
|
||||
elseif string.char(component[1]:byte(1)) == '%' then
|
||||
return component_types.stl(component)
|
||||
elseif component[1]:find('[gvtwb]?o?:') == 1 then
|
||||
return component_types.var(component)
|
||||
else
|
||||
return component_types['_'](component)
|
||||
end
|
||||
elseif type(component[1]) == 'table' then
|
||||
return component_types.custom(component)
|
||||
end
|
||||
end
|
||||
|
||||
--- Shows notice about invalid types passed as component
|
||||
--- @param index number the index of component in section table
|
||||
--- @param component table containing component elements
|
||||
--- return bool whether check passed or not
|
||||
local function is_valid_component_type(index, component)
|
||||
if type(component_types) == 'table' and type(index) == 'number' then
|
||||
return true
|
||||
end
|
||||
modules.notice.add_notice(string.format(
|
||||
[[
|
||||
### Unrecognized component
|
||||
Only functions, strings and tables can be used as component.
|
||||
You seem to have a `%s` as component indexed as `%s`.
|
||||
Something like:
|
||||
```lua
|
||||
%s = %s,
|
||||
```
|
||||
|
||||
This commonly occurs when you forget to pass table with option for component.
|
||||
When a component has option that component needs to be a table which holds
|
||||
the component as first element and the options as key value pairs.
|
||||
For example:
|
||||
```lua
|
||||
lualine_c = {
|
||||
{'diagnostics',
|
||||
sources = {'nvim'},
|
||||
}
|
||||
}
|
||||
```
|
||||
Notice the inner extra {} surrounding the component and it's options.
|
||||
Make sure your config follows this.
|
||||
]],
|
||||
type(component),
|
||||
index,
|
||||
index,
|
||||
vim.inspect(component)
|
||||
))
|
||||
return false
|
||||
end
|
||||
|
||||
---loads all the section from a config
|
||||
---@param sections table list of sections
|
||||
---@param options table global options table
|
||||
local function load_sections(sections, options)
|
||||
for section_name, section in pairs(sections) do
|
||||
for index, component in pairs(section) do
|
||||
if (type(component) == 'string' or type(component) == 'function') or modules.utils.is_component(component) then
|
||||
component = { component }
|
||||
end
|
||||
if is_valid_component_type(index, component) then
|
||||
component.self = {}
|
||||
component.self.section = section_name:match('lualine_(.*)')
|
||||
-- apply default args
|
||||
component = vim.tbl_extend('keep', component, options)
|
||||
section[index] = component_loader(component)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
---loads all the configs (active, inactive, tabline)
|
||||
---@param config table user config
|
||||
local function load_components(config)
|
||||
local sec_names = { 'sections', 'inactive_sections', 'tabline', 'winbar', 'inactive_winbar' }
|
||||
for _, section in ipairs(sec_names) do
|
||||
load_sections(config[section], config.options)
|
||||
end
|
||||
end
|
||||
|
||||
---loads all the extensions
|
||||
---@param config table user config
|
||||
local function load_extensions(config)
|
||||
local loaded_extensions = {}
|
||||
local sec_names = { 'sections', 'inactive_sections', 'winbar', 'inactive_winbar' }
|
||||
for _, extension in pairs(config.extensions) do
|
||||
if type(extension) == 'string' then
|
||||
local ok
|
||||
ok, extension = pcall(require, 'lualine.extensions.' .. extension)
|
||||
if not ok then
|
||||
modules.notice.add_notice(string.format(
|
||||
[[
|
||||
### Extensions
|
||||
Extension named `%s` was not found . Check if spelling is correct.
|
||||
]],
|
||||
extension
|
||||
))
|
||||
end
|
||||
end
|
||||
if type(extension) == 'table' then
|
||||
local local_extension = modules.utils.deepcopy(extension)
|
||||
for _, section in ipairs(sec_names) do
|
||||
if local_extension[section] then
|
||||
load_sections(local_extension[section], config.options)
|
||||
end
|
||||
end
|
||||
if type(local_extension.init) == 'function' then
|
||||
local_extension.init()
|
||||
end
|
||||
table.insert(loaded_extensions, local_extension)
|
||||
end
|
||||
end
|
||||
config.extensions = loaded_extensions
|
||||
end
|
||||
|
||||
---loads sections and extensions or entire user config
|
||||
---@param config table user config
|
||||
local function load_all(config)
|
||||
require('lualine.component')._reset_components()
|
||||
modules.fn_store.clear_fns()
|
||||
require('lualine.utils.nvim_opts').reset_cache()
|
||||
load_components(config)
|
||||
load_extensions(config)
|
||||
end
|
||||
|
||||
---loads a theme from lua module
|
||||
---prioritizes external themes (from user config or other plugins) over the bundled ones
|
||||
---@param theme_name string
|
||||
---@return table theme definition from module
|
||||
local function load_theme(theme_name)
|
||||
assert(is_valid_filename(theme_name), 'Invalid filename')
|
||||
local retval
|
||||
local path = table.concat { 'lua/lualine/themes/', theme_name, '.lua' }
|
||||
local files = vim.api.nvim_get_runtime_file(path, true)
|
||||
if #files <= 0 then
|
||||
path = table.concat { 'lua/lualine/themes/', theme_name, '/init.lua' }
|
||||
files = vim.api.nvim_get_runtime_file(path, true)
|
||||
end
|
||||
local n_files = #files
|
||||
if n_files == 0 then
|
||||
-- No match found
|
||||
error(path .. ' Not found')
|
||||
elseif n_files == 1 then
|
||||
-- when only one is found run that and return it's return value
|
||||
retval = dofile(files[1])
|
||||
else
|
||||
-- put entries from user config path in front
|
||||
local user_config_path = vim.fn.stdpath('config')
|
||||
table.sort(files, function(a, b)
|
||||
local pattern = table.concat { user_config_path, sep }
|
||||
return string.match(a, pattern) or not string.match(b, pattern)
|
||||
end)
|
||||
-- More then 1 found . Use the first one that isn't in lualines repo
|
||||
local lualine_repo_pattern = table.concat({ 'lualine.nvim', 'lua', 'lualine' }, sep)
|
||||
local file_found = false
|
||||
for _, file in ipairs(files) do
|
||||
if not file:find(lualine_repo_pattern) then
|
||||
retval = dofile(file)
|
||||
file_found = true
|
||||
break
|
||||
end
|
||||
end
|
||||
if not file_found then
|
||||
-- This shouldn't happen but somehow we have multiple files but they
|
||||
-- appear to be in lualines repo . Just run the first one
|
||||
retval = dofile(files[1])
|
||||
end
|
||||
end
|
||||
return retval
|
||||
end
|
||||
|
||||
return {
|
||||
load_all = load_all,
|
||||
load_theme = load_theme,
|
||||
}
|
||||
@ -0,0 +1,54 @@
|
||||
-- Copyright (c) 2020-2021 hoob3rt
|
||||
-- MIT license, see LICENSE for more details.
|
||||
local Mode = {}
|
||||
|
||||
-- stylua: ignore
|
||||
Mode.map = {
|
||||
['n'] = 'NORMAL',
|
||||
['no'] = 'O-PENDING',
|
||||
['nov'] = 'O-PENDING',
|
||||
['noV'] = 'O-PENDING',
|
||||
['no\22'] = 'O-PENDING',
|
||||
['niI'] = 'NORMAL',
|
||||
['niR'] = 'NORMAL',
|
||||
['niV'] = 'NORMAL',
|
||||
['nt'] = 'NORMAL',
|
||||
['ntT'] = 'NORMAL',
|
||||
['v'] = 'VISUAL',
|
||||
['vs'] = 'VISUAL',
|
||||
['V'] = 'V-LINE',
|
||||
['Vs'] = 'V-LINE',
|
||||
['\22'] = 'V-BLOCK',
|
||||
['\22s'] = 'V-BLOCK',
|
||||
['s'] = 'SELECT',
|
||||
['S'] = 'S-LINE',
|
||||
['\19'] = 'S-BLOCK',
|
||||
['i'] = 'INSERT',
|
||||
['ic'] = 'INSERT',
|
||||
['ix'] = 'INSERT',
|
||||
['R'] = 'REPLACE',
|
||||
['Rc'] = 'REPLACE',
|
||||
['Rx'] = 'REPLACE',
|
||||
['Rv'] = 'V-REPLACE',
|
||||
['Rvc'] = 'V-REPLACE',
|
||||
['Rvx'] = 'V-REPLACE',
|
||||
['c'] = 'COMMAND',
|
||||
['cv'] = 'EX',
|
||||
['ce'] = 'EX',
|
||||
['r'] = 'REPLACE',
|
||||
['rm'] = 'MORE',
|
||||
['r?'] = 'CONFIRM',
|
||||
['!'] = 'SHELL',
|
||||
['t'] = 'TERMINAL',
|
||||
}
|
||||
|
||||
---@return string current mode name
|
||||
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
|
||||
@ -0,0 +1,91 @@
|
||||
-- Copyright (c) 2020-2021 shadmansaleh
|
||||
-- MIT license, see LICENSE for more details.
|
||||
|
||||
-- To provide notices for user
|
||||
local M = {}
|
||||
local notices = {}
|
||||
local persistent_notices = {}
|
||||
|
||||
---append new notice
|
||||
---@param notice string|table table is a list of strings
|
||||
function M.add_notice(notice)
|
||||
if type(notice) == 'string' then
|
||||
notice = vim.split(notice, '\n')
|
||||
end
|
||||
if notice[#notice] ~= '' then
|
||||
notice[#notice + 1] = ''
|
||||
end
|
||||
table.insert(notices, notice)
|
||||
end
|
||||
|
||||
---appends persistent notice. These don't get cleared on setup
|
||||
---@param notice string|table table is a list of strings
|
||||
function M.add_persistent_notice(notice)
|
||||
if type(notice) == 'string' then
|
||||
notice = vim.split(notice, '\n')
|
||||
end
|
||||
if not vim.tbl_contains(persistent_notices, notice) then
|
||||
table.insert(persistent_notices, notice)
|
||||
end
|
||||
end
|
||||
|
||||
---show setup :LuaLineNotices and show notification about error when there
|
||||
---are notices available
|
||||
local notify_done = false
|
||||
function M.notice_message_startup()
|
||||
notify_done = false
|
||||
vim.defer_fn(function()
|
||||
if notify_done then
|
||||
return
|
||||
end
|
||||
if #notices > 0 or #persistent_notices > 0 then
|
||||
vim.cmd('command! -nargs=0 LualineNotices lua require"lualine.utils.notices".show_notices()')
|
||||
vim.notify(
|
||||
'lualine: There are some issues with your config. Run :LualineNotices for details',
|
||||
vim.log.levels.WARN,
|
||||
{}
|
||||
)
|
||||
end
|
||||
notify_done = true
|
||||
end, 2000)
|
||||
end
|
||||
|
||||
---create notice view
|
||||
function M.show_notices()
|
||||
vim.cmd('silent! keepalt split')
|
||||
|
||||
local winid = vim.api.nvim_get_current_win()
|
||||
local bufnr = vim.api.nvim_create_buf(false, true)
|
||||
vim.api.nvim_win_set_buf(winid, bufnr)
|
||||
|
||||
vim.wo[winid].winfixheight = true
|
||||
vim.wo[winid].winfixwidth = true
|
||||
vim.wo[winid].number = false
|
||||
vim.wo[winid].foldcolumn = '0'
|
||||
vim.wo[winid].relativenumber = false
|
||||
vim.wo[winid].signcolumn = 'no'
|
||||
vim.bo[bufnr].filetype = 'markdown'
|
||||
|
||||
vim.api.nvim_buf_set_keymap(bufnr, 'n', 'q', '<Cmd>bd<CR>', { noremap = true, silent = true })
|
||||
|
||||
local ok, _ = pcall(vim.api.nvim_buf_set_name, 0, 'Lualine Notices')
|
||||
if not ok then
|
||||
vim.notify('Lualine Notices is already open in another buffer', vim.log.levels.ERROR, {})
|
||||
vim.cmd('normal q')
|
||||
return
|
||||
end
|
||||
local notice = vim.tbl_flatten(persistent_notices)
|
||||
notice = vim.list_extend(notice, vim.tbl_flatten(notices))
|
||||
vim.fn.appendbufline(bufnr, 0, notice)
|
||||
|
||||
vim.fn.deletebufline(bufnr, #notice, vim.fn.line('$'))
|
||||
vim.api.nvim_win_set_cursor(winid, { 1, 0 })
|
||||
vim.bo[bufnr].modified = false
|
||||
vim.bo[bufnr].modifiable = false
|
||||
end
|
||||
|
||||
function M.clear_notices()
|
||||
notices = {}
|
||||
end
|
||||
|
||||
return M
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user