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:
@@ -116,7 +116,8 @@ lua <<EOF
|
|||||||
{ name = 'path' }
|
{ name = 'path' }
|
||||||
}, {
|
}, {
|
||||||
{ name = 'cmdline' }
|
{ name = 'cmdline' }
|
||||||
})
|
}),
|
||||||
|
matching = { disallow_symbol_nonprefix_matching = false }
|
||||||
})
|
})
|
||||||
|
|
||||||
-- Set up lspconfig.
|
-- Set up lspconfig.
|
||||||
|
|||||||
@@ -123,7 +123,8 @@ A recommended configuration can be found below.
|
|||||||
{ name = 'path' }
|
{ name = 'path' }
|
||||||
}, {
|
}, {
|
||||||
{ name = 'cmdline' }
|
{ name = 'cmdline' }
|
||||||
})
|
}),
|
||||||
|
matching = { disallow_symbol_nonprefix_matching = false }
|
||||||
})
|
})
|
||||||
|
|
||||||
-- Setup lspconfig.
|
-- Setup lspconfig.
|
||||||
@@ -560,6 +561,11 @@ matching.disallow_prefix_unmatching~
|
|||||||
`boolean`
|
`boolean`
|
||||||
Whether to allow prefix unmatching.
|
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*
|
*cmp-config.sorting.priority_weight*
|
||||||
sorting.priority_weight~
|
sorting.priority_weight~
|
||||||
`number`
|
`number`
|
||||||
|
|||||||
@@ -57,6 +57,7 @@ return function()
|
|||||||
disallow_partial_fuzzy_matching = true,
|
disallow_partial_fuzzy_matching = true,
|
||||||
disallow_partial_matching = false,
|
disallow_partial_matching = false,
|
||||||
disallow_prefix_unmatching = false,
|
disallow_prefix_unmatching = false,
|
||||||
|
disallow_symbol_nonprefix_matching = true,
|
||||||
},
|
},
|
||||||
|
|
||||||
sorting = {
|
sorting = {
|
||||||
|
|||||||
@@ -360,12 +360,13 @@ end
|
|||||||
---@param matching_config cmp.MatchingConfig
|
---@param matching_config cmp.MatchingConfig
|
||||||
---@return { score: integer, matches: table[] }
|
---@return { score: integer, matches: table[] }
|
||||||
entry.match = function(self, input, matching_config)
|
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 = {
|
local option = {
|
||||||
disallow_fuzzy_matching = matching_config.disallow_fuzzy_matching,
|
disallow_fuzzy_matching = matching_config.disallow_fuzzy_matching,
|
||||||
disallow_partial_fuzzy_matching = matching_config.disallow_partial_fuzzy_matching,
|
disallow_partial_fuzzy_matching = matching_config.disallow_partial_fuzzy_matching,
|
||||||
disallow_partial_matching = matching_config.disallow_partial_matching,
|
disallow_partial_matching = matching_config.disallow_partial_matching,
|
||||||
disallow_prefix_unmatching = matching_config.disallow_prefix_unmatching,
|
disallow_prefix_unmatching = matching_config.disallow_prefix_unmatching,
|
||||||
|
disallow_symbol_nonprefix_matching = matching_config.disallow_symbol_nonprefix_matching,
|
||||||
synonyms = {
|
synonyms = {
|
||||||
self:get_word(),
|
self:get_word(),
|
||||||
self:get_completion_item().label,
|
self:get_completion_item().label,
|
||||||
|
|||||||
@@ -73,12 +73,15 @@ end
|
|||||||
-- `,` -> print,
|
-- `,` -> print,
|
||||||
-- ~
|
-- ~
|
||||||
-- * Typically, the middle match with symbol characters only is false positive. should be ignored.
|
-- * 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
|
---Match entry
|
||||||
---@param input string
|
---@param input string
|
||||||
---@param word 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
|
---@return integer, table
|
||||||
matcher.match = function(input, word, option)
|
matcher.match = function(input, word, option)
|
||||||
option = option or {}
|
option = option or {}
|
||||||
@@ -160,8 +163,10 @@ matcher.match = function(input, word, option)
|
|||||||
end
|
end
|
||||||
|
|
||||||
if no_symbol_match and not prefix then
|
if no_symbol_match and not prefix then
|
||||||
|
if option.disallow_symbol_nonprefix_matching then
|
||||||
return 0, {}
|
return 0, {}
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
-- Compute prefix match score
|
-- Compute prefix match score
|
||||||
local score = prefix and matcher.PREFIX_FACTOR or 0
|
local score = prefix and matcher.PREFIX_FACTOR or 0
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ describe('matcher', function()
|
|||||||
disallow_partial_matching = false,
|
disallow_partial_matching = false,
|
||||||
disallow_prefix_unmatching = false,
|
disallow_prefix_unmatching = false,
|
||||||
disallow_partial_fuzzy_matching = false,
|
disallow_partial_fuzzy_matching = false,
|
||||||
|
disallow_symbol_nonprefix_matching = true,
|
||||||
})
|
})
|
||||||
assert.is.truthy(score >= 1)
|
assert.is.truthy(score >= 1)
|
||||||
assert.equals(matches[1].word_match_start, 5)
|
assert.equals(matches[1].word_match_start, 5)
|
||||||
@@ -58,6 +59,7 @@ describe('matcher', function()
|
|||||||
disallow_partial_matching = false,
|
disallow_partial_matching = false,
|
||||||
disallow_prefix_unmatching = false,
|
disallow_prefix_unmatching = false,
|
||||||
disallow_partial_fuzzy_matching = true,
|
disallow_partial_fuzzy_matching = true,
|
||||||
|
disallow_symbol_nonprefix_matching = true,
|
||||||
})
|
})
|
||||||
assert.is.truthy(score == 0)
|
assert.is.truthy(score == 0)
|
||||||
end)
|
end)
|
||||||
@@ -84,6 +86,11 @@ describe('matcher', function()
|
|||||||
assert.is.truthy(matcher.match('bar', 'foo_bar', { disallow_prefix_unmatching = false }) >= 1)
|
assert.is.truthy(matcher.match('bar', 'foo_bar', { disallow_prefix_unmatching = false }) >= 1)
|
||||||
end)
|
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()
|
it('debug', function()
|
||||||
matcher.debug = function(...)
|
matcher.debug = function(...)
|
||||||
print(vim.inspect({ ... }))
|
print(vim.inspect({ ... }))
|
||||||
|
|||||||
@@ -137,6 +137,7 @@ cmp.ItemField = {
|
|||||||
---@field public disallow_partial_fuzzy_matching boolean
|
---@field public disallow_partial_fuzzy_matching boolean
|
||||||
---@field public disallow_partial_matching boolean
|
---@field public disallow_partial_matching boolean
|
||||||
---@field public disallow_prefix_unmatching boolean
|
---@field public disallow_prefix_unmatching boolean
|
||||||
|
---@field public disallow_symbol_nonprefix_matching boolean
|
||||||
|
|
||||||
---@class cmp.SortingConfig
|
---@class cmp.SortingConfig
|
||||||
---@field public priority_weight integer
|
---@field public priority_weight integer
|
||||||
|
|||||||
Reference in New Issue
Block a user