# HG changeset patch # User Matt Mackall # Date 1450394852 21600 # Node ID 2916ebaef3129451bfd4f9f62487e70f74124d46 # Parent bf4d5d8dc2aa9bc6cd293f273f67e3aada5b465d# Parent 00aa37c65e0a365230938aed51d1b38b7cace135 merge with stable diff -r bf4d5d8dc2aa -r 2916ebaef312 mercurial/ui.py --- a/mercurial/ui.py Mon Dec 14 23:04:17 2015 +0000 +++ b/mercurial/ui.py Thu Dec 17 17:27:32 2015 -0600 @@ -11,6 +11,7 @@ import getpass import inspect import os +import re import socket import sys import tempfile @@ -812,10 +813,23 @@ This returns tuple "(message, choices)", and "choices" is the list of tuple "(response character, text without &)". + + >>> ui.extractchoices("awake? $$ &Yes $$ &No") + ('awake? ', [('y', 'Yes'), ('n', 'No')]) + >>> ui.extractchoices("line\\nbreak? $$ &Yes $$ &No") + ('line\\nbreak? ', [('y', 'Yes'), ('n', 'No')]) + >>> ui.extractchoices("want lots of $$money$$?$$Ye&s$$N&o") + ('want lots of $$money$$?', [('s', 'Yes'), ('o', 'No')]) """ - parts = prompt.split('$$') - msg = parts[0].rstrip(' ') - choices = [p.strip(' ') for p in parts[1:]] + + # Sadly, the prompt string may have been built with a filename + # containing "$$" so let's try to find the first valid-looking + # prompt to start parsing. Sadly, we also can't rely on + # choices containing spaces, ASCII, or basically anything + # except an ampersand followed by a character. + m = re.match(r'(?s)(.+?)\$\$([^\$]*&[^ \$].*)', prompt) + msg = m.group(1) + choices = [p.strip(' ') for p in m.group(2).split('$$')] return (msg, [(s[s.index('&') + 1].lower(), s.replace('&', '', 1)) for s in choices])