[PATCH 1 of 2 V5] ui: add new config flag for interface selection

Simon Farnsworth simonfar at fb.com
Wed Mar 16 07:09:51 EDT 2016


Augie, Pierre-Yves, you both had review comments on Laurent's V4 patch. Would you mind taking a look at this version?

Thanks,

Simon





On 14/03/2016, 15:47, "Mercurial-devel on behalf of Simon Farnsworth" <mercurial-devel-bounces at mercurial-scm.org on behalf of simonfar at fb.com> wrote:

># HG changeset patch
># User Simon Farnsworth <simonfar at fb.com>
># Date 1457967687 0
>#      Mon Mar 14 15:01:27 2016 +0000
># Node ID 5302c318da91dfa7185389cf2e8e3f0685237030
># Parent  70c2f8a982766b512e9d7f41f2d93fdb92f5481f
>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.
>
>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,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?
> 
>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
>@@ -1,5 +1,6 @@
> Set up a repo
> 
>+  $ cp $HGRCPATH $HGRCPATH.pretest
>   $ cat <<EOF >> $HGRCPATH
>   > [ui]
>   > interactive = true
>@@ -223,3 +224,90 @@
>   hello world
> 
> 
>+Check ui.interface logic for the chunkselector
>+
>+The default interface is text
>+  $ cp $HGRCPATH.pretest $HGRCPATH
>+  $ chunkselectorinterface() {
>+  > python <<EOF
>+  > from mercurial import hg, ui, parsers;\
>+  > repo = hg.repository(ui.ui(), ".");\
>+  > print repo.ui.interface("chunkselector")
>+  > EOF
>+  > }
>+  $ chunkselectorinterface
>+  text
>+
>+If only the default is set, we'll use that for the feature, too
>+  $ cp $HGRCPATH.pretest $HGRCPATH
>+  $ cat <<EOF >> $HGRCPATH
>+  > [ui]
>+  > interface = curses
>+  > EOF
>+  $ chunkselectorinterface
>+  curses
>+
>+It is possible to override the default interface with a feature specific
>+interface
>+  $ cp $HGRCPATH.pretest $HGRCPATH
>+  $ cat <<EOF >> $HGRCPATH
>+  > [ui]
>+  > interface = text
>+  > interface.chunkselector = curses
>+  > EOF
>+
>+  $ chunkselectorinterface
>+  curses
>+
>+  $ cp $HGRCPATH.pretest $HGRCPATH
>+  $ cat <<EOF >> $HGRCPATH
>+  > [ui]
>+  > interface = curses
>+  > interface.chunkselector = text
>+  > EOF
>+
>+  $ chunkselectorinterface
>+  text
>+
>+If a bad interface name is given, we use the default value (with a nice
>+error message to suggest that the configuration needs to be fixed)
>+
>+  $ cp $HGRCPATH.pretest $HGRCPATH
>+  $ cat <<EOF >> $HGRCPATH
>+  > [ui]
>+  > interface = blah
>+  > EOF
>+  $ chunkselectorinterface
>+  invalid value for ui.interface: blah (using text)
>+  text
>+
>+  $ cp $HGRCPATH.pretest $HGRCPATH
>+  $ cat <<EOF >> $HGRCPATH
>+  > [ui]
>+  > interface = curses
>+  > interface.chunkselector = blah
>+  > EOF
>+  $ chunkselectorinterface
>+  invalid value for ui.interface.chunkselector: blah (using curses)
>+  curses
>+
>+  $ cp $HGRCPATH.pretest $HGRCPATH
>+  $ cat <<EOF >> $HGRCPATH
>+  > [ui]
>+  > interface = blah
>+  > interface.chunkselector = curses
>+  > EOF
>+  $ chunkselectorinterface
>+  invalid value for ui.interface: blah
>+  curses
>+
>+  $ cp $HGRCPATH.pretest $HGRCPATH
>+  $ cat <<EOF >> $HGRCPATH
>+  > [ui]
>+  > interface = blah
>+  > interface.chunkselector = blah
>+  > EOF
>+  $ chunkselectorinterface
>+  invalid value for ui.interface: blah
>+  invalid value for ui.interface.chunkselector: blah (using text)
>+  text
>_______________________________________________
>Mercurial-devel mailing list
>Mercurial-devel at mercurial-scm.org
>https://urldefense.proofpoint.com/v2/url?u=https-3A__www.mercurial-2Dscm.org_mailman_listinfo_mercurial-2Ddevel&d=CwIGaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=mEgSWILcY4c4W3zjApBQLA&m=SIjGp-B9f6VSxEYvTD3hENetZeSS3NNoKGvCELhRLBs&s=SFIrdP59am7CX7Ix-MNL4hoTsYvoQaZNMYeWbHKtrn0&e= 


More information about the Mercurial-devel mailing list