在 Python cmd 中,一些字符坚持我的彩色提示

Some characters stick to my colorized prompt in Python cmd

我正在使用 Python 2's cmd module 为程序制作命令行。只要我不为我的提示添加颜色,一切都很好。

工作代码:

from cmd import Cmd

class App(Cmd):

    def __init__(self):
        Cmd.__init__(self)
        self.prompt = "PG ["+ (str('username'), 'green') +"@"+ str('hostname') +"]: "

    def do_exit(self, line):
        '''
        '''
        return True

App().cmdloop()

当我如下更改我的代码时,如果我输入一个长命令或尝试在命令历史记录中搜索,一些字符会保留在我的提示中。

问题代码:

from cmd import Cmd

class App(Cmd):

    def __init__(self):
        Cmd.__init__(self)
        self.prompt = "PG ["+ self.colorize(str('username'), 'green') +"@"+ str('hostname') +"]: "

    colorcodes =    {'green':{True:'\x1b[32m',False:'\x1b[39m'}}


    def colorize(self, val, color):
        return self.colorcodes[color][True] + val + self.colorcodes[color][False]

    def do_exit(self, line):
        '''
        '''
        return True

App().cmdloop()

你可以在 asciicasts. The problem also exists with the cmd2 module 中看到这个问题。

只需在您的颜色代码中添加标记即可:

    colorcodes =    {'green':{True:'\x01\x1b[32m\x02',False:'\x01\x1b[39m\x02'}}
                                  # ^^^^        ^^^^         ^^^^        ^^^^

在您的 asciicast 中,当您离开 i-search 模式并重新打印提示时,您遇到了问题。那是因为 Python 不知道转义字符实际上并没有在屏幕上占据 space。在每个转义序列之前放置 \x01,在每个转义序列之后放置 \x02,告诉 Python 假设这些字符不占用 space,因此提示将被正确重印。

这与 this answer, which had the corresponding problem in a different context. There is an open issue 中的解决方案相同,在 Python readline 文档中提到了这一点,但我没有看到它已经完成。

我在 Cygwin 上用 Python 2.7.12 测试了上面的 colorcodes 值,在 mintty 上用 运行 测试了这些值。在提示中,username 打印为绿色,其他所有内容均打印为默认值(浅灰色)。我使用了标准系统 cmd 模块, 不是 cmd2(您链接的)。