mirror of
https://github.com/SpaceVim/SpaceVim.git
synced 2025-01-24 02:20:03 +08:00
126 lines
2.9 KiB
Lua
126 lines
2.9 KiB
Lua
local source = {}
|
|
|
|
local utf8 = require("cmp_dictionary.lib.utf8")
|
|
local config = require("cmp_dictionary.config")
|
|
local caches = require("cmp_dictionary.caches")
|
|
local db = require("cmp_dictionary.db")
|
|
|
|
function source.new()
|
|
return setmetatable({}, { __index = source })
|
|
end
|
|
|
|
---@return string
|
|
function source.get_keyword_pattern()
|
|
return [[\k\+]]
|
|
end
|
|
|
|
local candidate_cache = {
|
|
req = "",
|
|
items = {},
|
|
}
|
|
|
|
---@param str string
|
|
---@return boolean
|
|
local function is_capital(str)
|
|
return str:find("^%u") and true or false
|
|
end
|
|
|
|
---@param str string
|
|
---@return string
|
|
local function to_lower_first(str)
|
|
local l = str:gsub("^.", string.lower)
|
|
return l
|
|
end
|
|
|
|
---@param str string
|
|
---@return string
|
|
local function to_upper_first(str)
|
|
local u = str:gsub("^.", string.upper)
|
|
return u
|
|
end
|
|
|
|
---@param req string
|
|
---@param isIncomplete boolean
|
|
---@return table
|
|
function source.get_candidate(req, isIncomplete)
|
|
if candidate_cache.req == req then
|
|
return { items = candidate_cache.items, isIncomplete = isIncomplete }
|
|
end
|
|
|
|
local items
|
|
local request = config.get("sqlite") and db.request or caches.request
|
|
items, isIncomplete = request(req, isIncomplete)
|
|
|
|
if config.get("first_case_insensitive") then
|
|
local pre, post = to_upper_first, to_lower_first
|
|
if is_capital(req) then
|
|
pre, post = post, pre
|
|
end
|
|
for _, item in ipairs(request(pre(req), isIncomplete)) do
|
|
table.insert(items, { label = post(item.label), detail = item.detail })
|
|
end
|
|
end
|
|
|
|
candidate_cache.req = req
|
|
candidate_cache.items = items
|
|
|
|
return { items = items, isIncomplete = isIncomplete }
|
|
end
|
|
|
|
---@param request cmp.SourceCompletionApiParams
|
|
---@param callback fun(response: lsp.CompletionResponse|nil)
|
|
function source.complete(_, request, callback)
|
|
-- Clear the cache since the dictionary has been updated.
|
|
if config.get("sqlite") then
|
|
if db.is_just_updated() then
|
|
candidate_cache = {}
|
|
end
|
|
else
|
|
if caches.is_just_updated() then
|
|
candidate_cache = {}
|
|
end
|
|
end
|
|
|
|
local exact = config.get("exact")
|
|
|
|
---@type string
|
|
local line = request.context.cursor_before_line
|
|
local offset = request.offset
|
|
line = line:sub(offset)
|
|
if line == "" then
|
|
return
|
|
end
|
|
|
|
local req, isIncomplete
|
|
if exact > 0 then
|
|
local line_len = utf8.len(line)
|
|
if line_len <= exact then
|
|
req = line
|
|
isIncomplete = line_len < exact
|
|
else
|
|
local last = exact
|
|
if line_len ~= #line then
|
|
last = utf8.offset(line, exact + 1) - 1
|
|
end
|
|
req = line:sub(1, last)
|
|
isIncomplete = false
|
|
end
|
|
else
|
|
-- must be -1
|
|
req = line
|
|
isIncomplete = true
|
|
end
|
|
|
|
callback(source.get_candidate(req, isIncomplete))
|
|
end
|
|
|
|
function source.resolve(_, completion_item, callback)
|
|
if config.get("sqlite") then
|
|
db.document(completion_item, callback)
|
|
else
|
|
require("cmp_dictionary.document")(completion_item, callback)
|
|
end
|
|
end
|
|
|
|
return source
|