Show More
@@ -61,11 +61,13 b' import keyword' | |||||
61 | import os |
|
61 | import os | |
62 | import re |
|
62 | import re | |
63 | import sys |
|
63 | import sys | |
|
64 | import unicodedata | |||
|
65 | import string | |||
64 |
|
66 | |||
65 | from IPython.config.configurable import Configurable |
|
67 | from IPython.config.configurable import Configurable | |
66 | from IPython.core.error import TryNext |
|
68 | from IPython.core.error import TryNext | |
67 | from IPython.core.inputsplitter import ESC_MAGIC |
|
69 | from IPython.core.inputsplitter import ESC_MAGIC | |
68 | from IPython.core.latex_symbols import latex_symbols |
|
70 | from IPython.core.latex_symbols import latex_symbols, reverse_latex_symbol | |
69 | from IPython.utils import generics |
|
71 | from IPython.utils import generics | |
70 | from IPython.utils import io |
|
72 | from IPython.utils import io | |
71 | from IPython.utils.decorators import undoc |
|
73 | from IPython.utils.decorators import undoc | |
@@ -955,6 +957,88 b' class IPCompleter(Completer):' | |||||
955 |
|
957 | |||
956 | return [leading + k + suf for k in matches] |
|
958 | return [leading + k + suf for k in matches] | |
957 |
|
959 | |||
|
960 | def unicode_name_matches(self, text): | |||
|
961 | u"""Match Latex-like syntax for unicode characters base | |||
|
962 | on the name of the character. | |||
|
963 | ||||
|
964 | This does \\GREEK SMALL LETTER ETA -> η | |||
|
965 | ||||
|
966 | Works only on valid python 3 identifier, or on combining characters that | |||
|
967 | will combine to form a valid identifier. | |||
|
968 | ||||
|
969 | Used on Python 3 only. | |||
|
970 | """ | |||
|
971 | slashpos = text.rfind('\\') | |||
|
972 | if slashpos > -1: | |||
|
973 | s = text[slashpos+1:] | |||
|
974 | try : | |||
|
975 | unic = unicodedata.lookup(s) | |||
|
976 | # allow combining chars | |||
|
977 | if ('a'+unic).isidentifier(): | |||
|
978 | return '\\'+s,[unic] | |||
|
979 | except KeyError as e: | |||
|
980 | pass | |||
|
981 | return u'', [] | |||
|
982 | ||||
|
983 | def back_unicode_name_matches(self, text): | |||
|
984 | u"""Match unicode characters back to unicode name | |||
|
985 | ||||
|
986 | This does ☃ -> \\snowman | |||
|
987 | ||||
|
988 | Note that snowman is not a valid python3 combining character but will be expanded. | |||
|
989 | Though it will not recombine back to the snowman character by the completion machinery. | |||
|
990 | ||||
|
991 | This will not either back-complete standard sequences like \n, \b ... | |||
|
992 | ||||
|
993 | Used on Python 3 only. | |||
|
994 | """ | |||
|
995 | if len(text)<2: | |||
|
996 | return u'', () | |||
|
997 | maybe_slash = text[-2] | |||
|
998 | if maybe_slash != '\\': | |||
|
999 | return u'', () | |||
|
1000 | ||||
|
1001 | char = text[-1] | |||
|
1002 | # no expand on quote for completion in strings. | |||
|
1003 | # nor backcomplete standard ascii keys | |||
|
1004 | if char in string.ascii_letters or char in ['"',"'"]: | |||
|
1005 | return u'', () | |||
|
1006 | try : | |||
|
1007 | unic = unicodedata.name(char) | |||
|
1008 | return '\\'+char,['\\'+unic] | |||
|
1009 | except KeyError as e: | |||
|
1010 | pass | |||
|
1011 | return u'', () | |||
|
1012 | ||||
|
1013 | def back_latex_name_matches(self, text): | |||
|
1014 | u"""Match latex characters back to unicode name | |||
|
1015 | ||||
|
1016 | This does ->\\sqrt | |||
|
1017 | ||||
|
1018 | Used on Python 3 only. | |||
|
1019 | """ | |||
|
1020 | if len(text)<2: | |||
|
1021 | return u'', () | |||
|
1022 | maybe_slash = text[-2] | |||
|
1023 | if maybe_slash != '\\': | |||
|
1024 | return u'', () | |||
|
1025 | ||||
|
1026 | ||||
|
1027 | char = text[-1] | |||
|
1028 | # no expand on quote for completion in strings. | |||
|
1029 | # nor backcomplete standard ascii keys | |||
|
1030 | if char in string.ascii_letters or char in ['"',"'"]: | |||
|
1031 | return u'', () | |||
|
1032 | try : | |||
|
1033 | latex = reverse_latex_symbol[char] | |||
|
1034 | # '\\' replace the \ as well | |||
|
1035 | return '\\'+char,[latex] | |||
|
1036 | except KeyError as e: | |||
|
1037 | pass | |||
|
1038 | return u'', () | |||
|
1039 | ||||
|
1040 | ||||
|
1041 | ||||
958 | def latex_matches(self, text): |
|
1042 | def latex_matches(self, text): | |
959 | u"""Match Latex syntax for unicode characters. |
|
1043 | u"""Match Latex syntax for unicode characters. | |
960 |
|
1044 | |||
@@ -1057,10 +1141,20 b' class IPCompleter(Completer):' | |||||
1057 | cursor_pos = len(line_buffer) if text is None else len(text) |
|
1141 | cursor_pos = len(line_buffer) if text is None else len(text) | |
1058 |
|
1142 | |||
1059 | if PY3: |
|
1143 | if PY3: | |
1060 | latex_text = text if not line_buffer else line_buffer[:cursor_pos] |
|
1144 | ||
1061 | latex_text, latex_matches = self.latex_matches(latex_text) |
|
1145 | base_text = text if not line_buffer else line_buffer[:cursor_pos] | |
|
1146 | latex_text, latex_matches = self.latex_matches(base_text) | |||
1062 | if latex_matches: |
|
1147 | if latex_matches: | |
1063 | return latex_text, latex_matches |
|
1148 | return latex_text, latex_matches | |
|
1149 | name_text = '' | |||
|
1150 | name_matches = [] | |||
|
1151 | for meth in (self.unicode_name_matches, self.back_unicode_name_matches, self.back_latex_name_matches): | |||
|
1152 | _name_text, _name_matches = meth(base_text) | |||
|
1153 | if _name_text: | |||
|
1154 | name_text = _name_text | |||
|
1155 | name_matches.extend(_name_matches) | |||
|
1156 | if name_text: | |||
|
1157 | return name_text, name_matches | |||
1064 |
|
1158 | |||
1065 | # if text is either None or an empty string, rely on the line buffer |
|
1159 | # if text is either None or an empty string, rely on the line buffer | |
1066 | if not text: |
|
1160 | if not text: | |
@@ -1170,3 +1264,4 b' class IPCompleter(Completer):' | |||||
1170 | return self.matches[state] |
|
1264 | return self.matches[state] | |
1171 | except IndexError: |
|
1265 | except IndexError: | |
1172 | return None |
|
1266 | return None | |
|
1267 |
@@ -1295,3 +1295,6 b' latex_symbols = {' | |||||
1295 | "\\mtteight" : "𝟾", |
|
1295 | "\\mtteight" : "𝟾", | |
1296 | "\\mttnine" : "𝟿", |
|
1296 | "\\mttnine" : "𝟿", | |
1297 | } |
|
1297 | } | |
|
1298 | ||||
|
1299 | ||||
|
1300 | reverse_latex_symbol = { v:k for k,v in latex_symbols.items()} |
@@ -76,6 +76,11 b' for line in valid_idents:' | |||||
76 | s += ' "%s" : "%s",\n' % (line[0], line[1]) |
|
76 | s += ' "%s" : "%s",\n' % (line[0], line[1]) | |
77 | s += "}\n" |
|
77 | s += "}\n" | |
78 |
|
78 | |||
|
79 | s += """ | |||
|
80 | ||||
|
81 | reverse_latex_symbol = { v:k for k,v in latex_symbols.items()} | |||
|
82 | """ | |||
|
83 | ||||
79 | fn = os.path.join('..','IPython','core','latex_symbols.py') |
|
84 | fn = os.path.join('..','IPython','core','latex_symbols.py') | |
80 | print("Writing the file: %s" % fn) |
|
85 | print("Writing the file: %s" % fn) | |
81 | with open(fn, 'w', encoding='utf-8') as f: |
|
86 | with open(fn, 'w', encoding='utf-8') as f: |
General Comments 0
You need to be logged in to leave comments.
Login now