Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add exact match comparator #1099

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions lua/blink/cmp/config/fuzzy.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
--- @field use_frecency boolean Tracks the most recently/frequently used items and boosts the score of the item
--- @field use_proximity boolean Boosts the score of items matching nearby words
--- @field use_unsafe_no_lock boolean UNSAFE!! When enabled, disables the lock and fsync when writing to the frecency database. This should only be used on unsupported platforms (i.e. alpine termux)
--- @field sorts ("label" | "sort_text" | "kind" | "score" | blink.cmp.SortFunction)[] Controls which sorts to use and in which order, these three are currently the only allowed options
--- @field sorts ("label" | "sort_text" | "kind" | "score" | "exact" | blink.cmp.SortFunction)[] Controls which sorts to use and in which order, these three are currently the only allowed options
--- @field prebuilt_binaries blink.cmp.PrebuiltBinariesConfig

--- @class (exact) blink.cmp.PrebuiltBinariesConfig
Expand All @@ -28,7 +28,7 @@ local fuzzy = {
use_frecency = true,
use_proximity = true,
use_unsafe_no_lock = false,
sorts = { 'score', 'sort_text' },
sorts = { 'exact', 'score', 'sort_text' },
prebuilt_binaries = {
download = true,
ignore_version_mismatch = false,
Expand All @@ -53,13 +53,16 @@ function fuzzy.validate(config)
config.sorts,
function(sorts)
for _, sort in ipairs(sorts) do
if not vim.tbl_contains({ 'label', 'sort_text', 'kind', 'score' }, sort) and type(sort) ~= 'function' then
if
not vim.tbl_contains({ 'label', 'sort_text', 'kind', 'score', 'exact' }, sort)
and type(sort) ~= 'function'
then
return false
end
end
return true
end,
'one of: "label", "sort_text", "kind", "score" or a function',
'one of: "label", "sort_text", "kind", "score", "exact" or a function',
},
prebuilt_binaries = { config.prebuilt_binaries, 'table' },
}, config)
Expand Down
3 changes: 2 additions & 1 deletion lua/blink/cmp/fuzzy/fuzzy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ pub fn fuzzy(
haystack: &[LspItem],
frecency: &FrecencyTracker,
opts: FuzzyOptions,
) -> (Vec<i32>, Vec<u32>) {
) -> (Vec<i32>, Vec<u32>, Vec<bool>) {
let haystack_labels = haystack
.iter()
.map(|s| s.filter_text.clone().unwrap_or(s.label.clone()))
Expand Down Expand Up @@ -128,6 +128,7 @@ pub fn fuzzy(
.iter()
.map(|mtch| mtch.index_in_haystack as u32)
.collect::<Vec<_>>(),
matches.iter().map(|mtch| mtch.exact).collect::<Vec<_>>(),
)
}

Expand Down
6 changes: 4 additions & 2 deletions lua/blink/cmp/fuzzy/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,12 @@ function fuzzy.fuzzy(line, cursor_col, haystacks_by_provider, range)
local keyword_start_col, keyword_end_col =
require('blink.cmp.fuzzy').get_keyword_range(line, cursor_col, config.completion.keyword.range)
local keyword_length = keyword_end_col - keyword_start_col
local keyword = line:sub(keyword_start_col, keyword_end_col - 1)
local keyword = line:sub(keyword_start_col, keyword_end_col)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm certain that the keyword is always truncated by one character on the right, but I'm not sure if I'm fixing it in the right place. I would appreciate it if you could take a look at this with your understanding of the code's semantics as its author.


local filtered_items = {}
for provider_id, haystack in pairs(haystacks_by_provider) do
-- perform fuzzy search
local scores, matched_indices = fuzzy.rust.fuzzy(line, cursor_col, provider_id, {
local scores, matched_indices, exacts = fuzzy.rust.fuzzy(line, cursor_col, provider_id, {
-- TODO: make this configurable
max_typos = config.fuzzy.max_typos(keyword),
use_frecency = config.fuzzy.use_frecency and keyword_length > 0,
Expand All @@ -86,7 +86,9 @@ function fuzzy.fuzzy(line, cursor_col, haystacks_by_provider, range)

for idx, item_index in ipairs(matched_indices) do
local item = haystack[item_index + 1]
--TODO: maybe we should declare these fields in `blink.cmp.CompletionItem`?
item.score = scores[idx]
item.exact = exacts[idx]
table.insert(filtered_items, item)
end
end
Expand Down
2 changes: 1 addition & 1 deletion lua/blink/cmp/fuzzy/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ pub fn set_provider_items(
pub fn fuzzy(
_lua: &Lua,
(line, cursor_col, provider_id, opts): (mlua::String, usize, String, FuzzyOptions),
) -> LuaResult<(Vec<i32>, Vec<u32>)> {
) -> LuaResult<(Vec<i32>, Vec<u32>, Vec<bool>)> {
let frecency = FRECENCY.read().map_err(|_| Error::AcquireFrecencyLock)?;
let frecency = frecency.as_ref().ok_or(Error::UseFrecencyBeforeInit)?;

Expand Down
6 changes: 5 additions & 1 deletion lua/blink/cmp/fuzzy/sort.lua
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
local sort = {}

--- @param list blink.cmp.CompletionItem[]
--- @param funcs ("label" | "sort_text" | "kind" | "score" | blink.cmp.SortFunction)[]
--- @param funcs ("label" | "sort_text" | "kind" | "score" | "exact" | blink.cmp.SortFunction)[]
--- @return blink.cmp.CompletionItem[]
function sort.sort(list, funcs)
local sorting_funcs = vim.tbl_map(
Expand All @@ -17,6 +17,10 @@ function sort.sort(list, funcs)
return list
end

function sort.exact(a, b)
if a.exact ~= b.exact then return a.exact end
end

function sort.score(a, b)
if a.score == b.score then return end
return a.score > b.score
Expand Down