Show More
@@ -35,7 +35,7 b' or using unicode completion:' | |||||
35 |
|
35 | |||
36 | .. code:: |
|
36 | .. code:: | |
37 |
|
37 | |||
38 | \\greek small letter alpha<tab> |
|
38 | \\GREEK SMALL LETTER ALPHA<tab> | |
39 | Ξ± |
|
39 | Ξ± | |
40 |
|
40 | |||
41 |
|
41 | |||
@@ -121,6 +121,7 b' import string' | |||||
121 | import sys |
|
121 | import sys | |
122 | import time |
|
122 | import time | |
123 | import unicodedata |
|
123 | import unicodedata | |
|
124 | import uuid | |||
124 | import warnings |
|
125 | import warnings | |
125 | from contextlib import contextmanager |
|
126 | from contextlib import contextmanager | |
126 | from importlib import import_module |
|
127 | from importlib import import_module | |
@@ -133,8 +134,9 b' from IPython.core.latex_symbols import latex_symbols, reverse_latex_symbol' | |||||
133 | from IPython.core.oinspect import InspectColors |
|
134 | from IPython.core.oinspect import InspectColors | |
134 | from IPython.utils import generics |
|
135 | from IPython.utils import generics | |
135 | from IPython.utils.dir2 import dir2, get_real_method |
|
136 | from IPython.utils.dir2 import dir2, get_real_method | |
|
137 | from IPython.utils.path import ensure_dir_exists | |||
136 | from IPython.utils.process import arg_split |
|
138 | from IPython.utils.process import arg_split | |
137 | from traitlets import Bool, Enum, Int, observe |
|
139 | from traitlets import Bool, Enum, Int, List as ListTrait, Unicode, default, observe | |
138 | from traitlets.config.configurable import Configurable |
|
140 | from traitlets.config.configurable import Configurable | |
139 |
|
141 | |||
140 | import __main__ |
|
142 | import __main__ | |
@@ -1003,8 +1005,6 b' def _make_signature(completion)-> str:' | |||||
1003 | class IPCompleter(Completer): |
|
1005 | class IPCompleter(Completer): | |
1004 | """Extension of the completer class with IPython-specific features""" |
|
1006 | """Extension of the completer class with IPython-specific features""" | |
1005 |
|
1007 | |||
1006 | _names = None |
|
|||
1007 |
|
||||
1008 | @observe('greedy') |
|
1008 | @observe('greedy') | |
1009 | def _greedy_changed(self, change): |
|
1009 | def _greedy_changed(self, change): | |
1010 | """update the splitter and readline delims when greedy is changed""" |
|
1010 | """update the splitter and readline delims when greedy is changed""" | |
@@ -1049,6 +1049,16 b' class IPCompleter(Completer):' | |||||
1049 | """, |
|
1049 | """, | |
1050 | ).tag(config=True) |
|
1050 | ).tag(config=True) | |
1051 |
|
1051 | |||
|
1052 | profile_completions = Bool( | |||
|
1053 | default_value=False, | |||
|
1054 | help="If True, emit profiling data for completion subsystem using cProfile." | |||
|
1055 | ).tag(config=True) | |||
|
1056 | ||||
|
1057 | profiler_output_dir = Unicode( | |||
|
1058 | default_value=".completion_profiles", | |||
|
1059 | help="Template for path at which to output profile data for completions." | |||
|
1060 | ).tag(config=True) | |||
|
1061 | ||||
1052 | @observe('limit_to__all__') |
|
1062 | @observe('limit_to__all__') | |
1053 | def _limit_to_all_changed(self, change): |
|
1063 | def _limit_to_all_changed(self, change): | |
1054 | warnings.warn('`IPython.core.IPCompleter.limit_to__all__` configuration ' |
|
1064 | warnings.warn('`IPython.core.IPCompleter.limit_to__all__` configuration ' | |
@@ -1126,6 +1136,12 b' class IPCompleter(Completer):' | |||||
1126 | # This is set externally by InteractiveShell |
|
1136 | # This is set externally by InteractiveShell | |
1127 | self.custom_completers = None |
|
1137 | self.custom_completers = None | |
1128 |
|
1138 | |||
|
1139 | # This is a list of names of unicode characters that can be completed | |||
|
1140 | # into their corresponding unicode value. The list is large, so we | |||
|
1141 | # laziliy initialize it on first use. Consuming code should access this | |||
|
1142 | # attribute through the `@unicode_names` property. | |||
|
1143 | self._unicode_names = None | |||
|
1144 | ||||
1129 | @property |
|
1145 | @property | |
1130 | def matchers(self): |
|
1146 | def matchers(self): | |
1131 | """All active matcher routines for completion""" |
|
1147 | """All active matcher routines for completion""" | |
@@ -1824,6 +1840,13 b' class IPCompleter(Completer):' | |||||
1824 |
|
1840 | |||
1825 | seen = set() |
|
1841 | seen = set() | |
1826 | try: |
|
1842 | try: | |
|
1843 | if self.profile_completions: | |||
|
1844 | import cProfile | |||
|
1845 | profiler = cProfile.Profile() | |||
|
1846 | profiler.enable() | |||
|
1847 | else: | |||
|
1848 | profiler = None | |||
|
1849 | ||||
1827 | for c in self._completions(text, offset, _timeout=self.jedi_compute_type_timeout/1000): |
|
1850 | for c in self._completions(text, offset, _timeout=self.jedi_compute_type_timeout/1000): | |
1828 | if c and (c in seen): |
|
1851 | if c and (c in seen): | |
1829 | continue |
|
1852 | continue | |
@@ -1833,6 +1856,13 b' class IPCompleter(Completer):' | |||||
1833 | """if completions take too long and users send keyboard interrupt, |
|
1856 | """if completions take too long and users send keyboard interrupt, | |
1834 | do not crash and return ASAP. """ |
|
1857 | do not crash and return ASAP. """ | |
1835 | pass |
|
1858 | pass | |
|
1859 | finally: | |||
|
1860 | if profiler is not None: | |||
|
1861 | profiler.disable() | |||
|
1862 | ensure_dir_exists(self.profiler_output_dir) | |||
|
1863 | output_path = os.path.join(self.profiler_output_dir, str(uuid.uuid4())) | |||
|
1864 | print("Writing profiler output to", output_path) | |||
|
1865 | profiler.dump_stats(output_path) | |||
1836 |
|
1866 | |||
1837 | def _completions(self, full_text: str, offset: int, *, _timeout)->Iterator[Completion]: |
|
1867 | def _completions(self, full_text: str, offset: int, *, _timeout)->Iterator[Completion]: | |
1838 | """ |
|
1868 | """ | |
@@ -2078,19 +2108,17 b' class IPCompleter(Completer):' | |||||
2078 | return text, _matches, origins, completions |
|
2108 | return text, _matches, origins, completions | |
2079 |
|
2109 | |||
2080 | def fwd_unicode_match(self, text:str) -> Tuple[str, list]: |
|
2110 | def fwd_unicode_match(self, text:str) -> Tuple[str, list]: | |
2081 | if self._names is None: |
|
|||
2082 | self._names = [] |
|
|||
2083 | for c in range(0,0x10FFFF + 1): |
|
|||
2084 | try: |
|
|||
2085 | self._names.append(unicodedata.name(chr(c))) |
|
|||
2086 | except ValueError: |
|
|||
2087 | pass |
|
|||
2088 |
|
2111 | |||
2089 | slashpos = text.rfind('\\') |
|
2112 | slashpos = text.rfind('\\') | |
2090 | # if text starts with slash |
|
2113 | # if text starts with slash | |
2091 | if slashpos > -1: |
|
2114 | if slashpos > -1: | |
|
2115 | # PERF: It's important that we don't access self._unicode_names | |||
|
2116 | # until we're inside this if-block. _unicode_names is lazily | |||
|
2117 | # initialized, and it takes a user-noticeable amount of time to | |||
|
2118 | # initialize it, so we don't want to initialize it unless we're | |||
|
2119 | # actually going to use it. | |||
2092 | s = text[slashpos+1:] |
|
2120 | s = text[slashpos+1:] | |
2093 | candidates = [x for x in self._names if x.startswith(s)] |
|
2121 | candidates = [x for x in self.unicode_names if x.startswith(s)] | |
2094 | if candidates: |
|
2122 | if candidates: | |
2095 | return s, candidates |
|
2123 | return s, candidates | |
2096 | else: |
|
2124 | else: | |
@@ -2099,3 +2127,20 b' class IPCompleter(Completer):' | |||||
2099 | # if text does not start with slash |
|
2127 | # if text does not start with slash | |
2100 | else: |
|
2128 | else: | |
2101 | return u'', () |
|
2129 | return u'', () | |
|
2130 | ||||
|
2131 | @property | |||
|
2132 | def unicode_names(self) -> List[str]: | |||
|
2133 | """List of names of unicode code points that can be completed. | |||
|
2134 | ||||
|
2135 | The list is lazily initialized on first access. | |||
|
2136 | """ | |||
|
2137 | if self._unicode_names is None: | |||
|
2138 | names = [] | |||
|
2139 | for c in range(0,0x10FFFF + 1): | |||
|
2140 | try: | |||
|
2141 | names.append(unicodedata.name(chr(c))) | |||
|
2142 | except ValueError: | |||
|
2143 | pass | |||
|
2144 | self._unicode_names = names | |||
|
2145 | ||||
|
2146 | return self._unicode_names |
General Comments 0
You need to be logged in to leave comments.
Login now