From 91ffdead3291263a356a66e40c7e82cfa431107f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nguy=E1=BB=85n=20H=E1=BB=93ng=20Qu=C3=A2n?= Date: Mon, 15 Jul 2024 15:15:20 +0700 Subject: [PATCH] Sort completions by input resemblance. (#2018) * Sort completions by input resemblance. Fixes #2017 * Clean code --- AUTHORS.txt | 1 + jedi/api/completion.py | 8 +++++++- test/test_api/test_api.py | 13 +++++++++++-- 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/AUTHORS.txt b/AUTHORS.txt index 349a867b..3ccb0a7c 100644 --- a/AUTHORS.txt +++ b/AUTHORS.txt @@ -65,6 +65,7 @@ Code Contributors - Márcio Mazza (@marciomazza) - Martin Vielsmaier (@moser) - TingJia Wu (@WutingjiaX) +- Nguyễn Hồng Quân And a few more "anonymous" contributors. diff --git a/jedi/api/completion.py b/jedi/api/completion.py index 342f7506..064065d8 100644 --- a/jedi/api/completion.py +++ b/jedi/api/completion.py @@ -138,6 +138,11 @@ class Completion: self._fuzzy = fuzzy + # Return list of completions in this order: + # - Beginning with what user is typing + # - Public (alphabet) + # - Private ("_xxx") + # - Dunder ("__xxx") def complete(self): leaf = self._module_node.get_leaf_for_position( self._original_position, @@ -176,7 +181,8 @@ class Completion: return ( # Removing duplicates mostly to remove False/True/None duplicates. _remove_duplicates(prefixed_completions, completions) - + sorted(completions, key=lambda x: (x.name.startswith('__'), + + sorted(completions, key=lambda x: (not x.name.startswith(self._like_name), + x.name.startswith('__'), x.name.startswith('_'), x.name.lower())) ) diff --git a/test/test_api/test_api.py b/test/test_api/test_api.py index 55feaf8b..8ff559f6 100644 --- a/test/test_api/test_api.py +++ b/test/test_api/test_api.py @@ -321,10 +321,19 @@ def test_docstrings_for_completions(Script): assert isinstance(c.docstring(), str) +def test_completions_order_most_resemblance_on_top(Script): + """Test that the completion which resembles the in-typing the most will come first.""" + code = "from pathlib import Path\npath = Path('hello.txt')\n\npat" + script = Script(code) + # User is typing "pat" and "path" is closer to it than "Path". + assert ['path', 'Path'] == [comp.name for comp in script.complete()] + + def test_fuzzy_completion(Script): script = Script('string = "hello"\nstring.upper') - assert ['isupper', - 'upper'] == [comp.name for comp in script.complete(fuzzy=True)] + # 'isupper' is included because it is fuzzily matched. + assert ['upper', + 'isupper'] == [comp.name for comp in script.complete(fuzzy=True)] def test_math_fuzzy_completion(Script, environment):