diff --git a/hgext/record.py b/hgext/record.py --- a/hgext/record.py +++ b/hgext/record.py @@ -291,25 +291,28 @@ def filterpatch(ui, chunks): _('Record &all changes to all remaining files'), _('&Quit, recording no changes'), _('&?')) - r = (ui.prompt("%s %s " % (query, resps), choices) - or _('y')).lower() - if r == _('?'): + r = ui.promptchoice("%s %s " % (query, resps), choices) + if r == 7: # ? doc = gettext(record.__doc__) c = doc.find(_('y - record this change')) for l in doc[c:].splitlines(): if l: ui.write(l.strip(), '\n') continue - elif r == _('s'): - r = resp_file[0] = 'n' - elif r == _('f'): - r = resp_file[0] = 'y' - elif r == _('d'): - r = resp_all[0] = 'n' - elif r == _('a'): - r = resp_all[0] = 'y' - elif r == _('q'): + elif r == 0: # yes + ret = 'y' + elif r == 1: # no + ret = 'n' + elif r == 2: # Skip + ret = resp_file[0] = 'n' + elif r == 3: # file (Record remaining) + ret = resp_file[0] = 'y' + elif r == 4: # done, skip remaining + ret = resp_all[0] = 'n' + elif r == 5: # all + ret = resp_all[0] = 'y' + elif r == 6: # quit raise util.Abort(_('user quit')) - return r + return ret pos, total = 0, len(chunks) - 1 while chunks: chunk = chunks.pop() diff --git a/mercurial/filemerge.py b/mercurial/filemerge.py --- a/mercurial/filemerge.py +++ b/mercurial/filemerge.py @@ -145,9 +145,9 @@ def filemerge(repo, mynode, orig, fcd, f if not tool or tool == 'internal:prompt': tool = "internal:local" - if ui.prompt(_(" no tool found to merge %s\n" + if ui.promptchoice(_(" no tool found to merge %s\n" "keep (l)ocal or take (o)ther?") % fd, - (_("&Local"), _("&Other")), _("l")) != _("l"): + (_("&Local"), _("&Other")), 0): tool = "internal:other" if tool == "internal:local": return 0 @@ -213,9 +213,9 @@ def filemerge(repo, mynode, orig, fcd, f if not r and _toolbool(ui, tool, "checkchanged"): if filecmp.cmp(repo.wjoin(fd), back): - if ui.prompt(_(" output file %s appears unchanged\n" + if ui.promptchoice(_(" output file %s appears unchanged\n" "was merge successful (yn)?") % fd, - (_("&Yes"), _("&No")), _("n")) != _("y"): + (_("&Yes"), _("&No")), 1): r = 1 if _toolbool(ui, tool, "fixeol"): diff --git a/mercurial/merge.py b/mercurial/merge.py --- a/mercurial/merge.py +++ b/mercurial/merge.py @@ -131,11 +131,13 @@ def manifestmerge(repo, p1, p2, pa, over if m == n: # flags agree return m # unchanged if m and n and not a: # flags set, don't agree, differ from parent - r = repo.ui.prompt( + r = repo.ui.promptchoice( _(" conflicting flags for %s\n" "(n)one, e(x)ec or sym(l)ink?") % f, - (_("&None"), _("E&xec"), _("Sym&link")), _("n")) - return r != _("n") and r or '' + (_("&None"), _("E&xec"), _("Sym&link")), 0) + if r == 1: return "x" # Exec + if r == 2: return "l" # Symlink + return "" if m and m != a: # changed from a to m return m if n and n != a: # changed from a to n @@ -191,10 +193,10 @@ def manifestmerge(repo, p1, p2, pa, over f, f2, f, fmerge(f, f2, f2), False) elif f in ma: # clean, a different, no remote if n != ma[f]: - if repo.ui.prompt( + if repo.ui.promptchoice( _(" local changed %s which remote deleted\n" "use (c)hanged version or (d)elete?") % f, - (_("&Changed"), _("&Delete")), _("c")) == _("d"): + (_("&Changed"), _("&Delete")), 0): act("prompt delete", "r", f) else: act("prompt keep", "a", f) @@ -222,10 +224,10 @@ def manifestmerge(repo, p1, p2, pa, over elif f not in ma: act("remote created", "g", f, m2.flags(f)) elif n != ma[f]: - if repo.ui.prompt( + if repo.ui.promptchoice( _("remote changed %s which local deleted\n" "use (c)hanged version or leave (d)eleted?") % f, - (_("&Changed"), _("&Deleted")), _("c")) == _("c"): + (_("&Changed"), _("&Deleted")), 0) == 0: act("prompt recreating", "g", f, m2.flags(f)) return action diff --git a/mercurial/subrepo.py b/mercurial/subrepo.py --- a/mercurial/subrepo.py +++ b/mercurial/subrepo.py @@ -63,11 +63,11 @@ def submerge(repo, wctx, mctx, actx): wctx.sub(s).get(r) sm[s] = r elif l[0] != r[0]: # sources differ - if repo.ui.prompt( + if repo.ui.promptchoice( _(' subrepository sources for %s differ\n' 'use (l)ocal source (%s) or (r)emote source (%s)?') % (s, l[0], r[0]), - (_('&Local'), _('&Remote')), _('l')) == _('r'): + (_('&Local'), _('&Remote')), 0): wctx.sub(s).get(r) sm[s] = r elif l[1] == a[1]: # local side is unchanged @@ -79,10 +79,10 @@ def submerge(repo, wctx, mctx, actx): elif l == a: # remote removed, local unchanged wctx.sub(s).remove() else: - if repo.ui.prompt( + if repo.ui.promptchoice( _(' local changed subrepository %s which remote removed\n' 'use (c)hanged version or (d)elete?') % s, - (_('&Changed'), _('&Delete')), _('c')) == _('d'): + (_('&Changed'), _('&Delete')), 0): wctx.sub(s).remove() for s, r in s2.items(): @@ -92,10 +92,10 @@ def submerge(repo, wctx, mctx, actx): wctx.sub(s).get(r) sm[s] = r elif r != sa[s]: - if repo.ui.prompt( + if repo.ui.promptchoice( _(' remote changed subrepository %s which local removed\n' 'use (c)hanged version or (d)elete?') % s, - (_('&Changed'), _('&Delete')), _('c')) == _('c'): + (_('&Changed'), _('&Delete')), 0) == 0: wctx.sub(s).get(r) sm[s] = r diff --git a/mercurial/ui.py b/mercurial/ui.py --- a/mercurial/ui.py +++ b/mercurial/ui.py @@ -269,30 +269,35 @@ class ui(object): line = line[:-1] return line - def prompt(self, msg, choices=None, default="y"): - """Prompt user with msg, read response, and ensure it matches - one of the provided choices. choices is a sequence of acceptable - responses with the format: ('&None', 'E&xec', 'Sym&link') - No sequence implies no response checking. Responses are case - insensitive. If ui is not interactive, the default is returned. + def prompt(self, msg, default="y"): + """Prompt user with msg, read response. + If ui is not interactive, the default is returned. """ if not self.interactive(): self.write(msg, ' ', default, "\n") return default + try: + r = self._readline(msg + ' ') + if not r: + return default + return r + except EOFError: + raise util.Abort(_('response expected')) + + def promptchoice(self, msg, choices, default=0): + """Prompt user with msg, read response, and ensure it matches + one of the provided choices. The index of the choice is returned. + choices is a sequence of acceptable responses with the format: + ('&None', 'E&xec', 'Sym&link') Responses are case insensitive. + If ui is not interactive, the default is returned. + """ + resps = [s[s.index('&')+1].lower() for s in choices] while True: - try: - r = self._readline(msg + ' ') - if not r: - return default - if not choices: - return r - resps = [s[s.index('&')+1].lower() for s in choices] - if r.lower() in resps: - return r.lower() - else: - self.write(_("unrecognized response\n")) - except EOFError: - raise util.Abort(_('response expected')) + r = self.prompt(msg, resps[default]) + if r.lower() in resps: + return resps.index(r.lower()) + self.write(_("unrecognized response\n")) + def getpass(self, prompt=None, default=None): if not self.interactive(): return default