1
0
mirror of https://github.com/SpaceVim/SpaceVim.git synced 2025-01-24 02:10:05 +08:00
SpaceVim/bundle/cmp-dictionary/lua/cmp_dictionary/util.lua
2023-06-11 21:41:39 +08:00

119 lines
2.4 KiB
Lua

local uv = vim.uv or vim.loop
local M = {}
---@param path string
---@return string buffer
function M.read_file_sync(path)
-- 292 == 0x444
local fd = assert(uv.fs_open(path, "r", 292))
local stat = assert(uv.fs_fstat(fd))
local buffer = assert(uv.fs_read(fd, stat.size, 0))
uv.fs_close(fd)
return buffer
end
---@param list unknown[]
---@return unknown[]
local function deduplicate(list)
local set = {}
local new_list = {}
for _, v in ipairs(list) do
if not set[v] then
table.insert(new_list, v)
set[v] = true
end
end
return new_list
end
---@return string[]
function M.get_dictionaries()
-- Workaround. vim.opt_global returns now a local value.
-- https://github.com/neovim/neovim/issues/21506
---@type string[]
local global = vim.split(vim.go.dictionary, ",")
---@type string[]
local local_ = vim.opt_local.dictionary:get()
local dict = {}
for _, al in ipairs({ global, local_ }) do
for _, d in ipairs(al) do
if vim.fn.filereadable(vim.fn.expand(d)) == 1 then
table.insert(dict, d)
end
end
end
dict = deduplicate(dict)
return dict
end
---@param vector string[]
---@param index integer
---@param key string
---@return boolean
local function ascending_order(vector, index, key)
return vector[index] >= key
end
---@param vector unknown[]
---@param key string
---@param cb fun(vec: unknown[], idx: integer, key: string): boolean
---@return integer
function M.binary_search(vector, key, cb)
local left = 0
local right = #vector
local isOK = cb or ascending_order
-- (left, right]
while right - left > 1 do
local mid = math.floor((left + right) / 2)
if isOK(vector, mid, key) then
right = mid
else
left = mid
end
end
return right
end
local timer = {}
local function stop(name)
if timer[name] then
timer[name]:stop()
timer[name]:close()
timer[name] = nil
end
end
function M.debounce(name, callback, timeout)
stop(name)
timer[name] = uv.new_timer()
timer[name]:start(
timeout,
0,
vim.schedule_wrap(function()
stop(name)
callback()
end)
)
end
M.bool_fn = setmetatable({}, {
__index = function(_, key)
return function(...)
local v = vim.fn[key](...)
if not v or v == 0 or v == "" then
return false
elseif type(v) == "table" and next(v) == nil then
return false
end
return true
end
end,
})
return M