diff --git a/jedi/api/completion.py b/jedi/api/completion.py index d5c9182b..7a3c9c88 100644 --- a/jedi/api/completion.py +++ b/jedi/api/completion.py @@ -27,6 +27,22 @@ def get_call_signature_param_names(call_signatures): Parameter.KEYWORD_ONLY): yield p._name +def start_match(string, like_name): + return string.startswith(like_name) + + +def substr_match(string, like_name): + return like_name in string + + +def fuzzy_match(string, like_name): + if len(like_name) <= 1: + return like_name in string + pos = string.find(like_name[0]) + if pos >= 0: + return fuzzy_match(string[pos + 1:], like_name[1:]) + return False + def filter_names(inference_state, completion_names, stack, like_name): comp_dct = {} @@ -37,7 +53,7 @@ def filter_names(inference_state, completion_names, stack, like_name): if settings.case_insensitive_completion: string = string.lower() - if string.startswith(like_name): + if fuzzy_match(string, like_name): new = classes.Completion( inference_state, name, diff --git a/test/test_api/test_completion.py b/test/test_api/test_completion.py index 1d3d092b..d0da4864 100644 --- a/test/test_api/test_completion.py +++ b/test/test_api/test_completion.py @@ -267,3 +267,18 @@ def test_file_path_completions(Script, file, code, column, expected): assert len(comps) > 100 # This is basically global completions. else: assert [c.complete for c in comps] == expected + +from jedi.api.completion import start_match, substr_match, fuzzy_match + +def test_start_match(): + assert start_match('Condition', 'C') + +def test_substr_match(): + assert substr_match('Condition', 'dit') + +def test_fuzzy_match(): + assert fuzzy_match('Condition', 'i') + assert not fuzzy_match('Condition', 'p') + assert fuzzy_match('Condition', 'ii') + assert not fuzzy_match('Condition', 'Ciito') + assert fuzzy_match('Condition', 'Cdiio')