diff options
Diffstat (limited to 'start/cmp/lua/cmp/utils/misc.lua')
-rw-r--r-- | start/cmp/lua/cmp/utils/misc.lua | 253 |
1 files changed, 253 insertions, 0 deletions
diff --git a/start/cmp/lua/cmp/utils/misc.lua b/start/cmp/lua/cmp/utils/misc.lua new file mode 100644 index 0000000..7c6d0e7 --- /dev/null +++ b/start/cmp/lua/cmp/utils/misc.lua @@ -0,0 +1,253 @@ +local misc = {} + +---Create once callback +---@param callback function +---@return function +misc.once = function(callback) + local done = false + return function(...) + if done then + return + end + done = true + callback(...) + end +end + +---Return concatenated list +---@param list1 any[] +---@param list2 any[] +---@return any[] +misc.concat = function(list1, list2) + local new_list = {} + for _, v in ipairs(list1) do + table.insert(new_list, v) + end + for _, v in ipairs(list2) do + table.insert(new_list, v) + end + return new_list +end + +---Repeat values +---@generic T +---@param str_or_tbl T +---@param count number +---@return T +misc.rep = function(str_or_tbl, count) + if type(str_or_tbl) == 'string' then + return string.rep(str_or_tbl, count) + end + local rep = {} + for _ = 1, count do + for _, v in ipairs(str_or_tbl) do + table.insert(rep, v) + end + end + return rep +end + +---Return the valu is empty or not. +---@param v any +---@return boolean +misc.empty = function(v) + if not v then + return true + end + if v == vim.NIL then + return true + end + if type(v) == 'string' and v == '' then + return true + end + if type(v) == 'table' and vim.tbl_isempty(v) then + return true + end + if type(v) == 'number' and v == 0 then + return true + end + return false +end + +---The symbol to remove key in misc.merge. +misc.none = vim.NIL + +---Merge two tables recursively +---@generic T +---@param v1 T +---@param v2 T +---@return T +misc.merge = function(v1, v2) + local merge1 = type(v1) == 'table' and (not vim.tbl_islist(v1) or vim.tbl_isempty(v1)) + local merge2 = type(v2) == 'table' and (not vim.tbl_islist(v2) or vim.tbl_isempty(v2)) + if merge1 and merge2 then + local new_tbl = {} + for k, v in pairs(v2) do + new_tbl[k] = misc.merge(v1[k], v) + end + for k, v in pairs(v1) do + if v2[k] == nil and v ~= misc.none then + new_tbl[k] = v + end + end + return new_tbl + end + if v1 == misc.none then + return nil + end + if v1 == nil then + if v2 == misc.none then + return nil + else + return v2 + end + end + if v1 == true then + if merge2 then + return v2 + end + return {} + end + + return v1 +end + +---Generate id for group name +misc.id = setmetatable({ + group = {}, +}, { + __call = function(_, group) + misc.id.group[group] = misc.id.group[group] or 0 + misc.id.group[group] = misc.id.group[group] + 1 + return misc.id.group[group] + end, +}) + +---Check the value is nil or not. +---@param v boolean +---@return boolean +misc.safe = function(v) + if v == nil or v == vim.NIL then + return nil + end + return v +end + +---Treat 1/0 as bool value +---@param v boolean|1|0 +---@param def boolean +---@return boolean +misc.bool = function(v, def) + if misc.safe(v) == nil then + return def + end + return v == true or v == 1 +end + +---Set value to deep object +---@param t table +---@param keys string[] +---@param v any +misc.set = function(t, keys, v) + local c = t + for i = 1, #keys - 1 do + local key = keys[i] + c[key] = misc.safe(c[key]) or {} + c = c[key] + end + c[keys[#keys]] = v +end + +---Copy table +---@generic T +---@param tbl T +---@return T +misc.copy = function(tbl) + if type(tbl) ~= 'table' then + return tbl + end + + if vim.tbl_islist(tbl) then + local copy = {} + for i, value in ipairs(tbl) do + copy[i] = misc.copy(value) + end + return copy + end + + local copy = {} + for key, value in pairs(tbl) do + copy[key] = misc.copy(value) + end + return copy +end + +---Safe version of vim.str_utfindex +---@param text string +---@param vimindex number|nil +---@return number +misc.to_utfindex = function(text, vimindex) + vimindex = vimindex or #text + 1 + return vim.str_utfindex(text, math.max(0, math.min(vimindex - 1, #text))) +end + +---Safe version of vim.str_byteindex +---@param text string +---@param utfindex number +---@return number +misc.to_vimindex = function(text, utfindex) + utfindex = utfindex or #text + for i = utfindex, 1, -1 do + local s, v = pcall(function() + return vim.str_byteindex(text, i) + 1 + end) + if s then + return v + end + end + return utfindex + 1 +end + +---Mark the function as deprecated +misc.deprecated = function(fn, msg) + local printed = false + return function(...) + if not printed then + print(msg) + printed = true + end + return fn(...) + end +end + +--Redraw +misc.redraw = setmetatable({ + doing = false, + force = false, + termcode = vim.api.nvim_replace_termcodes('<C-r><Esc>', true, true, true), +}, { + __call = function(self, force) + if vim.tbl_contains({ '/', '?' }, vim.fn.getcmdtype()) then + if vim.o.incsearch then + return vim.api.nvim_feedkeys(self.termcode, 'in', true) + end + end + + if self.doing then + return + end + self.doing = true + self.force = not not force + vim.schedule(function() + if self.force then + vim.cmd([[redraw!]]) + else + vim.cmd([[redraw]]) + end + self.doing = false + self.force = false + end) + end, +}) + +return misc |