From 141417de619833284074b2360dea8206d5196c4e Mon Sep 17 00:00:00 2001
From: Shadman <shadmansaleh3@gmail.com>
Date: Tue, 4 May 2021 23:42:26 +0600
Subject: [PATCH] Performence improvments (#205)

* Only load default config when needed

* Only load default cterm colors when needed

* Async load components and theme

* Rename: util_colors -> cterm_colors
---
 lua/lualine/highlight.lua     | 11 ++---
 lua/lualine/init.lua          | 85 ++++++++++++++++++++---------------
 lua/lualine/utils/section.lua |  3 ++
 3 files changed, 57 insertions(+), 42 deletions(-)

diff --git a/lua/lualine/highlight.lua b/lua/lualine/highlight.lua
index a668602..0139484 100644
--- a/lua/lualine/highlight.lua
+++ b/lua/lualine/highlight.lua
@@ -1,11 +1,10 @@
 -- Copyright (c) 2020-2021 hoob3rt
 -- MIT license, see LICENSE for more details.
 local M = {}
-local utils_colors = require 'lualine.utils.cterm_colors'
+local cterm_colors
 local utils = require 'lualine.utils.utils'
 local section_highlight_map = {x = 'c', y = 'b', z = 'a'}
 local active_theme = nil
-local cterm_colors = false
 
 function M.highlight(name, foreground, background, gui, reload)
   local command = {'highlight', name}
@@ -13,14 +12,14 @@ function M.highlight(name, foreground, background, gui, reload)
     table.insert(command, 'guifg=' .. foreground)
     if cterm_colors then
       table.insert(command,
-                   'ctermfg=' .. utils_colors.get_cterm_color(foreground))
+                   'ctermfg=' .. cterm_colors.get_cterm_color(foreground))
     end
   end
   if background and background ~= 'none' then
     table.insert(command, 'guibg=' .. background)
     if cterm_colors then
       table.insert(command,
-                   'ctermbg=' .. utils_colors.get_cterm_color(background))
+                   'ctermbg=' .. cterm_colors.get_cterm_color(background))
     end
   end
   if gui then
@@ -36,7 +35,9 @@ end
 function M.create_highlight_groups(theme)
   utils.clear_highlights()
   active_theme = theme
-  cterm_colors = not vim.o.termguicolors
+  if not vim.o.termguicolors then
+    cterm_colors = require 'lualine.utils.cterm_colors'
+  end
   for mode, sections in pairs(theme) do
     for section, colorscheme in pairs(sections) do
       local highlight_group_name = {'lualine', section, mode}
diff --git a/lua/lualine/init.lua b/lua/lualine/init.lua
index aabe7f3..bd0a791 100644
--- a/lua/lualine/init.lua
+++ b/lua/lualine/init.lua
@@ -5,7 +5,6 @@ local highlight = require('lualine.highlight')
 local config = {}
 
 local function apply_configuration(config_table)
-  if not config_table then return end
   local function parse_sections(section_group_name)
     if not config_table[section_group_name] then return end
     for section_name, section in pairs(config_table[section_group_name]) do
@@ -81,18 +80,23 @@ local function component_loader(component)
 end
 
 local function load_sections(sections)
-  for section_name, section in pairs(sections) do
-    for index, component in pairs(section) do
-      if type(component) == 'string' or type(component) == 'function' then
-        component = {component}
+  local async_loader
+  async_loader = vim.loop.new_async(vim.schedule_wrap(function()
+    for section_name, section in pairs(sections) do
+      for index, component in pairs(section) do
+        if type(component) == 'string' or type(component) == 'function' then
+          component = {component}
+        end
+        component.self = {}
+        component.self.section = section_name
+        -- apply default args
+        component = vim.tbl_extend('keep', component, config.options)
+        section[index] = component_loader(component)
       end
-      component.self = {}
-      component.self.section = section_name
-      -- apply default args
-      component = vim.tbl_extend('keep', component, config.options)
-      section[index] = component_loader(component)
     end
-  end
+    async_loader:close()
+  end))
+  async_loader:send()
 end
 
 local function load_components()
@@ -234,31 +238,36 @@ end
 local function tabline() return statusline(config.tabline, true) end
 
 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(require, 'lualine.themes.' .. theme_name)
-      if ok then return theme end
-    elseif type(theme_name) == 'table' then
-      -- use the provided theme as-is
-      return config.options.theme
+  local async_loader
+  async_loader = vim.loop.new_async(vim.schedule_wrap(function()
+    local function get_theme_from_config()
+      local theme_name = config.options.theme
+      if type(theme_name) == 'string' then
+        local ok, theme = pcall(require, 'lualine.themes.' .. theme_name)
+        if ok then return theme end
+      elseif type(theme_name) == 'table' then
+        -- use the provided theme as-is
+        return config.options.theme
+      end
+      vim.api.nvim_echo({
+        {
+          'theme ' .. tostring(theme_name) .. ' not found, defaulting to gruvbox',
+          'ErrorMsg'
+        }
+      }, true, {})
+      return require 'lualine.themes.gruvbox'
     end
-    vim.api.nvim_echo({
-      {
-        'theme ' .. tostring(theme_name) .. ' not found, defaulting to gruvbox',
-        'ErrorMsg'
-      }
-    }, true, {})
-    return require 'lualine.themes.gruvbox'
-  end
-  local theme = get_theme_from_config()
-  highlight.create_highlight_groups(theme)
-  vim.api.nvim_exec([[
-  augroup lualine
-  autocmd!
-  autocmd ColorScheme * lua require'lualine.utils.utils'.reload_highlights()
-  augroup END
-  ]], false)
+    local theme = get_theme_from_config()
+    highlight.create_highlight_groups(theme)
+    vim.api.nvim_exec([[
+    augroup lualine
+    autocmd!
+    autocmd ColorScheme * lua require'lualine.utils.utils'.reload_highlights()
+    augroup END
+    ]], false)
+    async_loader:close()
+  end))
+  async_loader:send()
 end
 
 local function set_tabline()
@@ -272,8 +281,10 @@ local function set_statusline()
   if next(config.sections) ~= nil or next(config.inactive_sections) ~= nil then
     vim.o.statusline = '%!v:lua.require\'lualine\'.statusline()'
     vim.api.nvim_exec([[
-    autocmd lualine WinLeave,BufLeave * lua vim.wo.statusline=require'lualine'.statusline()
-    autocmd lualine WinEnter,BufEnter * set statusline<
+  augroup lualine
+    autocmd WinLeave,BufLeave * lua vim.wo.statusline=require'lualine'.statusline()
+    autocmd WinEnter,BufEnter * set statusline<
+  augroup END
     ]], false)
   end
 end
diff --git a/lua/lualine/utils/section.lua b/lua/lualine/utils/section.lua
index b35e209..ce86034 100644
--- a/lua/lualine/utils/section.lua
+++ b/lua/lualine/utils/section.lua
@@ -7,6 +7,9 @@ function M.draw_section(section, highlight_name)
   local status = {}
   for _, component in pairs(section) do
     -- load components into status table
+    if type(component) ~= 'table' or (type(component) == 'table' and not component.component_no) then
+      return '' -- unknown element in section. section posibly not yet loaded
+    end
     table.insert(status, component:draw(highlight_name))
   end