Improve matching and sorting on specific cases
This commit is contained in:
@@ -58,7 +58,6 @@ return function()
|
|||||||
return diff
|
return diff
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return true
|
|
||||||
end)
|
end)
|
||||||
return entries
|
return entries
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
local char = require('cmp.utils.char')
|
local char = require('cmp.utils.char')
|
||||||
|
local str = require('cmp.utils.str')
|
||||||
|
|
||||||
local matcher = {}
|
local matcher = {}
|
||||||
|
|
||||||
@@ -72,8 +73,9 @@ end
|
|||||||
---Match entry
|
---Match entry
|
||||||
---@param input string
|
---@param input string
|
||||||
---@param word string
|
---@param word string
|
||||||
|
---@param words string[]
|
||||||
---@return number
|
---@return number
|
||||||
matcher.match = function(input, word)
|
matcher.match = function(input, word, words)
|
||||||
-- Empty input
|
-- Empty input
|
||||||
if #input == 0 then
|
if #input == 0 then
|
||||||
return matcher.PREFIX_FACTOR + matcher.NOT_FUZZY_FACTOR
|
return matcher.PREFIX_FACTOR + matcher.NOT_FUZZY_FACTOR
|
||||||
@@ -108,8 +110,22 @@ matcher.match = function(input, word)
|
|||||||
return 0
|
return 0
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Add prefix bonus
|
||||||
|
local prefix = false
|
||||||
|
if matches[1].input_match_start == 1 and matches[1].word_match_start == 1 then
|
||||||
|
prefix = true
|
||||||
|
else
|
||||||
|
for _, w in ipairs(words or {}) do
|
||||||
|
if str.has_prefix(w, string.sub(input, matches[1].input_match_start, matches[1].input_match_end)) then
|
||||||
|
prefix = true
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
-- Compute prefix match score
|
-- Compute prefix match score
|
||||||
local score = 0
|
local score = prefix and matcher.PREFIX_FACTOR or 0
|
||||||
|
local boundary_fixer = prefix and matches[1].index - 1 or 0
|
||||||
local idx = 1
|
local idx = 1
|
||||||
for _, m in ipairs(matches) do
|
for _, m in ipairs(matches) do
|
||||||
local s = 0
|
local s = 0
|
||||||
@@ -119,14 +135,11 @@ matcher.match = function(input, word)
|
|||||||
end
|
end
|
||||||
idx = idx + 1
|
idx = idx + 1
|
||||||
if s > 0 then
|
if s > 0 then
|
||||||
score = score + (s * (1 + math.max(0, matcher.WORD_BOUNDALY_ORDER_FACTOR - m.index) / matcher.WORD_BOUNDALY_ORDER_FACTOR))
|
score = score + (s * (1 + math.max(0, matcher.WORD_BOUNDALY_ORDER_FACTOR - (m.index - boundary_fixer)) / matcher.WORD_BOUNDALY_ORDER_FACTOR))
|
||||||
score = score + (m.strict_match and 0.1 or 0)
|
score = score + (m.strict_match and 0.1 or 0)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Add prefix bonus
|
|
||||||
score = score + ((matches[1].input_match_start == 1 and matches[1].word_match_start == 1) and matcher.PREFIX_FACTOR or 0)
|
|
||||||
|
|
||||||
-- Check remaining input as fuzzy
|
-- Check remaining input as fuzzy
|
||||||
if matches[#matches].input_match_end < #input then
|
if matches[#matches].input_match_end < #input then
|
||||||
if matcher.fuzzy(input, word, matches) then
|
if matcher.fuzzy(input, word, matches) then
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ describe('matcher', function()
|
|||||||
assert.is.truthy(matcher.match('candlesingle', 'candle#accept#single') >= 1)
|
assert.is.truthy(matcher.match('candlesingle', 'candle#accept#single') >= 1)
|
||||||
assert.is.truthy(matcher.match('conso', 'console') > matcher.match('conso', 'ConstantSourceNode'))
|
assert.is.truthy(matcher.match('conso', 'console') > matcher.match('conso', 'ConstantSourceNode'))
|
||||||
assert.is.truthy(matcher.match('var_', 'var_dump') >= 1)
|
assert.is.truthy(matcher.match('var_', 'var_dump') >= 1)
|
||||||
|
assert.is.truthy(matcher.match('my_', 'my_awesome_variable') > matcher.match('my_', 'completion_matching_strategy_list'))
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it('debug', function()
|
it('debug', function()
|
||||||
|
|||||||
@@ -112,9 +112,10 @@ source.get_entries = function(self, ctx)
|
|||||||
if not inputs[o] then
|
if not inputs[o] then
|
||||||
inputs[o] = string.sub(ctx.cursor_before_line, o)
|
inputs[o] = string.sub(ctx.cursor_before_line, o)
|
||||||
end
|
end
|
||||||
e.score = matcher.match(inputs[o], e:get_filter_text())
|
e.score = matcher.match(inputs[o], e:get_filter_text(), { e:get_word() })
|
||||||
e.exact = inputs[o] == e:get_filter_text()
|
e.exact = false
|
||||||
if e.score >= 1 then
|
if e.score >= 1 then
|
||||||
|
e.exact = vim.tbl_contains({ e:get_filter_text(), e:get_word() }, inputs[o])
|
||||||
table.insert(entries, e)
|
table.insert(entries, e)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user