From patchwork Thu Mar 10 19:47:37 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [1,of,2] ui: add new config flag for interface selection From: Simon Farnsworth X-Patchwork-Id: 13745 Message-Id: <77d0ac209cc8555d887b.1457639257@SimonFar-MacBookPro.local> To: Date: Thu, 10 Mar 2016 19:47:37 +0000 # HG changeset patch # User Simon Farnsworth # Date 1457639102 0 # Thu Mar 10 19:45:02 2016 +0000 # Node ID 77d0ac209cc8555d887b35313fad25e947aab7fa # Parent 1c658391b22fb4d98ccfb60c0e57315b55634117 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.. 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. diff --git a/mercurial/help/config.txt b/mercurial/help/config.txt --- a/mercurial/help/config.txt +++ b/mercurial/help/config.txt @@ -1607,6 +1607,15 @@ ``interactive`` Allow to prompt the user. (default: True) +``interface`` + Select the default interface for interactive features (default: text). + Possible values are 'text' and 'curses'. + +``interface.chunkselector`` + Select the interface for change recording (e.g. :hg:`commit` -i). + Possible values are 'text' and 'curses'. + This config overrides the interface specified by ui.interface. + ``logtemplate`` Template string for commands that print changesets. diff --git a/mercurial/ui.py b/mercurial/ui.py --- a/mercurial/ui.py +++ b/mercurial/ui.py @@ -697,6 +697,70 @@ 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.issuperset(availableinterfaces): + # Programming error, not user error + 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 is not None: + if i not in allowedinterfaces: + self.warn(_("invalid value for ui.interface: %s (using %s)\n") + % (i, defaultinterface)) + elif defaultinterface in availableinterfaces: + defaultinterface = i + + i = self.config("ui", "interface.%s" % feature, defaultinterface) + if i in availableinterfaces: + return i + else: + self.warn(_("invalid value for ui.interface.%s: %s (using %s)\n") + % (feature, i, defaultinterface)) + return defaultinterface + def interactive(self): '''is interactive input allowed? diff --git a/tests/test-commit-interactive-curses.t b/tests/test-commit-interactive-curses.t --- a/tests/test-commit-interactive-curses.t +++ b/tests/test-commit-interactive-curses.t @@ -223,3 +223,58 @@ hello world +Check ui.interface logic for the chunkselector + +The default interface is text + $ chunkselectorinterface() { + > python < from mercurial import hg, ui, parsers;\ + > repo = hg.repository(ui.ui(), ".");\ + > print repo.ui.interface("chunkselector") + > EOF + > } + $ chunkselectorinterface + text + +The default curses interface is crecord + $ cat <> $HGRCPATH + > [ui] + > interface = curses + > EOF + $ chunkselectorinterface + crecord + +It is possible to override the default interface with a feature specific +interface + $ cat <> $HGRCPATH + > [ui] + > interface = text + > interface.chunkselector = curses + > EOF + + $ chunkselectorinterface + crecord + +If a bad interface name is given, we use the default value: + $ cat <> $HGRCPATH + > [ui] + > interface = curses + > interface.chunkselector = blah + > EOF + + $ chunkselectorinterface + invalid value for ui.interface.chunkselector: blah + (using default interface instead: crecord) + crecord + $ cat <> $HGRCPATH + > [ui] + > interface = blah + > interface.chunkselector = blah + > EOF + + $ chunkselectorinterface + invalid value for ui.interface: blah + (using default interface instead text) + invalid value for ui.interface.chunkselector: blah + (using default interface instead: text) + text