lualine-harpoon.nvim/lua/lualine-harpoon/component.lua

134 lines
3.2 KiB
Lua

local status = require("lualine-harpoon.status")
local cfg = require("lualine-harpoon.config")
local req = require("lualine_require")
local Component = req.require("lualine.component")
---@class LualineHarpoonComponent
---@field cache LualineHarpoonCache
---@field options LualineHarpoonConfig
local M = Component:extend()
---@class LualineHarpoonCache
---@field result string?
---@field is_valid boolean
---@field last_buf string?
---@field last_changedtick integer?
---@field last_status_hash string?
---@param opts table?
function M:init(opts)
M.super:init(opts)
self.options = vim.tbl_deep_extend("force", cfg, self.options or {})
self.cache = {
result = nil,
is_valid = false,
last_buf = nil,
last_changedtick = nil,
last_status_hash = nil,
}
self:setup_cache_invalidation()
end
---@private
function M:setup_cache_invalidation()
local group_name = "LualineHarpoon_" .. tostring(self)
local group = vim.api.nvim_create_augroup(group_name, { clear = true })
vim.api.nvim_create_autocmd({
"BufEnter",
"BufWritePost",
"User",
}, {
group = group,
callback = function()
self.cache.is_valid = false
end,
})
end
---@param st HarpoonStatus
---@return string
function M:hash_status(st)
return string.format("%s:%s", tostring(st.current or "nil"), st.total)
end
---@return boolean
function M:is_cache_valid()
if not self.cache.is_valid then
return false
end
local current_buf = vim.api.nvim_buf_get_name(0)
local current_changetick = vim.api.nvim_buf_get_changedtick(0)
if self.cache.last_buf ~= current_buf or self.cache.last_changedtick ~= current_changetick then
return false
end
local current_status = status.get_status()
local current_hash = self:hash_status(current_status)
return self.cache.last_status_hash == current_hash
end
---@param new_cfg LualineHarpoonConfig
function M.upadte_config(new_cfg)
cfg = new_cfg
end
---@param result string
---@private
function M:update_cache(result)
local current_status = status.get_status()
self.cache.result = result
self.cache.is_valid = true
self.cache.last_buf = vim.api.nvim_buf_get_name(0)
self.cache.last_changedtick = vim.api.nvim_buf_get_changedtick(0)
self.cache.last_status_hash = self:hash_status(current_status)
end
---@return string
function M:update_status()
if self:is_cache_valid() then
return self.cache.result
end
local st = status.get_status()
local result = ""
-- Handle custom format function
if type(self.options.format) == "function" then
result = self.options.format(st.current, st.total)
elseif st.total > 0 then
-- Default formatting when we have marks
local s = self.options.symbol
local n = st.current and tostring(st.current) or s.unknown
result = string.format("%s%s%s%d%s", s.open, n, s.separator, st.total, s.close)
elseif self.options.show_when_empty then
-- Show something when no marks exist, but only if show_when_empty is true
local s = self.options.symbol
if type(self.options.empty_text) == "string" then
result = self.options.empty_text
end
result = string.format("%s0%s0%s", s.open, s.separator, s.close)
end
self:update_cache(result)
return result
end
---@return string
function M:draw_status()
local text = self:update_status()
if self.color_hl and text ~= "" then
return self.color_hl(text)
end
return text
end
return M