I am using Python 2's cmd module to make a command line for a program. Everything works nicely as long as I don't add color to my prompt.
Working code:
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()
When I change my code as below, if I enter a long command or try to search in the command history, some characters stick to my prompt.
Problem code:
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()
You can see this problem in asciicasts. The problem also exists with the cmd2 module.
Just add markers to your color codes:
colorcodes = {'green':{True:'\x01\x1b[32m\x02',False:'\x01\x1b[39m\x02'}}
# ^^^^ ^^^^ ^^^^ ^^^^
In your asciicast, you have problems when you leave i-search mode and the prompt is re-printed. That is because Python doesn't know that the escape characters don't actually take up space on the screen. Putting \x01
before each escape sequence, and \x02
after each escape sequence, tells Python to assume those characters take up no space, and so the prompt will be correctly reprinted.
This is the same solution as in this answer, which had the corresponding problem in a different context. There is an open issue to mention this in the Python readline documentation, but I don't see that it has yet been done.
I tested the above colorcodes
values with Python 2.7.12 on Cygwin, running in mintty. In the prompt, username
printed green and everything else printed the default (light gray). I used the standard system cmd
module, not cmd2
(which you linked).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With