comparison mercurial/ui.py @ 27392:00aa37c65e0a stable

ui: try to handle $$ more robustly in prompts (issue4970)
author Matt Mackall <mpm@selenic.com>
date Mon, 30 Nov 2015 13:47:29 -0600
parents 71d5238f92e9
children 2916ebaef312
comparison
equal deleted inserted replaced
27370:d9e3ebe56970 27392:00aa37c65e0a
9 9
10 import errno 10 import errno
11 import getpass 11 import getpass
12 import inspect 12 import inspect
13 import os 13 import os
14 import re
14 import socket 15 import socket
15 import sys 16 import sys
16 import tempfile 17 import tempfile
17 import traceback 18 import traceback
18 19
762 def extractchoices(prompt): 763 def extractchoices(prompt):
763 """Extract prompt message and list of choices from specified prompt. 764 """Extract prompt message and list of choices from specified prompt.
764 765
765 This returns tuple "(message, choices)", and "choices" is the 766 This returns tuple "(message, choices)", and "choices" is the
766 list of tuple "(response character, text without &)". 767 list of tuple "(response character, text without &)".
768
769 >>> ui.extractchoices("awake? $$ &Yes $$ &No")
770 ('awake? ', [('y', 'Yes'), ('n', 'No')])
771 >>> ui.extractchoices("line\\nbreak? $$ &Yes $$ &No")
772 ('line\\nbreak? ', [('y', 'Yes'), ('n', 'No')])
773 >>> ui.extractchoices("want lots of $$money$$?$$Ye&s$$N&o")
774 ('want lots of $$money$$?', [('s', 'Yes'), ('o', 'No')])
767 """ 775 """
768 parts = prompt.split('$$') 776
769 msg = parts[0].rstrip(' ') 777 # Sadly, the prompt string may have been built with a filename
770 choices = [p.strip(' ') for p in parts[1:]] 778 # containing "$$" so let's try to find the first valid-looking
779 # prompt to start parsing. Sadly, we also can't rely on
780 # choices containing spaces, ASCII, or basically anything
781 # except an ampersand followed by a character.
782 m = re.match(r'(?s)(.+?)\$\$([^\$]*&[^ \$].*)', prompt)
783 msg = m.group(1)
784 choices = [p.strip(' ') for p in m.group(2).split('$$')]
771 return (msg, 785 return (msg,
772 [(s[s.index('&') + 1].lower(), s.replace('&', '', 1)) 786 [(s[s.index('&') + 1].lower(), s.replace('&', '', 1))
773 for s in choices]) 787 for s in choices])
774 788
775 def promptchoice(self, prompt, default=0): 789 def promptchoice(self, prompt, default=0):