Add option for symbol matching logic. (#1515)

The no_symbol_match makes command line completion a lot less useful. It
disables any matches for file names with symbols in them. This prevents
completing things like ":b foo/bar" to ":b foo/bar.txt" or ":b foo_" to
":b baz/foo_bar.txt". Add an option `disallow_symbol_nonprefix_matching`
that prevents a match if it contains a symbol and isn't a prefix match.
Make that option the default. Add the option to documentation and tests.
Add to the examples for command line setup disabling the option.
This commit is contained in:
Kyle Butt 2024-03-21 12:00:36 -06:00 committed by GitHub
parent a1b4ef08c2
commit 6460f979b9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 27 additions and 5 deletions

View file

@ -116,7 +116,8 @@ lua <<EOF
{ name = 'path' }
}, {
{ name = 'cmdline' }
})
}),
matching = { disallow_symbol_nonprefix_matching = false }
})
-- Set up lspconfig.

View file

@ -123,7 +123,8 @@ A recommended configuration can be found below.
{ name = 'path' }
}, {
{ name = 'cmdline' }
})
}),
matching = { disallow_symbol_nonprefix_matching = false }
})
-- Setup lspconfig.
@ -560,6 +561,11 @@ matching.disallow_prefix_unmatching~
`boolean`
Whether to allow prefix unmatching.
cmp-config.matching.disallow_symbol_nonprefix_matching
matching.disallow_symbol_nonprefix_matching
`boolean`
Whether to allow symbols in matches if the match is not a prefix match.
*cmp-config.sorting.priority_weight*
sorting.priority_weight~
`number`

View file

@ -57,6 +57,7 @@ return function()
disallow_partial_fuzzy_matching = true,
disallow_partial_matching = false,
disallow_prefix_unmatching = false,
disallow_symbol_nonprefix_matching = true,
},
sorting = {

View file

@ -360,12 +360,13 @@ end
---@param matching_config cmp.MatchingConfig
---@return { score: integer, matches: table[] }
entry.match = function(self, input, matching_config)
return self.match_cache:ensure(input .. ':' .. (self.resolved_completion_item and '1' or '0' .. ':') .. (matching_config.disallow_fuzzy_matching and '1' or '0') .. ':' .. (matching_config.disallow_partial_fuzzy_matching and '1' or '0') .. ':' .. (matching_config.disallow_partial_matching and '1' or '0') .. ':' .. (matching_config.disallow_prefix_unmatching and '1' or '0'), function()
return self.match_cache:ensure(input .. ':' .. (self.resolved_completion_item and '1' or '0' .. ':') .. (matching_config.disallow_fuzzy_matching and '1' or '0') .. ':' .. (matching_config.disallow_partial_fuzzy_matching and '1' or '0') .. ':' .. (matching_config.disallow_partial_matching and '1' or '0') .. ':' .. (matching_config.disallow_prefix_unmatching and '1' or '0') .. ':' .. (matching_config.disallow_symbol_nonprefix_matching and '1' or '0'), function()
local option = {
disallow_fuzzy_matching = matching_config.disallow_fuzzy_matching,
disallow_partial_fuzzy_matching = matching_config.disallow_partial_fuzzy_matching,
disallow_partial_matching = matching_config.disallow_partial_matching,
disallow_prefix_unmatching = matching_config.disallow_prefix_unmatching,
disallow_symbol_nonprefix_matching = matching_config.disallow_symbol_nonprefix_matching,
synonyms = {
self:get_word(),
self:get_completion_item().label,

View file

@ -73,12 +73,15 @@ end
-- `,` -> print,
-- ~
-- * Typically, the middle match with symbol characters only is false positive. should be ignored.
-- This doesn't work for command line completions like ":b foo_" which we like to match
-- "lib/foo_bar.txt". The option disallow_symbol_nonprefix_matching controls this and defaults
-- to preventing matches like these. The documentation recommends it for command line completion.
--
--
---Match entry
---@param input string
---@param word string
---@param option { synonyms: string[], disallow_fullfuzzy_matching: boolean, disallow_fuzzy_matching: boolean, disallow_partial_fuzzy_matching: boolean, disallow_partial_matching: boolean, disallow_prefix_unmatching: boolean }
---@param option { synonyms: string[], disallow_fullfuzzy_matching: boolean, disallow_fuzzy_matching: boolean, disallow_partial_fuzzy_matching: boolean, disallow_partial_matching: boolean, disallow_prefix_unmatching: boolean, disallow_symbol_nonprefix_matching: boolean }
---@return integer, table
matcher.match = function(input, word, option)
option = option or {}
@ -160,7 +163,9 @@ matcher.match = function(input, word, option)
end
if no_symbol_match and not prefix then
return 0, {}
if option.disallow_symbol_nonprefix_matching then
return 0, {}
end
end
-- Compute prefix match score

View file

@ -49,6 +49,7 @@ describe('matcher', function()
disallow_partial_matching = false,
disallow_prefix_unmatching = false,
disallow_partial_fuzzy_matching = false,
disallow_symbol_nonprefix_matching = true,
})
assert.is.truthy(score >= 1)
assert.equals(matches[1].word_match_start, 5)
@ -58,6 +59,7 @@ describe('matcher', function()
disallow_partial_matching = false,
disallow_prefix_unmatching = false,
disallow_partial_fuzzy_matching = true,
disallow_symbol_nonprefix_matching = true,
})
assert.is.truthy(score == 0)
end)
@ -84,6 +86,11 @@ describe('matcher', function()
assert.is.truthy(matcher.match('bar', 'foo_bar', { disallow_prefix_unmatching = false }) >= 1)
end)
it('disallow_symbol_nonprefix_matching', function()
assert.is.truthy(matcher.match('foo_', 'b foo_bar', { disallow_symbol_nonprefix_matching = true }) == 0)
assert.is.truthy(matcher.match('foo_', 'b foo_bar', { disallow_symbol_nonprefix_matching = false }) >= 1)
end)
it('debug', function()
matcher.debug = function(...)
print(vim.inspect({ ... }))

View file

@ -137,6 +137,7 @@ cmp.ItemField = {
---@field public disallow_partial_fuzzy_matching boolean
---@field public disallow_partial_matching boolean
---@field public disallow_prefix_unmatching boolean
---@field public disallow_symbol_nonprefix_matching boolean
---@class cmp.SortingConfig
---@field public priority_weight integer