perf: Improve startup by droping most of the requires + refactors

Important: It's no longer guaranteed that if component/extension
of same name exists in multiple entries in rtp which one will be
loaded. The guarantee is still there for themes . Means other
plugins or users config can overwrite a lualines internal theme
with same file name . I'm droping the guarantee for components
and extensions because there isn't much usecase for it . It's simple
to have a unique name and droping that guarantee allows more
optimizations that speeds up lualine.
This commit is contained in:
shadmansaleh 2021-08-30 17:54:23 +06:00
parent 2b90200998
commit 1439ba6d37
10 changed files with 153 additions and 136 deletions

View File

@ -1,12 +1,13 @@
-- Copyright (c) 2020-2021 hoob3rt -- Copyright (c) 2020-2021 hoob3rt
-- MIT license, see LICENSE for more details. -- MIT license, see LICENSE for more details.
local modules = require('lualine.utils.lazy_require'){ local lualine_require = require'lualine_require'
local modules = lualine_require.lazy_require{
highlight = 'lualine.highlight', highlight = 'lualine.highlight',
utils = 'lualine.utils.utils', utils = 'lualine.utils.utils',
utils_notices = 'lualine.utils.notices', utils_notices = 'lualine.utils.notices',
} }
local Diagnostics = require('lualine.component'):new() local Diagnostics = lualine_require.require('lualine.component'):new()
-- LuaFormatter off -- LuaFormatter off
Diagnostics.default_colors = { Diagnostics.default_colors = {

View File

@ -1,11 +1,14 @@
-- Copyright (c) 2020-2021 shadmansaleh -- Copyright (c) 2020-2021 shadmansaleh
-- MIT license, see LICENSE for more details. -- MIT license, see LICENSE for more details.
local utils = require 'lualine.utils.utils'
local utils_notices = require('lualine.utils.notices')
local highlight = require 'lualine.highlight'
local Job = require'lualine.utils.job'
local Diff = require('lualine.component'):new() local lualine_require = require'lualine_require'
local modules = lualine_require.lazy_require{
utils = 'lualine.utils.utils',
utils_notices = 'lualine.utils.notices',
highlight = 'lualine.highlight',
Job = 'lualine.utils.job',
}
local Diff = lualine_require.require('lualine.component'):new()
-- Vars -- Vars
-- variable to store git diff stats -- variable to store git diff stats
@ -25,7 +28,7 @@ Diff.default_colors = {
local diff_cache = {} -- Stores last known value of diff of a buffer local diff_cache = {} -- Stores last known value of diff of a buffer
local function color_deprecation_notice(color, opt_name) local function color_deprecation_notice(color, opt_name)
utils_notices.add_notice(string.format([[ modules.utils_notices.add_notice(string.format([[
### Diff component ### Diff component
Using option `%s` as string to set foreground color has been deprecated Using option `%s` as string to set foreground color has been deprecated
and will soon be removed. Now this option has same semantics as regular and will soon be removed. Now this option has same semantics as regular
@ -64,7 +67,7 @@ Diff.new = function(self, options, child)
-- apply colors -- apply colors
if not new_instance.options.color_added then if not new_instance.options.color_added then
new_instance.options.color_added = {fg = new_instance.options.color_added = {fg =
utils.extract_highlight_colors('DiffAdd', 'fg') or modules.utils.extract_highlight_colors('DiffAdd', 'fg') or
Diff.default_colors.added} Diff.default_colors.added}
elseif type(new_instance.options.color_added) == 'string' elseif type(new_instance.options.color_added) == 'string'
and vim.fn.hlexists(new_instance.options.color_added) == 0 then and vim.fn.hlexists(new_instance.options.color_added) == 0 then
@ -73,7 +76,7 @@ Diff.new = function(self, options, child)
end end
if not new_instance.options.color_modified then if not new_instance.options.color_modified then
new_instance.options.color_modified = {fg = new_instance.options.color_modified = {fg =
utils.extract_highlight_colors('DiffChange', 'fg') or modules.utils.extract_highlight_colors('DiffChange', 'fg') or
Diff.default_colors.modified} Diff.default_colors.modified}
elseif type(new_instance.options.color_modified) == 'string' elseif type(new_instance.options.color_modified) == 'string'
and vim.fn.hlexists(new_instance.options.color_modified) == 0 then and vim.fn.hlexists(new_instance.options.color_modified) == 0 then
@ -82,7 +85,7 @@ Diff.new = function(self, options, child)
end end
if not new_instance.options.color_removed then if not new_instance.options.color_removed then
new_instance.options.color_removed = {fg = new_instance.options.color_removed = {fg =
utils.extract_highlight_colors('DiffDelete', 'fg') or modules.utils.extract_highlight_colors('DiffDelete', 'fg') or
Diff.default_colors.removed} Diff.default_colors.removed}
elseif type(new_instance.options.color_removed) == 'string' elseif type(new_instance.options.color_removed) == 'string'
and vim.fn.hlexists(new_instance.options.color_removed) == 0 then and vim.fn.hlexists(new_instance.options.color_removed) == 0 then
@ -93,13 +96,13 @@ Diff.new = function(self, options, child)
-- create highlights and save highlight_name in highlights table -- create highlights and save highlight_name in highlights table
if new_instance.options.colored then if new_instance.options.colored then
new_instance.highlights = { new_instance.highlights = {
added = highlight.create_component_highlight_group( added = modules.highlight.create_component_highlight_group(
new_instance.options.color_added, 'diff_added', new_instance.options.color_added, 'diff_added',
new_instance.options), new_instance.options),
modified = highlight.create_component_highlight_group( modified = modules.highlight.create_component_highlight_group(
new_instance.options.color_modified, 'diff_modified', new_instance.options.color_modified, 'diff_modified',
new_instance.options), new_instance.options),
removed = highlight.create_component_highlight_group( removed = modules.highlight.create_component_highlight_group(
new_instance.options.color_removed, 'diff_removed', new_instance.options.color_removed, 'diff_removed',
new_instance.options) new_instance.options)
} }
@ -109,7 +112,7 @@ Diff.new = function(self, options, child)
if Diff.diff_checker_enabled then if Diff.diff_checker_enabled then
-- setup internal source -- setup internal source
utils.define_autocmd('BufWritePost', "lua require'lualine.components.diff'.update_git_diff()") modules.utils.define_autocmd('BufWritePost', "lua require'lualine.components.diff'.update_git_diff()")
Diff.update_diff_args() Diff.update_diff_args()
end end
@ -136,7 +139,7 @@ Diff.update_status = function(self, is_focused)
if self.options.colored then if self.options.colored then
-- load the highlights and store them in colors table -- load the highlights and store them in colors table
for name, highlight_name in pairs(self.highlights) do for name, highlight_name in pairs(self.highlights) do
colors[name] = highlight.component_format_highlight(highlight_name) colors[name] = modules.highlight.component_format_highlight(highlight_name)
end end
end end
@ -242,7 +245,7 @@ function Diff.update_git_diff()
if Diff.diff_args then if Diff.diff_args then
Diff.diff_output_cache = {} Diff.diff_output_cache = {}
if Diff.diff_job then Diff.diff_job:stop() end if Diff.diff_job then Diff.diff_job:stop() end
Diff.diff_job = Job(Diff.diff_args) Diff.diff_job = modules.Job(Diff.diff_args)
if Diff.diff_job then Diff.diff_job:start() end if Diff.diff_job then Diff.diff_job:start() end
end end
end end

View File

@ -1,9 +1,11 @@
-- Copyright (c) 2020-2021 hoob3rt -- Copyright (c) 2020-2021 hoob3rt
-- MIT license, see LICENSE for more details. -- MIT license, see LICENSE for more details.
local highlight = require('lualine.highlight') local lualine_require = require'lualine_require'
local utils = require('lualine.utils.utils') local modules = lualine_require.lazy_require{
highlight = 'lualine.highlight',
local FileType = require('lualine.component'):new() utils = 'lualine.utils.utils',
}
local FileType = lualine_require.require('lualine.component'):new()
function FileType:new(options, child) function FileType:new(options, child)
local new_instance = self._parent:new(options, child or FileType) local new_instance = self._parent:new(options, child or FileType)
@ -28,21 +30,21 @@ function FileType:apply_icon()
icon, icon_highlight_group = devicons.get_icon(f_name, f_extension) icon, icon_highlight_group = devicons.get_icon(f_name, f_extension)
if icon and self.options.colored then if icon and self.options.colored then
local highlight_color = utils.extract_highlight_colors( local highlight_color = modules.utils.extract_highlight_colors(
icon_highlight_group, 'fg') icon_highlight_group, 'fg')
local is_focused = utils.is_focused() local is_focused = modules.utils.is_focused()
local default_highlight = highlight.format_highlight(is_focused, local default_highlight = modules.highlight.format_highlight(is_focused,
self.options.self self.options.self
.section) .section)
local icon_highlight = self.options.self.section .. '_' .. local icon_highlight = self.options.self.section .. '_' ..
icon_highlight_group icon_highlight_group
if not utils.highlight_exists(icon_highlight .. '_normal') then if not modules.utils.highlight_exists(icon_highlight .. '_normal') then
icon_highlight = highlight.create_component_highlight_group( icon_highlight = modules.highlight.create_component_highlight_group(
{fg = highlight_color}, icon_highlight_group, {fg = highlight_color}, icon_highlight_group,
self.options) self.options)
end end
icon = highlight.component_format_highlight(icon_highlight) .. icon .. icon = modules.highlight.component_format_highlight(icon_highlight) .. icon ..
default_highlight default_highlight
end end
else else

View File

@ -1,5 +1,6 @@
-- Copyright (c) 2020-2021 hoob3rt -- Copyright (c) 2020-2021 hoob3rt
-- MIT license, see LICENSE for more details. -- MIT license, see LICENSE for more details.
local require = require'lualine_require'.require
local Mode = require('lualine.component'):new() local Mode = require('lualine.component'):new()
local get_mode = require('lualine.utils.mode').get_mode local get_mode = require('lualine.utils.mode').get_mode

View File

@ -1,22 +1,25 @@
-- Copyright (c) 2020-2021 hoob3rt -- Copyright (c) 2020-2021 hoob3rt
-- MIT license, see LICENSE for more details. -- MIT license, see LICENSE for more details.
local M = {} local M = {}
local cterm_colors local lualine_require = require'lualine_require'
local utils = require 'lualine.utils.utils' local require = lualine_require.require
local modules = lualine_require.lazy_require{
utils = 'lualine.utils.utils',
color_utils = 'lualine.utils.cterm_colors',
}
local section_highlight_map = {x = 'c', y = 'b', z = 'a'} local section_highlight_map = {x = 'c', y = 'b', z = 'a'}
local active_theme = nil local active_theme = nil
local create_cterm_colors = false
local function sanitize_color(color) local function sanitize_color(color)
if type(color) == 'string' then if type(color) == 'string' then
if color:sub(1,1) == '#' then return color end -- RGB value if color:sub(1,1) == '#' then return color end -- RGB value
local converter = require 'lualine.utils.cterm_colors' return modules.color_utils.color_name2rgb(color)
return converter.color_name2rgb(color)
elseif type(color) == 'number' then elseif type(color) == 'number' then
if color > 255 then if color > 255 then
error("What's this it can't be higher then 255 and you've given "..color) error("What's this it can't be higher then 255 and you've given "..color)
end end
local converter = require 'lualine.utils.cterm_colors' return modules.color_utils.cterm2rgb(color)
return converter.cterm2rgb(color)
end end
end end
@ -30,16 +33,16 @@ function M.highlight(name, foreground, background, gui, link, reload)
table.insert(command, name) table.insert(command, name)
if foreground and foreground ~= 'none' then if foreground and foreground ~= 'none' then
table.insert(command, 'guifg=' .. foreground) table.insert(command, 'guifg=' .. foreground)
if cterm_colors then if create_cterm_colors then
table.insert(command, table.insert(command,
'ctermfg=' .. cterm_colors.get_cterm_color(foreground)) 'ctermfg=' .. modules.color_utils.get_cterm_color(foreground))
end end
end end
if background and background ~= 'none' then if background and background ~= 'none' then
table.insert(command, 'guibg=' .. background) table.insert(command, 'guibg=' .. background)
if cterm_colors then if create_cterm_colors then
table.insert(command, table.insert(command,
'ctermbg=' .. cterm_colors.get_cterm_color(background)) 'ctermbg=' .. modules.color_utils.get_cterm_color(background))
end end
end end
if gui then if gui then
@ -49,15 +52,15 @@ function M.highlight(name, foreground, background, gui, link, reload)
end end
vim.cmd(table.concat(command, ' ')) vim.cmd(table.concat(command, ' '))
if not reload then if not reload then
utils.save_highlight(name, {name, foreground, background, gui, link, true}) modules.utils.save_highlight(name, {name, foreground, background, gui, link, true})
end end
end end
function M.create_highlight_groups(theme) function M.create_highlight_groups(theme)
utils.clear_highlights() modules.utils.clear_highlights()
active_theme = theme active_theme = theme
if not vim.opt.termguicolors:get() then if not vim.go.termguicolors then
cterm_colors = require 'lualine.utils.cterm_colors' create_cterm_colors = true
end end
for mode, sections in pairs(theme) do for mode, sections in pairs(theme) do
for section, color in pairs(sections) do for section, color in pairs(sections) do
@ -109,13 +112,13 @@ local function get_default_component_color(color, options_color, default_color,
if type(options_color) == 'table' and options_color[kind] then if type(options_color) == 'table' and options_color[kind] then
return options_color[kind] return options_color[kind]
elseif type(options_color) == 'string' then elseif type(options_color) == 'string' then
return utils.extract_highlight_colors(options_color, kind) return modules.utils.extract_highlight_colors(options_color, kind)
end end
end end
if type(default_color) == 'table' then if type(default_color) == 'table' then
return default_color[kind] return default_color[kind]
elseif type(default_color) == 'string' then elseif type(default_color) == 'string' then
return utils.extract_highlight_colors(default_color, kind) return modules.utils.extract_highlight_colors(default_color, kind)
end end
end end
@ -130,9 +133,9 @@ end
-- to retrive highlight group -- to retrive highlight group
function M.create_component_highlight_group(color, highlight_tag, options) function M.create_component_highlight_group(color, highlight_tag, options)
local tag_id = 0 local tag_id = 0
while (utils.highlight_exists(table.concat( while (modules.utils.highlight_exists(table.concat(
{'lualine', highlight_tag, 'no_mode'}, '_')) {'lualine', highlight_tag, 'no_mode'}, '_'))
or (options.self.section and utils.highlight_exists(table.concat( or (options.self.section and modules.utils.highlight_exists(table.concat(
{options.self.section, highlight_tag, 'normal'}, '_'))) {options.self.section, highlight_tag, 'normal'}, '_')))
) do ) do
highlight_tag = highlight_tag .. '_' .. tostring(tag_id) highlight_tag = highlight_tag .. '_' .. tostring(tag_id)
@ -193,12 +196,12 @@ function M.component_format_highlight(highlight_name)
if highlight_name:find('no_mode') == #highlight_name - #'no_mode' + 1 then if highlight_name:find('no_mode') == #highlight_name - #'no_mode' + 1 then
return '%#' .. highlight_group .. '#' return '%#' .. highlight_group .. '#'
end end
if utils.is_focused() then if modules.utils.is_focused() then
highlight_group = append_mode(highlight_group) highlight_group = append_mode(highlight_group)
else else
highlight_group = highlight_group .. '_inactive' highlight_group = highlight_group .. '_inactive'
end end
if utils.highlight_exists(highlight_group) then if modules.utils.highlight_exists(highlight_group) then
return '%#' .. highlight_group .. '#' return '%#' .. highlight_group .. '#'
else else
return '%#' .. highlight_name .. '_normal#' return '%#' .. highlight_name .. '_normal#'
@ -207,7 +210,7 @@ end
function M.format_highlight(is_focused, highlight_group) function M.format_highlight(is_focused, highlight_group)
if highlight_group > 'lualine_c' if highlight_group > 'lualine_c'
and not utils.highlight_exists(highlight_group .. '_normal') then and not modules.utils.highlight_exists(highlight_group .. '_normal') then
highlight_group = 'lualine_' .. highlight_group = 'lualine_' ..
section_highlight_map[highlight_group:match( section_highlight_map[highlight_group:match(
'lualine_(.)')] 'lualine_(.)')]
@ -218,7 +221,7 @@ function M.format_highlight(is_focused, highlight_group)
else else
highlight_name = append_mode(highlight_group) highlight_name = append_mode(highlight_group)
end end
if utils.highlight_exists(highlight_name) then if modules.utils.highlight_exists(highlight_name) then
return '%#' .. highlight_name .. '#' return '%#' .. highlight_name .. '#'
end end
return '%#' .. highlight_group .. '_normal#' return '%#' .. highlight_group .. '_normal#'
@ -236,11 +239,11 @@ function M.get_transitional_highlights(left_hl, right_hl)
-- construct the name of hightlight group -- construct the name of hightlight group
local highlight_name = table.concat({'lualine_transitional',left_hl,'to',right_hl}, '_') local highlight_name = table.concat({'lualine_transitional',left_hl,'to',right_hl}, '_')
if not utils.highlight_exists(highlight_name) then if not modules.utils.highlight_exists(highlight_name) then
-- Create the highlight_group if needed -- Create the highlight_group if needed
-- Get colors from highlights -- Get colors from highlights
local fg = utils.extract_highlight_colors(left_hl, 'bg') local fg = modules.utils.extract_highlight_colors(left_hl, 'bg')
local bg = utils.extract_highlight_colors(right_hl, 'bg') local bg = modules.utils.extract_highlight_colors(right_hl, 'bg')
if not fg or not bg then return nil end -- Color retrieval failed if not fg or not bg then return nil end -- Color retrieval failed
if bg == fg then return nil end -- Separator won't be visible anyway if bg == fg then return nil end -- Separator won't be visible anyway
M.highlight(highlight_name, fg, bg, nil) M.highlight(highlight_name, fg, bg, nil)

View File

@ -1,6 +1,7 @@
-- Copyright (c) 2020-2021 hoob3rt -- Copyright (c) 2020-2021 hoob3rt
-- MIT license, see LICENSE for more details. -- MIT license, see LICENSE for more details.
local modules = require('lualine.utils.lazy_require'){ local lualine_require = require'lualine_require'
local modules = lualine_require.lazy_require{
highlight = 'lualine.highlight', highlight = 'lualine.highlight',
loader = 'lualine.utils.loader', loader = 'lualine.utils.loader',
utils_section = 'lualine.utils.section', utils_section = 'lualine.utils.section',
@ -284,6 +285,7 @@ local function setup(user_config)
new_config = true new_config = true
config = modules.config_module.apply_configuration(user_config) config = modules.config_module.apply_configuration(user_config)
vim.go.statusline = "%{%v:lua.require'lualine'.statusline()%}" vim.go.statusline = "%{%v:lua.require'lualine'.statusline()%}"
vim.go.laststatus = 2
end end
return { return {

View File

@ -1,13 +0,0 @@
return function(modules)
return setmetatable({}, {
__index = function(self, key)
local loaded = rawget(self, key)
if loaded ~= nil then return loaded end
local module_location = modules[key]
if module_location == nil then return nil end
local module = require(module_location)
rawset(self, key, module)
return module
end
})
end

View File

@ -1,73 +1,20 @@
-- Copyright (c) 2020-2021 hoob3rt -- Copyright (c) 2020-2021 hoob3rt
-- MIT license, see LICENSE for more details. -- MIT license, see LICENSE for more details.
local lualine_require = require'lualine_require'
local require = lualine_require.require
local notice = require'lualine.utils.notices' local notice = require'lualine.utils.notices'
local utils = require'lualine.utils.utils' local is_valid_filename = lualine_require.is_valid_filename
local function lualine_load(patern, use_cache)
assert(utils.is_valid_filename(patern[#patern]), "Invalid filename")
local retval, cache_name = nil, nil
local sep = package.config:sub(1,1) local sep = package.config:sub(1,1)
if use_cache == true then
-- Turn {lua, lualine, module, name} -> lualine.module.name
-- same formst that require uses
-- then check if it's in requires cache
local copy_patern = {}
local start = patern[1] == 'lua' and 2 or 1
local copy_start = 1
for i=start, #patern do
copy_patern[copy_start] = patern[i]
copy_start = copy_start + 1
end
cache_name = table.concat(copy_patern, '.')
if package.loaded[cache_name] then
return package.loaded[cache_name]
end
end
-- Get all the runtime files that match the patern
local files = vim.fn.uniq(vim.api.nvim_get_runtime_file(
table.concat(patern, sep)..'.lua', true))
local n_files = #files
if n_files == 0 then
-- No match found
error(table.concat(patern, sep) .. " 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
-- 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
-- apear to be in lualines repo . Just run the first one
retval = dofile(files[1])
end
end
if use_cache == true and cache_name then
package.loaded[cache_name] = retval
end
return retval
end
local component_types = { local component_types = {
luaf = function(component) luaf = function(component)
return return
lualine_load({'lua', 'lualine', 'components', 'special', 'function_component'}, true):new(component) require('lualine.components.special.function_component'):new(component)
end, end,
mod = function(component) mod = function(component)
local ok, loaded_component = pcall(lualine_load, local ok, loaded_component = pcall(require,'lualine.components.'..component[1])
{'lua', 'lualine', 'components', component[1]}, true)
if ok then if ok then
component.component_name = component[1] component.component_name = component[1]
loaded_component = loaded_component:new(component) loaded_component = loaded_component:new(component)
@ -78,15 +25,15 @@ local component_types = {
local stl_expr = component[1] -- Vim's %p %l statusline elements local stl_expr = component[1] -- Vim's %p %l statusline elements
component[1] = function() return stl_expr end component[1] = function() return stl_expr end
return return
lualine_load({'lua', 'lualine', 'components', 'special', 'function_component'}, true):new(component) require('lualine.components.special.function_component'):new(component)
end, end,
var = function(component) var = function(component)
return return
lualine_load({'lua', 'lualine', 'components', 'special', 'vim_var_component'}, true):new(component) require('lualine.components.special.vim_var_component'):new(component)
end, end,
['_'] = function(component) ['_'] = function(component)
return return
lualine_load({'lua', 'lualine', 'components', 'special', 'eval_func_component'}, true):new(component) require('lualine.components.special.eval_func_component'):new(component)
end end
} }
@ -146,7 +93,7 @@ local function load_extensions(config)
local loaded_extensions = {} local loaded_extensions = {}
for _, extension in pairs(config.extensions) do for _, extension in pairs(config.extensions) do
if type(extension) == 'string' then if type(extension) == 'string' then
local ok, local_extension = pcall(lualine_load, {'lua', 'lualine', 'extensions', extension}, true) local ok, local_extension = pcall(require, 'lualine.extensions.' ..extension)
if ok then if ok then
local_extension = vim.deepcopy(local_extension) local_extension = vim.deepcopy(local_extension)
load_sections(local_extension.sections, config.options) load_sections(local_extension.sections, config.options)
@ -184,7 +131,36 @@ local function load_all(config)
end end
local function load_theme(theme_name) local function load_theme(theme_name)
return lualine_load({'lua', 'lualine', 'themes', theme_name}, false) assert(is_valid_filename(theme_name), "Invalid filename")
local retval
local path = table.concat({'lua', 'lualine', 'themes', theme_name}, sep)..'.lua'
local files = vim.fn.globpath(vim.api.nvim_get_option('rtp'),
path, true, true)
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
-- 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
-- apear to be in lualines repo . Just run the first one
retval = dofile(files[1])
end
end
return retval
end end
return { return {

View File

@ -75,11 +75,6 @@ function M.is_focused()
return tonumber(vim.g.actual_curwin) == vim.fn.win_getid() return tonumber(vim.g.actual_curwin) == vim.fn.win_getid()
end end
function M.is_valid_filename(name)
local invalid_chars="[^a-zA-Z0-9_. -]"
return name:find(invalid_chars) == nil
end
function M.charAt(str, pos) function M.charAt(str, pos)
return string.char(str:byte(pos)) return string.char(str:byte(pos))
end end

47
lua/lualine_require.lua Normal file
View File

@ -0,0 +1,47 @@
local M = {}
M.sep = package.config:sub(1,1)
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))
if base_start then
source = source:sub(2, base_start + 12 + 1 + 3) -- #lualine.nvim = 12 , #lua = 3.
if source then M.plugin_dir = source end
end
end
function M.is_valid_filename(name)
local invalid_chars="[^a-zA-Z0-9_. -]"
return name:find(invalid_chars) == nil
end
function M.require(module)
if package.loaded[module] then return package.loaded[module] end
if M.plugin_dir then
local path = M.plugin_dir .. module:gsub('%.', M.sep) .. '.lua'
assert(M.is_valid_filename(module), "Invalid filename")
if vim.loop.fs_stat(path) then
local mod_result = dofile(path)
package.loaded[module] = mod_result
return mod_result
end
end
return require(module)
end
function M.lazy_require(modules)
return setmetatable({}, {
__index = function(self, key)
local loaded = rawget(self, key)
if loaded ~= nil then return loaded end
local module_location = modules[key]
if module_location == nil then return nil end
local module = M.require(module_location)
rawset(self, key, module)
return module
end
})
end
return M