doc: improve code documentation (#82)

This commit is contained in:
Shadman 2021-10-12 20:04:47 +06:00 committed by GitHub
parent babc57c62b
commit 08d1340ec9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 354 additions and 98 deletions

View File

@ -13,6 +13,10 @@ local config -- Stores cureently applied config
local new_config = true -- Stores config that will be applied
-- Helper for apply_transitional_separators()
--- finds first applied highlight group fter str_checked in status
---@param status string : unprossed 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)
@ -32,6 +36,12 @@ local function find_next_hl(status, str_checked)
end
-- Helper for apply_transitional_separators()
--- applies transitional separator highlight + transitional separator
---@param status string : unprossed 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 concated separator highlight and transitional separator
local function fill_section_separator(status, str_checked, last_hl, sep, reverse)
-- Inserts transitional separator along with transitional highlight
local next_hl = find_next_hl(status, str_checked)
@ -52,6 +62,10 @@ local function fill_section_separator(status, str_checked, last_hl, sep, reverse
end
end
--- processes statusline string
--- replaces %s/S{sep} with proper left/right separator highlight + sep
---@param status string : unprossed statusline string
---@return string : processed statusline string
local function apply_transitional_separators(status)
local status_applied = {} -- Collects all the pieces for concatation
local last_hl -- Stores lash highligjt group that we found
@ -122,6 +136,11 @@ local function apply_transitional_separators(status)
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 evsluated for focused window or not
---@return string statusline string
local function statusline(sections, is_focused)
-- The sequence sections should maintain [SECTION_SEQUENCE]
local section_sequence = { 'a', 'b', 'c', 'x', 'y', 'z' }
@ -156,7 +175,14 @@ local function statusline(sections, is_focused)
return apply_transitional_separators(table.concat(status))
end
-- check if any extension matches the filetype and return proper sections
--- 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 evsluated for focused window or not
---@return table : (section_table) section config where components are replaced with
--- component objects
-- TODO: change this so it uses a hash table instead of iteration over lisr
-- to improve redraws. Add buftype / bufname for extensions
-- or some kind of cond ?
local function get_extension_sections(current_ft, is_focused)
for _, extension in ipairs(config.extensions) do
for _, filetype in ipairs(extension.filetypes) do
@ -171,6 +197,7 @@ local function get_extension_sections(current_ft, is_focused)
return nil
end
---@return string statusline string for tabline
local function tabline()
return statusline(config.tabline, true)
end
@ -191,6 +218,13 @@ 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 option for theme if it's a string loads theme of that name
--- if it's a table directlybuses it .
--- when theme load fails this fallsback to 'auto' theme if even that fails
--- this falls back to 'gruvbox' theme
--- also sets up auto command to reload lualine on ColorScheme or background
--- change on
local function setup_theme()
local function get_theme_from_config()
local theme_name = config.options.theme
@ -219,6 +253,7 @@ local function setup_theme()
autocmd lualine OptionSet background lua require'lualine'.setup()]]
end
--- Sets &tabline option to lualine
local function set_tabline()
if next(config.tabline) ~= nil then
vim.go.tabline = "%{%v:lua.require'lualine'.tabline()%}"
@ -226,6 +261,8 @@ local function set_tabline()
end
end
--- Sets &ststusline option to lualine
--- adds auto command to redraw lualine on VimResized event
local function set_statusline()
if next(config.sections) ~= nil or next(config.inactive_sections) ~= nil then
vim.cmd 'autocmd lualine VimResized * redrawstatus'
@ -234,16 +271,15 @@ local function set_statusline()
end
end
local function setup_augroup()
vim.cmd [[augroup lualine | autocmd! | augroup END]]
end
--- reloads lualine using new_config
local function reset_lualine()
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
setup_augroup()
vim.cmd [[augroup lualine | autocmd! | augroup END]]
setup_theme()
-- load components & extensions
modules.loader.load_all(config)
set_statusline()
set_tabline()
@ -253,33 +289,50 @@ local function reset_lualine()
new_config = nil
end
-- lualine.statusline function
--- Draw correct statusline for current winwow
---@param focused boolean : force the vale of is_focuased . useful for debugginf
---@return string statusline string
local function status_dispatch(focused)
-- disable on specific filetypes
local retval
if new_config then
-- reload lualine when config was changed
reset_lualine()
end
local current_ft = vim.bo.filetype
local is_focused = focused ~= nil and focused or modules.utils.is_focused()
for _, ft in pairs(config.options.disabled_filetypes) do
-- disable on specific filetypes
if ft == current_ft then
vim.wo.statusline = ''
return ''
end
end
local extension_sections = get_extension_sections(current_ft, is_focused)
if is_focused then
if extension_sections ~= nil then
return statusline(extension_sections, is_focused)
retval = statusline(extension_sections, is_focused)
else
retval = statusline(config.sections, is_focused)
end
return statusline(config.sections, is_focused)
else
if extension_sections ~= nil then
return statusline(extension_sections, is_focused)
retval = statusline(extension_sections, is_focused)
else
retval = statusline(config.inactive_sections, is_focused)
end
return statusline(config.inactive_sections, is_focused)
end
return retval
end
-- lualine.setup function
--- sets new user config
--- This function doesn't load components/theme etc.. they are done before
--- first statusline redraw after new config. This is more efficient when
--- lualine config is done in several setup calls in chunks. This way
--- we don't intialize components just to throgh them away .Instead they are
--- initialized when we know we will use them.
--- sets &last_status tl 2
---@param user_config table table
local function setup(user_config)
new_config = true
config = modules.config_module.apply_configuration(user_config)

View File

@ -7,6 +7,9 @@ local M = require('lualine.utils.class'):extend()
-- Used to provide a unique id for each component
local component_no = 1
-- variable to store component output for manipulation
M.status = ''
function M:__tostring()
local str = 'Component: ' .. self.options.component_name
if self.debug then
@ -15,7 +18,8 @@ function M:__tostring()
return str
end
-- Initialize new component
---initialize new component
---@param options table options for component
function M:init(options)
self.options = options or {}
component_no = component_no + 1
@ -27,6 +31,8 @@ function M:init(options)
self:create_option_highlights()
end
---sets the default separator for component based on whether the component
---is in left sections or right sections when separator option is omited.
function M:set_separator()
if self.options.separator == nil then
if self.options.component_separators then
@ -39,6 +45,7 @@ function M:set_separator()
end
end
---creates hl group from color option
function M:create_option_highlights()
-- set custom highlights
if self.options.color then
@ -50,7 +57,7 @@ function M:create_option_highlights()
end
end
-- Adds spaces to left and right of a component
---adds spaces to left and right of a component
function M:apply_padding()
local padding = self.options.padding
local l_padding, r_padding
@ -77,7 +84,7 @@ function M:apply_padding()
end
end
-- Applies custom highlights for component
---applies custom highlights for component
function M:apply_highlights(default_highlight)
if self.options.color_highlight then
self.status = highlight.component_format_highlight(self.options.color_highlight) .. self.status
@ -97,15 +104,15 @@ function M:apply_highlights(default_highlight)
end
end
-- Apply icon in front of component
---apply icon in front of component (prepemds component with icon)
function M:apply_icon()
if self.options.icons_enabled and self.options.icon then
self.status = self.options.icon .. ' ' .. self.status
end
end
-- Apply separator at end of component only when
-- custom highlights haven't affected background
---apply separator 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
@ -125,6 +132,7 @@ function M:apply_separator()
end
end
---apply transitional separator for the component
function M:apply_section_separators()
if type(self.options.separator) ~= 'table' then
return
@ -138,6 +146,8 @@ function M:apply_section_separators()
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 = ''
@ -147,14 +157,12 @@ function M:strip_separator()
return self.status
end
-- variable to store component output for manipulation
M.status = ''
-- Actual function that updates a component. Must be overwritten with component functionality
-- 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
---driver code of the class
function M:draw(default_highlight, is_focused)
self.status = ''
self.applied_separator = ''

View File

@ -16,7 +16,8 @@ local sep = package.config:sub(1, 1)
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 veriable to branch name or commit hash if not on branch
---sets git_branch veriable 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
@ -32,7 +33,7 @@ local function get_git_head(head_file)
return nil
end
-- Update branch
---update the current value of git_branch and setup file watch on HEAD file
local function update_branch()
active_bufnr = tostring(vim.fn.bufnr())
file_changed:stop()
@ -55,7 +56,9 @@ local function update_branch()
branch_cache[vim.fn.bufnr()] = current_git_branch
end
-- returns full path to git directory for dir_path or current directory
---returns full path to git directory for dir_path or current directory
---@param dir_path string|nil
---@return string
function M.find_git_dir(dir_path)
-- get file dir so we can search from that dir
local file_dir = dir_path or vim.fn.expand '%:p:h'
@ -103,6 +106,7 @@ function M.find_git_dir(dir_path)
return git_dir
end
---initialize git_branch ,odule
function M.init()
-- run watch head on load so branch is present when component is loaded
M.find_git_dir()

View File

@ -1,7 +1,8 @@
local highlight = require 'lualine.highlight'
local Buffer = require('lualine.utils.class'):extend()
---intialize a new buffer from opts
---@param opts table
function Buffer:init(opts)
assert(opts.bufnr, 'Cannot create Buffer without bufnr')
self.bufnr = opts.bufnr
@ -10,6 +11,7 @@ function Buffer:init(opts)
self:get_props()
end
---setup icons, modified status for buffer
function Buffer:get_props()
self.file = vim.fn.bufname(self.bufnr)
self.buftype = vim.api.nvim_buf_get_option(self.bufnr, 'buftype')
@ -40,21 +42,25 @@ function Buffer:get_props()
self.icon = dev .. ' '
end
end
return self
end
---returns rendered buffer
---@return string
function Buffer:render()
local name
if self.ellipse then
if self.ellipse then -- show elipsis
name = '...'
else
name = string.format(' %s%s%s ', self.icon, self:name(), self.modified_icon)
end
self.len = vim.fn.strchars(name)
-- setup for mouse clicks
local line = string.format('%%%s@LualineSwitchBuffer@%s%%T', self.bufnr, name)
-- apply highlight
line = highlight.component_format_highlight(self.highlights[(self.current and 'active' or 'inactive')]) .. line
-- apply separators
if self.options.self.section < 'lualine_x' and not self.first then
local sep_before = self:separator_before()
line = sep_before .. line
@ -67,6 +73,8 @@ function Buffer:render()
return line
end
---apply separator before current buffer
---@return string
function Buffer:separator_before()
if self.current or self.aftercurrent then
return '%S{' .. self.options.section_separators.left .. '}'
@ -75,6 +83,8 @@ function Buffer:separator_before()
end
end
---apply separator after current buffer
---@return string
function Buffer:separator_after()
if self.current or self.beforecurrent then
return '%s{' .. self.options.section_separators.right .. '}'
@ -83,6 +93,8 @@ function Buffer:separator_after()
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]

View File

@ -22,6 +22,11 @@ local default_options = {
},
}
-- 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 '_normal' or '_inactive'
local section_redirects = {
@ -66,6 +71,8 @@ function M:update_status()
end
local current_bufnr = vim.fn.bufnr()
local current = -2
-- mark the first, last, current, before current, after current buffers
-- for rendering
if buffers[1] then
buffers[1].first = true
end
@ -95,6 +102,8 @@ function M:update_status()
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 = Buffer { bufnr = vim.fn.bufnr(), options = self.options, highlights = self.highlights }
b.current = true
@ -127,24 +136,26 @@ function M:update_status()
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
end
if total_length > max_length then
break
end
if before then
table.insert(data, 1, rendered_before)
end
if after then
if total_length > max_length then
break
end
data[#data + 1] = rendered_after
end
end
-- draw elipsis (...) on relevent sides if all buffers don't fit in max_length
if total_length > max_length then
if before ~= nil then
before.ellipse = true

View File

@ -2,6 +2,7 @@ local require = require('lualine_require').require
local utils = require 'lualine.utils.utils'
local M = {}
-- default symbols for diagnostics component
M.symbols = {
icons = {
error = '', -- xf659
@ -12,6 +13,7 @@ M.symbols = {
no_icons = { error = 'E:', warn = 'W:', info = 'I:', hint = 'H:' },
}
-- default options for diagnostics component
M.options = {
colored = true,
update_in_insert = false,

View File

@ -69,6 +69,7 @@ function M:update_status()
end
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
@ -82,6 +83,7 @@ function M:update_status()
info = info_count,
hint = hint_count,
}
-- format the counts with symbols and highlights
if self.options.colored then
local colors = {}
for name, hl in pairs(self.highlight_groups) do

View File

@ -1,5 +1,8 @@
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 = vim.lsp.diagnostic.get_count(0, 'Error')
@ -45,6 +48,9 @@ M.sources = {
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

View File

@ -17,7 +17,8 @@ local diff_job = nil
local active_bufnr = '0'
local diff_cache = {} -- Stores last known value of diff of a buffer
-- initialize the module
---initialize the module
---param opts table
function M.init(opts)
if type(opts.source) == 'function' then
M.src = opts.source
@ -28,14 +29,15 @@ function M.init(opts)
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 }
---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]
@ -52,7 +54,8 @@ function M.get_sign_count(bufnr)
return git_diff
end
-- process diff data and update git_diff{ added, removed, modified }
---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
@ -79,7 +82,7 @@ local function process_diff(data)
git_diff = { added = added, modified = modified, removed = removed }
end
-- Updates the job args
---updates the job args
function M.update_diff_args()
-- Donn't show git diff when current buffer doesn't have a filename
active_bufnr = tostring(vim.fn.bufnr())
@ -118,7 +121,7 @@ function M.update_diff_args()
M.update_git_diff()
end
-- Update git_diff veriable
---update git_diff veriable
function M.update_git_diff()
if M.diff_args then
diff_output_cache = {}

View File

@ -9,10 +9,18 @@ local default_options = {
shorting_target = 40,
}
---counts how many times pattern occur in base ( used for counting path-sep )
---@param base string
---@param pattern string
---@return number
local function count(base, pattern)
return select(2, string.gsub(base, pattern, ''))
end
---shortens path by turning apple/orange -> a/orange
---@param path string
---@param sep string path separator
---@return string
local function shorten_path(path, sep)
-- ('([^/])[^/]+%/', '%1/', 1)
return path:gsub(string.format('([^%s])[^%s]+%%%s', sep, sep, sep), '%1' .. sep, 1)

View File

@ -23,12 +23,18 @@ function M:update_status()
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, {})

View File

@ -14,6 +14,11 @@ local default_options = {
},
}
-- 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 '_normal' or '_inactive'
local section_redirects = {
@ -55,6 +60,8 @@ function M:update_status()
for t = 1, vim.fn.tabpagenr '$' do
tabs[#tabs + 1] = Tab { tabnr = t, 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
@ -79,7 +86,9 @@ function M:update_status()
end
end
local current_tab = tabs[current]
if current_tab == nil then
-- 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 redundent code
local t = Tab { tabnr = vim.fn.tabpagenr(), options = self.options, highlights = self.highlights }
t.current = true
t.last = true
@ -97,6 +106,7 @@ function M:update_status()
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
@ -105,6 +115,7 @@ function M:update_status()
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
@ -114,6 +125,7 @@ function M:update_status()
data[#data + 1] = rendered_after
end
end
-- draw elipsis (...) on relevent sides if all tabs don't fit in max_length
if total_length > max_length then
if before ~= nil then
before.ellipse = true

View File

@ -1,6 +1,8 @@
local highlight = require 'lualine.highlight'
local Tab = require('lualine.utils.class'):extend()
---intialize a new tab from opts
---@param opts table
function Tab:init(opts)
assert(opts.tabnr, 'Cannot create Tab without tabnr')
self.tabnr = opts.tabnr
@ -8,6 +10,9 @@ function Tab:init(opts)
self.highlights = opts.highlights
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 buflist = vim.fn.tabpagebuflist(self.tabnr)
local winnr = vim.fn.tabpagewinnr(self.tabnr)
@ -27,11 +32,14 @@ function Tab:label()
return vim.fn.fnamemodify(file, ':t')
end
---returns rendered tab
---@return string
function Tab:render()
local name
if self.ellipse then
if self.ellipse then -- show elipsis
name = '...'
else
-- different formats for different modes
if self.options.mode == 0 then
name = string.format('%s%s ', (self.last or not self.first) and ' ' or '', tostring(self.tabnr))
elseif self.options.mode == 1 then
@ -40,10 +48,14 @@ function Tab:render()
name = string.format('%s%s %s ', (self.last or not self.first) and ' ' or '', tostring(self.tabnr), self:label())
end
end
self.len = #name
self.len = vim.fn.strchars(name)
-- setup for mouse clicks
local line = string.format('%%%s@LualineSwitchTab@%s%%T', self.tabnr, name)
-- apply highlight
line = highlight.component_format_highlight(self.highlights[(self.current and 'active' or 'inactive')]) .. line
-- apply separators
if self.options.self.section < 'lualine_x' and not self.first then
local sep_before = self:separator_before()
line = sep_before .. line
@ -56,6 +68,8 @@ function Tab:render()
return line
end
---apply separator before current tab
---@return string
function Tab:separator_before()
if self.current or self.aftercurrent then
return '%S{' .. self.options.section_separators.left .. '}'
@ -64,6 +78,8 @@ function Tab:separator_before()
end
end
---apply separator after current tab
---@return string
function Tab:separator_after()
if self.current or self.beforecurrent then
return '%s{' .. self.options.section_separators.right .. '}'

View File

@ -29,7 +29,9 @@ local config = {
extensions = {},
}
-- change separator format 'x' to {left='x', right='x'}
--- 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
@ -39,6 +41,9 @@ local function fix_separators(separators)
return separators
end
---extends config based on configtable
---@param config_table table
---@return table copy of config
local function apply_configuration(config_table)
if not config_table then
return vim.deepcopy(config)
@ -63,6 +68,8 @@ local function apply_configuration(config_table)
return vim.deepcopy(config)
end
--- returns current active config
---@return table a copy of config
local function get_current_config()
return vim.deepcopy(config)
end

View File

@ -33,12 +33,14 @@ local mode_to_highlight = {
['TERMINAL'] = '_terminal',
}
-- determine if an highlight exist and isn't cleared
--- 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
--- clears loaded_highlights table and highlights
local function clear_highlights()
for highlight_name, _ in pairs(loaded_highlights) do
vim.cmd('highlight clear ' .. highlight_name)
@ -46,6 +48,9 @@ local function clear_highlights()
end
end
---converts cterm, color_name type colors to #rrggbb format
---@param color string|number
---@return string
local function sanitize_color(color)
if type(color) == 'string' then
if color:sub(1, 1) == '#' then
@ -60,6 +65,12 @@ local function sanitize_color(color)
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 ect
---@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
@ -68,13 +79,13 @@ function M.highlight(name, foreground, background, gui, link)
foreground = sanitize_color(foreground)
background = sanitize_color(background)
table.insert(command, name)
if foreground and foreground ~= 'none' then
if foreground and foreground ~= 'None' then
table.insert(command, 'guifg=' .. foreground)
if create_cterm_colors then
table.insert(command, 'ctermfg=' .. modules.color_utils.rgb2cterm(foreground))
end
end
if background and background ~= 'none' then
if background and background ~= 'None' then
table.insert(command, 'guibg=' .. background)
if create_cterm_colors then
table.insert(command, 'ctermbg=' .. modules.color_utils.rgb2cterm(background))
@ -89,6 +100,8 @@ function M.highlight(name, foreground, background, gui, link)
loaded_highlights[name] = true
end
---define hl_groups for a theme
---@param theme table
function M.create_highlight_groups(theme)
clear_highlights()
active_theme = theme
@ -105,9 +118,9 @@ function M.create_highlight_groups(theme)
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
---@description: adds '_mode' at end of highlight_group
---@param highlight_group string name of highlight group
---@return string highlight group name with mode
function M.append_mode(highlight_group, is_focused)
if is_focused == nil then
is_focused = modules.utils.is_focused()
@ -120,12 +133,12 @@ function M.append_mode(highlight_group, is_focused)
end
-- Helper function for create component highlight
-- Handles fall back of colors when crea58ng highlight group
-- @param color table color passed for creating component highlight
-- @param options_color color set by color option for component
-- this is first falk back
-- @param default_color Colors et in theme this is 2nd fall back
-- @param kind (fg/bg))
---Handles fall back of colors when creating highlight group
---@param color table color passed for creating component highlight
---@param options_color table color set by color option for component
--- this is first fall back
---@param default_color table colors et in theme this is 2nd fall back
---@param kind string fg/bg
local function get_default_component_color(color, options_color, default_color, kind)
if color[kind] then
return color[kind]
@ -144,15 +157,15 @@ local function get_default_component_color(color, options_color, default_color,
end
end
-- Create highlight group with fg bg and gui from theme
-- @color 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
-- @highlight_tag is unique tag for highlight group
-- returns the name of highlight group
-- @options is parameter of component.init() function
-- @return: (string) unique name that can be used by component_format_highlight
-- to retrive highlight group
---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 string unique name that can be used by component_format_highlight
--- to retrieve highlight group
function M.create_component_highlight_group(color, highlight_tag, options)
local tag_id = 0
while
@ -211,11 +224,11 @@ function M.create_component_highlight_group(color, highlight_tag, options)
return options.self.section .. '_' .. highlight_tag
end
-- @description: retrieve highlight_groups for components
-- @param highlight_name:(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
-- @return: (string) formated highlight group name
---@description: retrieve highlight_groups for components
---@param highlight_name 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
---@return string formatted highlight group name
function M.component_format_highlight(highlight_name)
local highlight_group = highlight_name
if highlight_name:find 'no_mode' == #highlight_name - #'no_mode' + 1 then
@ -229,6 +242,12 @@ function M.component_format_highlight(highlight_name)
end
end
---@description: retrieve highlight_groups for section
---@param highlight_group 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(highlight_group, is_focused)
if highlight_group > 'lualine_c' and not M.highlight_exists(highlight_group .. '_normal') then
highlight_group = 'lualine_' .. section_highlight_map[highlight_group:match 'lualine_(.)']
@ -241,11 +260,11 @@ function M.format_highlight(highlight_group, is_focused)
return '%#' .. highlight_group .. '_normal#'
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 '◀️' ' eeds reverse colors so the caller should swap left and right
-- @return: (string) formated highlight group name
---@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.
@ -253,7 +272,7 @@ function M.get_transitional_highlights(left_hl, right_hl)
return nil
end
-- construct the name of hightlight group
-- 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

View File

@ -4,11 +4,11 @@ local Object = {}
Object.__index = Object
-- luacheck: push no unused args
-- Initializer
---Initializer
function Object:init(...) end
-- luacheck: pop
-- Extened base class to create a child class
---Extened base class to create a child class
function Object:extend()
local cls = {}
for k, v in pairs(self) do
@ -28,14 +28,14 @@ function Object:__tostring()
end
-- luacheck: pop
-- Creates a new object
---Creates a new object
function Object:new(...)
local obj = setmetatable({}, self)
obj:init(...)
return obj
end
-- Creates a new object
---Creates a new object
function Object:__call(...)
return self:new(...)
end

View File

@ -274,6 +274,9 @@ local color_table = {
}
-- stylua: ignore end
---converts #rrggbb fomated color to cterm ('0'-'255') color
---@param hex_color string
---@return string
function M.rgb2cterm(hex_color)
local function get_color_distance(color1, color2)
-- returns how much color2 deviates from color1
@ -300,6 +303,9 @@ function M.rgb2cterm(hex_color)
return closest_cterm_color
end
---converts color name (only ones supported by neovim) formated 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
@ -308,6 +314,9 @@ function M.color_name2rgb(name)
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

View File

@ -1,12 +1,15 @@
-- Copyright (c) 2020-2021 shadmansaleh
-- MIT license, see LICENSE for more details.
-- Wrapper arround job api
--- wrapper arround 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 imidiately disables io from the job.
stop = function(self)
if self.killed then
return
@ -30,6 +33,10 @@ local Job = setmetatable({
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

View File

@ -7,13 +7,15 @@ local modules = lualine_require.lazy_require {
notice = 'lualine.utils.notices',
}
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 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
@ -27,6 +29,7 @@ local component_types = {
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()
@ -34,14 +37,19 @@ local component_types = {
end
return require 'lualine.components.special.function_component'(component)
end,
--- loads variables & options (g:,go:,b:,bo:...) as componenta
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 confif
---@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)
@ -114,6 +122,9 @@ You'll have to change it to this to retain old behavior:
end
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
@ -130,12 +141,16 @@ local function load_sections(sections, options)
end
end
---loads all the configs (active, inactive, tabline)
---@param config table user config
local function load_components(config)
load_sections(config.sections, config.options)
load_sections(config.inactive_sections, config.options)
load_sections(config.tabline, config.options)
end
---loads all the extensions
---@param config table user confif
local function load_extensions(config)
local loaded_extensions = {}
for _, extension in pairs(config.extensions) do
@ -175,11 +190,17 @@ Extension named `%s` was not found . Check if spelling is correct.
config.extensions = loaded_extensions
end
---loads sections and extensions or entire user config
---@param config table user config
local function load_all(config)
load_components(config)
load_extensions(config)
end
---loads a theme from lua module
---priotizes external themes (from user config or other plugins) over the bundled ones
---@param theme_name string
---@return table theme defination from module
local function load_theme(theme_name)
assert(is_valid_filename(theme_name), 'Invalid filename')
local retval

View File

@ -1,6 +1,7 @@
-- Copyright (c) 2020-2021 hoob3rt
-- MIT license, see LICENSE for more details.
local Mode = {}
-- stylua: ignore
Mode.map = {
['n'] = 'NORMAL',
@ -40,6 +41,7 @@ Mode.map = {
['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

View File

@ -6,6 +6,8 @@ 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')
@ -13,6 +15,8 @@ function M.add_notice(notice)
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')
@ -22,6 +26,8 @@ function M.add_persistent_notice(notice)
end
end
---show setup :LuaLineNotices and show notification about error when there
---are notices available
function M.notice_message_startup()
if #notices > 0 or #persistent_notices then
vim.cmd 'command! -nargs=0 LualineNotices lua require"lualine.utils.notices".show_notices()'
@ -35,6 +41,7 @@ function M.notice_message_startup()
end
end
---create notice view
function M.show_notices()
vim.cmd 'silent! keepalt split'
@ -54,7 +61,7 @@ function M.show_notices()
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 window', vim.log.levels.ERROR, {})
vim.notify('Lualine Notices is already open in another buffer', vim.log.levels.ERROR, {})
vim.cmd 'normal q'
return
end

View File

@ -4,7 +4,16 @@ local M = {}
local require = require('lualine_require').require
local utils = require 'lualine.utils.utils'
local highlight = require 'lualine.highlight'
-- Returns formated string for a section
---runs draw function on components in section
---handles separator edge cases :/
---also handles default transitional separators at section boundaries
---(why? I don't know)
---@param section table list of components
---@param section_name string used for getting proper hl
---@param is_focused boolean
---@return string formated string for a section
--TODO Clean this up this does lots of messy stuff.
function M.draw_section(section, section_name, is_focused)
local highlight_name = highlight.format_highlight('lualine_' .. section_name, is_focused)

View File

@ -4,6 +4,10 @@ local M = {}
-- Note for now only works for termguicolors scope can be bg or fg or any other
-- attr parameter like bold/italic/reverse
---@param color_group string hl_group name
---@param scope string bg | fg
---@return table|string returns #rrggbb formated color when scope is specified
---- or comolete color table when scope isn't specified
function M.extract_highlight_colors(color_group, scope)
if vim.fn.hlexists(color_group) == 0 then
return nil
@ -23,8 +27,12 @@ function M.extract_highlight_colors(color_group, scope)
return color
end
-- retrives color value from highlight group name in syntax_list
-- first present highlight is returned
--- retrives color value from highlight group name in syntax_list
--- first present highlight is returned
---@param scope string
---@param syntaxlist table
---@param default string
---@return string|nil
function M.extract_color_from_hllist(scope, syntaxlist, default)
for _, highlight_name in ipairs(syntaxlist) do
if vim.fn.hlexists(highlight_name) ~= 0 then
@ -44,7 +52,9 @@ function M.extract_color_from_hllist(scope, syntaxlist, default)
return default
end
-- remove empty strings from list
---remove empty strings from list
---@param list table
---@return table
function M.list_shrink(list)
local new_list = {}
for i = 1, #list do
@ -55,12 +65,19 @@ function M.list_shrink(list)
return new_list
end
-- Check if a auto command is already defined
--- Check if a auto command is already defined
---@param event string
---@param patern string
---@param command_str string
---@return boolean whether autocmd is already defined
local function autocmd_is_defined(event, patern, command_str)
return vim.api.nvim_exec(string.format('au lualine %s %s', event, patern), true):find(command_str) ~= nil
end
-- Define a auto command if it's not already defined
--- Define a auto command if it's not already defined
---@param event string event name
---@param patern string event patern
---@param cmd string command to run on event
function M.define_autocmd(event, patern, cmd)
if not cmd then
cmd = patern
@ -76,6 +93,10 @@ function M.is_focused()
return tonumber(vim.g.actual_curwin) == vim.fn.win_getid()
end
--- Check what's the charecter at pos
---@param str string
---@param pos number
---@return string charecter at position pos in string str
function M.charAt(str, pos)
return string.char(str:byte(pos))
end

View File

@ -4,6 +4,7 @@ local M = {}
M.sep = package.config:sub(1, 1)
-- Figures ou full path of lualine installation
local source = debug.getinfo(1, 'S').source
if source:sub(1, 1) == '@' then
local base_start = source:find(table.concat({ 'lualine.nvim', 'lua', 'lualine_require.lua' }, M.sep))
@ -15,11 +16,17 @@ if source:sub(1, 1) == '@' then
end
end
--- checks if name is valied
---@param name string
---@return boolean
function M.is_valid_filename(name)
local invalid_chars = '[^a-zA-Z0-9_. -]'
return name:find(invalid_chars) == nil
end
---require module module
---@param module string mogule arraived
---@return any the required module
function M.require(module)
if package.loaded[module] then
return package.loaded[module]
@ -61,6 +68,10 @@ function M.require(module)
return require(module)
end
---requires modules when they are used
---@param modules table k-v table where v is module path and k is name that will
--- be indexed
---@return table metatable where when a key is indexed it gets required and cached
function M.lazy_require(modules)
return setmetatable({}, {
__index = function(self, key)