|
62 | 62 | # noinspection PyUnresolvedReferences
|
63 | 63 | from six.moves.urllib.request import urlopen
|
64 | 64 |
|
65 |
| -# Prefer statically linked gnureadline if available (for Mac OS X compatibility due to issues with libedit) |
66 |
| -try: |
67 |
| - import gnureadline as readline |
68 |
| -except ImportError: |
69 |
| - try: |
70 |
| - import readline |
71 |
| - except ImportError: |
72 |
| - pass |
73 |
| - |
74 | 65 | # Python 3 compatibility hack due to no built-in file keyword in Python 3
|
75 | 66 | # Due to one occurrence of isinstance(<foo>, file) checking to see if something is of file type
|
76 | 67 | try:
|
|
88 | 79 | except ImportError:
|
89 | 80 | ipython_available = False
|
90 | 81 |
|
| 82 | +# Try to import readline, but allow failure for convenience in Windows unit testing |
| 83 | +# Note: If this actually fails, you should install readline on Linux or Mac or pyreadline on Windows |
| 84 | +try: |
| 85 | + import readline |
| 86 | +except ImportError: |
| 87 | + pass |
| 88 | + |
91 | 89 | __version__ = '0.7.1a'
|
92 | 90 |
|
93 | 91 | # Pyparsing enablePackrat() can greatly speed up parsing, but problems have been seen in Python 3 in the past
|
@@ -1105,12 +1103,41 @@ def _default(self, statement):
|
1105 | 1103 |
|
1106 | 1104 | return False
|
1107 | 1105 |
|
| 1106 | + @staticmethod |
| 1107 | + def _surround_ansi_escapes(prompt, start="\x01", end="\x02"): |
| 1108 | + """Overcome bug in GNU Readline in relation to calculation of prompt length in presence of ASNI escape codes. |
| 1109 | +
|
| 1110 | + :param prompt: str - original prompt |
| 1111 | + :param start: str - start code to tell GNU Readline about beginning of invisible characters |
| 1112 | + :param end: str - end code to tell GNU Readline about end of invisible characters |
| 1113 | + :return: str - prompt safe to pass to GNU Readline |
| 1114 | + """ |
| 1115 | + # Windows terminals don't use ANSI escape codes and Windows readline isn't based on GNU Readline |
| 1116 | + if sys.platform == "win32": |
| 1117 | + return prompt |
| 1118 | + |
| 1119 | + escaped = False |
| 1120 | + result = "" |
| 1121 | + |
| 1122 | + for c in prompt: |
| 1123 | + if c == "\x1b" and not escaped: |
| 1124 | + result += start + c |
| 1125 | + escaped = True |
| 1126 | + elif c.isalpha() and escaped: |
| 1127 | + result += c + end |
| 1128 | + escaped = False |
| 1129 | + else: |
| 1130 | + result += c |
| 1131 | + |
| 1132 | + return result |
| 1133 | + |
1108 | 1134 | def pseudo_raw_input(self, prompt):
|
1109 | 1135 | """copied from cmd's cmdloop; like raw_input, but accounts for changed stdin, stdout"""
|
1110 | 1136 |
|
1111 | 1137 | if self.use_rawinput:
|
| 1138 | + safe_prompt = self._surround_ansi_escapes(prompt) |
1112 | 1139 | try:
|
1113 |
| - line = sm.input(prompt) |
| 1140 | + line = sm.input(safe_prompt) |
1114 | 1141 | except EOFError:
|
1115 | 1142 | line = 'EOF'
|
1116 | 1143 | else:
|
|
0 commit comments