summaryrefslogtreecommitdiff
path: root/script/core
diff options
context:
space:
mode:
author最萌小汐 <sumneko@hotmail.com>2021-08-23 20:24:58 +0800
committer最萌小汐 <sumneko@hotmail.com>2021-08-23 20:24:58 +0800
commitd84b3137321e6d61e165b8450236c879aee6360f (patch)
treef5b8ecb9a68567cc39af2b5afb791066b0b65698 /script/core
parent6cbd142a48eec2eff2ffdc02a7bbf7b7ee6f0152 (diff)
downloadlua-language-server-d84b3137321e6d61e165b8450236c879aee6360f.zip
completion: improve misspelling results
Diffstat (limited to 'script/core')
-rw-r--r--script/core/matchkey.lua76
1 files changed, 61 insertions, 15 deletions
diff --git a/script/core/matchkey.lua b/script/core/matchkey.lua
index 83977496..eb67dac6 100644
--- a/script/core/matchkey.lua
+++ b/script/core/matchkey.lua
@@ -1,25 +1,44 @@
+local lowers = {}
+local uppers = {}
+for c in ('abcdefghijklmnopqrstuvwxyz'):gmatch '.' do
+ lowers[c] = true
+ uppers[c:upper()] = true
+end
+
---@param input string
---@param other string
----@param fast boolean
----@return boolean isMatch
----@return number deviation
-return function (input, other, fast)
- if input == other then
- return true, 0
+local function isValidFirstChar(input, other)
+ local first = input:sub(1, 1):upper()
+ if first == other:sub(1, 1):upper() then
+ return true
end
- if input == '' then
- return true, 0
+ local pos, char = other:find(first, 2, true)
+ if not pos and uppers[first] then
+ -- word after symbol?
+ if other:find('%A' .. first:lower(), 2) then
+ return true
+ end
end
- if #input > #other then
- return false, 0
+ if not char then
+ return false
+ end
+ -- symbol?
+ if not uppers[char] then
+ return true
+ end
+ -- word boundary?
+ local beforeChar = other:sub(pos - 1, pos - 1)
+ if not uppers[beforeChar] then
+ return true
end
+ return false
+end
+
+local function isAlmostSame(input, other)
local lMe = input:lower()
local lOther = other:lower()
if lMe == lOther:sub(1, #lMe) then
- return true, 0
- end
- if fast and input:sub(1, 1) ~= other:sub(1, 1) then
- return false, 0
+ return true
end
local chars = {}
for i = 1, #lOther do
@@ -31,8 +50,35 @@ return function (input, other, fast)
if chars[c] and chars[c] > 0 then
chars[c] = chars[c] - 1
else
- return false, 0
+ return false
end
end
+ return true
+end
+
+---@param input string
+---@param other string
+---@param fast boolean
+---@return boolean isMatch
+---@return number deviation
+return function (input, other, fast)
+ if input == other then
+ return true, 0
+ end
+ if input == '' then
+ return true, 0
+ end
+ if #input > #other then
+ return false, 0
+ end
+ if fast and input:sub(1, 1) ~= other:sub(1, 1) then
+ return false, 0
+ end
+ if not isValidFirstChar(input, other) then
+ return false, 0
+ end
+ if not isAlmostSame(input, other) then
+ return false, 0
+ end
return true, 1
end