Skip to content
This repository has been archived by the owner on Jan 7, 2023. It is now read-only.

Commit

Permalink
Merge pull request #109 from datwaft/dev
Browse files Browse the repository at this point in the history
feat: optimization of highlights using global highlight-group cache
  • Loading branch information
datwaft authored Jul 29, 2021
2 parents 86d0410 + e1504ff commit 775e4ab
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 14 deletions.
11 changes: 6 additions & 5 deletions lua/bubbly/factories/bubble.lua
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
-- Created by datwaft <github.com/datwaft>

local gethighlight = require'bubbly.utils.highlight'.gethighlight
local ensure_highlight_exists = require'bubbly.utils.highlight'.ensure_highlight_exists

local settings = {
left_character = vim.g.bubbly_characters.left,
Expand Down Expand Up @@ -32,9 +33,9 @@ return function(list)
-- Render delimiter of the bubble
local function render_delimiter(delimiter, color)
if type(color) == 'string' then
return '%#'..gethighlight(nil, color) ..'Delimiter#'..delimiter
return '%#'..ensure_highlight_exists(gethighlight(nil, color)..'Delimiter')..'#'..delimiter
else
return '%#'..gethighlight(color.foreground, color.background)..'Delimiter#'..delimiter
return '%#'..ensure_highlight_exists(gethighlight(color.foreground, color.background)..'Delimiter')..'#'..delimiter
end
end
-- Auxiliar function to know if data is last in the list
Expand Down Expand Up @@ -73,16 +74,16 @@ return function(list)
if isfirst then bubble = bubble..render_delimiter(e.left, e.color) end
-- render data style
if type(e.color) == 'string' then
bubble = bubble..'%#'..gethighlight(nil, e.color, e.style) ..'#'
bubble = bubble..'%#'..ensure_highlight_exists(gethighlight(nil, e.color, e.style))..'#'
else
bubble = bubble..'%#'..gethighlight(e.color.foreground, e.color.background, e.style)..'#'
bubble = bubble..'%#'..ensure_highlight_exists(gethighlight(e.color.foreground, e.color.background, e.style))..'#'
end
-- render data
if not isfirst then bubble = bubble..' ' end
bubble = bubble..e.data:gsub('^%s*(.-)%s*$', '%1')
if not islast then bubble = bubble..' ' end
-- render right delimiter
if islast then bubble = bubble..render_delimiter(e.right, e.color)..'%#BubblyStatusLine#' end
if islast then bubble = bubble..render_delimiter(e.right, e.color)..'%#'..ensure_highlight_exists('BubblyStatusLine')..'#' end
-- render post
bubble = bubble..e.post
-- disable isfirst
Expand Down
32 changes: 23 additions & 9 deletions lua/bubbly/factories/highlight.lua
Original file line number Diff line number Diff line change
Expand Up @@ -16,36 +16,50 @@ local function execute_command(name, foreground, background, style)
vim.cmd(highlight(name, foreground, background, style))
end

-- Executes highlight vim command for normal, bold, italic and delimiter highlight
-- Creates highlight config to be used in global highlight cache
---@param command string - vim highlight command
local function highlight_config(command)
return { exists = false, cmd = command }
end

-- Returns highlight configs wrapping vim commands for normal, bold, italic and
-- delimiter highlight
---@param name string
---@param foreground string
---@param background string
---@param default_background string
local function define_bubble_highlight(name, foreground, background, default_background)
execute_command(name, background, foreground)
execute_command(name..'Bold', background, foreground, 'bold')
execute_command(name..'Italic', background, foreground, 'italic')
execute_command(name..'Delimiter', foreground, default_background)
return {
[name] = highlight_config(highlight(name, background, foreground)),
[name..'Bold'] = highlight_config(highlight(name..'Bold', background, foreground, 'bold')),
[name..'Italic'] = highlight_config(highlight(name..'Italic', background, foreground, 'italic')),
[name..'Delimiter'] = highlight_config(highlight(name..'Delimiter', foreground, default_background)),
}
end

-- Generates all vim highlights following :help :highlight for a palette
-- Generates all vim highlight configs following :help :highlight for a palette
-- and saves them in a global variable
---@param palette table<string, string>
return function(palette)
local fg = hlparser(palette.foreground)
local bg = hlparser(palette.background)
local highlights = {}
for k1, v1 in pairs(palette) do
v1 = hlparser(v1)
for k2, v2 in pairs(palette) do
if k1 ~= k2 then
v2 = hlparser(v2)
local name = 'Bubbly'..titlecase(k2)..titlecase(k1)
define_bubble_highlight(name, v1, v2, bg)
local bubble_highlights = define_bubble_highlight(name, v1, v2, bg)
highlights = vim.tbl_extend('force', highlights, bubble_highlights)
end
end
if k1 ~= 'background' then
define_bubble_highlight('Bubbly'..titlecase(k1), v1, bg, bg)
local bubble_highlights = define_bubble_highlight('Bubbly'..titlecase(k1), v1, bg, bg)
highlights = vim.tbl_extend('force', highlights, bubble_highlights)
end
end
execute_command('BubblyStatusLine', fg, bg)
highlights['BubblyStatusLine'] = highlight_config(highlight('BubblyStatusLine', fg, bg))
execute_command('BubblyTabLine', fg, bg)
vim.g._bubbly_highlight_cache = highlights
end
16 changes: 16 additions & 0 deletions lua/bubbly/utils/highlight.lua
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,22 @@ function M.gethighlight(foreground, background, special)
titlecase(special)
end

-- Ensures that a highlight with given name exists.
---@param name string | nil
---@return string
function M.ensure_highlight_exists(name)
local highlight_cache = vim.g._bubbly_highlight_cache or {}
local highlight = highlight_cache[name]
if highlight and not highlight.exists then
vim.cmd(highlight.cmd)
highlight.exists = true
highlight_cache[name] = highlight
vim.g._bubbly_highlight_cache = highlight_cache
end
-- Return the highlight name to be able to wrap 'name' with this function call
return name
end

-- Parses a palette value
---@param usercolor string
---@return string
Expand Down

0 comments on commit 775e4ab

Please sign in to comment.