Show More
@@ -2014,7 +2014,7 b' class IPCompleter(Completer):' | |||||
2014 |
|
2014 | |||
2015 | # Start with a clean slate of completions |
|
2015 | # Start with a clean slate of completions | |
2016 | matches = [] |
|
2016 | matches = [] | |
2017 | custom_res = self.dispatch_custom_completer(text) |
|
2017 | ||
2018 | # FIXME: we should extend our api to return a dict with completions for |
|
2018 | # FIXME: we should extend our api to return a dict with completions for | |
2019 | # different types of objects. The rlcomplete() method could then |
|
2019 | # different types of objects. The rlcomplete() method could then | |
2020 | # simply collapse the dict into a list for readline, but we'd have |
|
2020 | # simply collapse the dict into a list for readline, but we'd have | |
@@ -2025,13 +2025,7 b' class IPCompleter(Completer):' | |||||
2025 | full_text = line_buffer |
|
2025 | full_text = line_buffer | |
2026 | completions = self._jedi_matches( |
|
2026 | completions = self._jedi_matches( | |
2027 | cursor_pos, cursor_line, full_text) |
|
2027 | cursor_pos, cursor_line, full_text) | |
2028 | if custom_res is not None: |
|
2028 | ||
2029 | # did custom completers produce something? |
|
|||
2030 | matches = [(m, 'custom') for m in custom_res] |
|
|||
2031 | else: |
|
|||
2032 | # Extend the list of completions with the results of each |
|
|||
2033 | # matcher, so we return results to the user from all |
|
|||
2034 | # namespaces. |
|
|||
2035 |
|
|
2029 | if self.merge_completions: | |
2036 |
|
|
2030 | matches = [] | |
2037 |
|
|
2031 | for matcher in self.matchers: | |
@@ -2048,6 +2042,7 b' class IPCompleter(Completer):' | |||||
2048 |
|
|
2042 | for m in matcher(text)] | |
2049 |
|
|
2043 | if matches: | |
2050 |
|
|
2044 | break | |
|
2045 | ||||
2051 | seen = set() |
|
2046 | seen = set() | |
2052 | filtered_matches = set() |
|
2047 | filtered_matches = set() | |
2053 | for m in matches: |
|
2048 | for m in matches: | |
@@ -2056,10 +2051,13 b' class IPCompleter(Completer):' | |||||
2056 | filtered_matches.add(m) |
|
2051 | filtered_matches.add(m) | |
2057 | seen.add(t) |
|
2052 | seen.add(t) | |
2058 |
|
2053 | |||
2059 | _filtered_matches = sorted( |
|
2054 | _filtered_matches = sorted(filtered_matches, key=lambda x: completions_sorting_key(x[0])) | |
2060 | set(filtered_matches), key=lambda x: completions_sorting_key(x[0]))\ |
|
2055 | ||
2061 | [:MATCHES_LIMIT] |
|
2056 | custom_res = [(m, 'custom') for m in self.dispatch_custom_completer(text) or []] | |
|
2057 | ||||
|
2058 | _filtered_matches = custom_res or _filtered_matches | |||
2062 |
|
2059 | |||
|
2060 | _filtered_matches = _filtered_matches[:MATCHES_LIMIT] | |||
2063 | _matches = [m[0] for m in _filtered_matches] |
|
2061 | _matches = [m[0] for m in _filtered_matches] | |
2064 | origins = [m[1] for m in _filtered_matches] |
|
2062 | origins = [m[1] for m in _filtered_matches] | |
2065 |
|
2063 |
@@ -175,6 +175,20 b' class TestCompleter(unittest.TestCase):' | |||||
175 |
|
175 | |||
176 | ip.complete("x.") |
|
176 | ip.complete("x.") | |
177 |
|
177 | |||
|
178 | def test_custom_completion_ordering(self): | |||
|
179 | """Test that errors from custom attribute completers are silenced.""" | |||
|
180 | ip = get_ipython() | |||
|
181 | ||||
|
182 | _, matches = ip.complete('in') | |||
|
183 | assert matches.index('input') < matches.index('int') | |||
|
184 | ||||
|
185 | def complete_example(a): | |||
|
186 | return ['example2', 'example1'] | |||
|
187 | ||||
|
188 | ip.Completer.custom_completers.add_re('ex*', complete_example) | |||
|
189 | _, matches = ip.complete('ex') | |||
|
190 | assert matches.index('example2') < matches.index('example1') | |||
|
191 | ||||
178 | def test_unicode_completions(self): |
|
192 | def test_unicode_completions(self): | |
179 | ip = get_ipython() |
|
193 | ip = get_ipython() | |
180 | # Some strings that trigger different types of completion. Check them both |
|
194 | # Some strings that trigger different types of completion. Check them both |
General Comments 0
You need to be logged in to leave comments.
Login now