Mercurial > public > mercurial-scm > hg
diff mercurial/ui.py @ 28542:71e12fc53b80
ui: add new config flag for interface selection
This patch introduces a new config flag ui.interface to select the interface
for interactive commands. It currently only applies to chunks selection.
The config can be overridden on a per feature basis with the flag
ui.interface.<feature>.
features for the moment can only be 'chunkselector', moving forward we expect
to have 'histedit' and other commands there.
If an incorrect value is given to ui.interface we print a warning and use the
default interface: text. If HGPLAIN is specified we also use the default
interface: text.
Note that we fail quickly if a feature does not handle all the interfaces
that we permit in ui.interface; in future, we could design a fallback path
(e.g. blackpearl to curses, curses to text), but let's leave that until we
need it.
author | Simon Farnsworth <simonfar@fb.com> |
---|---|
date | Mon, 14 Mar 2016 15:01:27 +0000 |
parents | d09be0b8a3c6 |
children | c30d5ca4945b |
line wrap: on
line diff
--- a/mercurial/ui.py Fri Mar 11 10:30:08 2016 +0000 +++ b/mercurial/ui.py Mon Mar 14 15:01:27 2016 +0000 @@ -697,6 +697,77 @@ return False return util.isatty(fh) + def interface(self, feature): + """what interface to use for interactive console features? + + The interface is controlled by the value of `ui.interface` but also by + the value of feature-specific configuration. For example: + + ui.interface.histedit = text + ui.interface.chunkselector = curses + + Here the features are "histedit" and "chunkselector". + + The configuration above means that the default interfaces for commands + is curses, the interface for histedit is text and the interface for + selecting chunk is crecord (the best curses interface available). + + Consider the following exemple: + ui.interface = curses + ui.interface.histedit = text + + Then histedit will use the text interface and chunkselector will use + the default curses interface (crecord at the moment). + """ + alldefaults = frozenset(["text", "curses"]) + + featureinterfaces = { + "chunkselector": [ + "text", + "curses", + ] + } + + # Feature-specific interface + if feature not in featureinterfaces.keys(): + # Programming error, not user error + raise ValueError("Unknown feature requested %s" % feature) + + availableinterfaces = frozenset(featureinterfaces[feature]) + if alldefaults > availableinterfaces: + # Programming error, not user error. We need a use case to + # define the right thing to do here. + raise ValueError( + "Feature %s does not handle all default interfaces" % + feature) + + if self.plain(): + return "text" + + # Default interface for all the features + defaultinterface = "text" + i = self.config("ui", "interface", None) + if i in alldefaults: + defaultinterface = i + + choseninterface = defaultinterface + f = self.config("ui", "interface.%s" % feature, None) + if f in availableinterfaces: + choseninterface = f + + if i is not None and defaultinterface != i: + if f is not None: + self.warn(_("invalid value for ui.interface: %s\n") % + (i,)) + else: + self.warn(_("invalid value for ui.interface: %s (using %s)\n") % + (i, choseninterface)) + if f is not None and choseninterface != f: + self.warn(_("invalid value for ui.interface.%s: %s (using %s)\n") % + (feature, f, choseninterface)) + + return choseninterface + def interactive(self): '''is interactive input allowed?