diff options
author | Todd Leonhardt <todd.leonhardt@gmail.com> | 2017-05-11 21:41:36 -0400 |
---|---|---|
committer | Todd Leonhardt <todd.leonhardt@gmail.com> | 2017-05-11 21:41:36 -0400 |
commit | 2bd17dbc34ce88a4cd5375dadb0406b891a1fdb6 (patch) | |
tree | e80135780402ed18a7c0c4a788782f9326169b3e /cmd2.py | |
parent | ecf5a11315fc0bcab575182820f8c06e348813d2 (diff) | |
download | cmd2-git-2bd17dbc34ce88a4cd5375dadb0406b891a1fdb6.tar.gz |
Added code to protect against GNU Readline bug
GNU Readline has a bug in calculating prompt length when ANSI escape codes are present in the prompt. It requires you to escape the escape codes to tell it where sections of invisible characters begin and end.
So before calling input(), cmd2 now makes the prompt safe by escaping any ANSI escape codes present.
Diffstat (limited to 'cmd2.py')
-rwxr-xr-x | cmd2.py | 28 |
1 files changed, 27 insertions, 1 deletions
@@ -34,6 +34,7 @@ import optparse import os import platform import re +import readline import shlex import six import subprocess @@ -1096,12 +1097,37 @@ class Cmd(cmd.Cmd): return False + @staticmethod + def _surround_ansi_escapes(prompt, start="\x01", end="\x02"): + """Overcome bug in GNU Readline in relation to calculation of prompt length in presence of ASNI escape codes. + + :param prompt: str - original prompt + :param start: str - start code to tell GNU Readline about beginning of invisible characters + :param end: str - end code to tell GNU Readline about end of invisible characters + :return: str - prompt safe to pass to GNU Readline + """ + escaped = False + result = "" + + for c in prompt: + if c == "\x1b" and not escaped: + result += start + c + escaped = True + elif c.isalpha() and escaped: + result += c + end + escaped = False + else: + result += c + + return result + def pseudo_raw_input(self, prompt): """copied from cmd's cmdloop; like raw_input, but accounts for changed stdin, stdout""" if self.use_rawinput: + safe_prompt = self._surround_ansi_escapes(prompt) try: - line = sm.input(prompt) + line = sm.input(safe_prompt) except EOFError: line = 'EOF' else: |