Patchwork D119: color: add autoterminfo option to prefer terminfo over ansi for non-windows

login
register
mail settings
Submitter phabricator
Date July 18, 2017, 3:15 a.m.
Message ID <differential-rev-PHID-DREV-ciecakifquvueijthhbf-req@phab.mercurial-scm.org>
Download mbox | patch
Permalink /patch/22467/
State Superseded, archived
Headers show

Comments

phabricator - July 18, 2017, 3:15 a.m.
spectral created this revision.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.

REVISION SUMMARY
  If color.mode=auto in the config (this is the default) then color.py currently
  checks if using windows, and if not, uses 'ansi'.  This means that to get
  terminfo-based terminal support, one has to specify color.mode=terminfo
  explicitly; this enables several warnings if a user's terminal does not actually
  have support for terminfo (for example, we failed to load curses, or the
  terminal does not have a 'setaf' entry).
  
  If color.autoterminfo is True, we will attempt to use terminfo, and *silently*
  fallback to 'ansi' if it is not viable.
  
  This patch does nothing to change the ui.debug messages that are output if
  terminfo is chosen but the terminal does not support one of the "default"
  features, such as 'dim' or 'invis'.  Therefore, the fallback to 'ansi' if
  terminfo is not available will be silent, but if terminfo *is* available but
  does not support every feature, invocations with --debug will still see/start
  to see "no terminfo entry for <feature>" messages.

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D119

AFFECTED FILES
  mercurial/color.py
  mercurial/help/config.txt
  tests/hgterm-dumb.ti
  tests/test-status-color.t

CHANGE DETAILS




EMAIL PREFERENCES
  https://phab.mercurial-scm.org/settings/panel/emailpreferences/

To: spectral, #hg-reviewers
Cc: mercurial-devel
phabricator - July 18, 2017, 3:56 p.m.
simonfar added a comment.


  Looks good to me, though.

INLINE COMMENTS

> color.py:259-264
>      elif realmode == 'terminfo':
>          _terminfosetup(ui, mode)
>          if not ui._terminfoparams:
>              ## FIXME Shouldn't we return None in this case too?
>              modewarn()
>              realmode = 'ansi'

For the real reviewer - this combines with `modewarn()` above to do the silent fallback promised above.

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D119

EMAIL PREFERENCES
  https://phab.mercurial-scm.org/settings/panel/emailpreferences/

To: spectral, #hg-reviewers
Cc: simonfar, mercurial-devel
phabricator - July 18, 2017, 8:50 p.m.
krbullock added a comment.


  I like this, but I'd rather not take it right before a freeze. Can we revisit this for 4.4?

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D119

EMAIL PREFERENCES
  https://phab.mercurial-scm.org/settings/panel/emailpreferences/

To: spectral, #hg-reviewers
Cc: krbullock, simonfar, mercurial-devel
phabricator - July 18, 2017, 9:06 p.m.
spectral removed subscribers: krbullock, simonfar.
spectral added a comment.


  In https://phab.mercurial-scm.org/D119#2012, @krbullock wrote:
  
  > I like this, but I'd rather not take it right before a freeze. Can we revisit this for 4.4?
  
  
  I'm fine with waiting.  I was on the fence with whether to send this now or not anyway, and I understand the concern about finalizing a config option name.  Closing/abandoning now, will try to reopen after the freeze. :)

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D119

EMAIL PREFERENCES
  https://phab.mercurial-scm.org/settings/panel/emailpreferences/

To: spectral, #hg-reviewers
Cc: mercurial-devel
phabricator - July 23, 2017, 6:05 p.m.
indygreg added a comment.


  Can we refactor `color.mode=auto` to do something reasonable, like detect and use terminfo if it is available? It always struck me as strange that `auto` doesn't actually get you the best possible experience.
  
  FWIW, I think the color code needs to be massively refactored to support "nice things" like native 256 color usage, different profiles for different background colors, color blind awareness, customization based on TERM, etc.

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D119

To: spectral, #hg-reviewers
Cc: indygreg, mercurial-devel

Patch

diff --git a/tests/test-status-color.t b/tests/test-status-color.t
--- a/tests/test-status-color.t
+++ b/tests/test-status-color.t
@@ -256,6 +256,49 @@ 
   \x1b[30m\x1b[88mC \x1b[30m\x1b[30m\x1b[88m.hgignore\x1b[30m (esc)
   \x1b[30m\x1b[88mC \x1b[30m\x1b[30m\x1b[88mmodified\x1b[30m (esc)
 
+color.autoterminfo chooses terminfo if it's viable:
+
+  $ TERM=hgterm TERMINFO="$TESTTMP/terminfo" hg status --config color.mode=auto --config color.autoterminfo=1 --config color.status.clean=dim -A
+  \x1b[30m\x1b[32m\x1b[2mA \x1b[30m\x1b[30m\x1b[32m\x1b[2madded\x1b[30m (esc)
+  \x1b[30m\x1b[32m\x1b[2mA \x1b[30m\x1b[30m\x1b[32m\x1b[2mcopied\x1b[30m (esc)
+  \x1b[30m\x1b[30m  modified\x1b[30m (esc)
+  \x1b[30m\x1b[31m\x1b[2mR \x1b[30m\x1b[30m\x1b[31m\x1b[2mremoved\x1b[30m (esc)
+  \x1b[30m\x1b[36m\x1b[2m\x1b[4m! \x1b[30m\x1b[30m\x1b[36m\x1b[2m\x1b[4mdeleted\x1b[30m (esc)
+  \x1b[30m\x1b[35m\x1b[2m\x1b[4m? \x1b[30m\x1b[30m\x1b[35m\x1b[2m\x1b[4munknown\x1b[30m (esc)
+  \x1b[30m\x1b[30m\x1b[2mI \x1b[30m\x1b[30m\x1b[30m\x1b[2mignored\x1b[30m (esc)
+  \x1b[30m\x1b[88mC \x1b[30m\x1b[30m\x1b[88m.hgignore\x1b[30m (esc)
+  \x1b[30m\x1b[88mC \x1b[30m\x1b[30m\x1b[88mmodified\x1b[30m (esc)
+
+ECMA fallback warning with mode=terminfo explicit:
+
+  $ TERMINFO="$TESTTMP/terminfo" tic "$TESTDIR/hgterm-dumb.ti"
+  $ TERM=hgterm-dumb TERMINFO="$TESTTMP/terminfo" hg status --config color.mode=terminfo -A
+  no terminfo entry for setab/setaf: reverting to ECMA-48 color
+  no terminfo entry for setab/setaf: reverting to ECMA-48 color
+  no terminfo entry for setab/setaf: reverting to ECMA-48 color
+  \x1b[0;32;1mA \x1b[0m\x1b[0;32;1madded\x1b[0m (esc)
+  \x1b[0;32;1mA \x1b[0m\x1b[0;32;1mcopied\x1b[0m (esc)
+  \x1b[0;0m  modified\x1b[0m (esc)
+  \x1b[0;31;1mR \x1b[0m\x1b[0;31;1mremoved\x1b[0m (esc)
+  \x1b[0;36;1;4m! \x1b[0m\x1b[0;36;1;4mdeleted\x1b[0m (esc)
+  \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4munknown\x1b[0m (esc)
+  \x1b[0;30;1mI \x1b[0m\x1b[0;30;1mignored\x1b[0m (esc)
+  \x1b[0;0mC \x1b[0m\x1b[0;0m.hgignore\x1b[0m (esc)
+  \x1b[0;0mC \x1b[0m\x1b[0;0mmodified\x1b[0m (esc)
+
+No fallback warning with autoterminfo:
+
+  $ TERM=hgterm-dumb TERMINFO="$TESTTMP/terminfo" hg status --config color.mode=auto --config color.autoterminfo=1 -A
+  \x1b[0;32;1mA \x1b[0m\x1b[0;32;1madded\x1b[0m (esc)
+  \x1b[0;32;1mA \x1b[0m\x1b[0;32;1mcopied\x1b[0m (esc)
+  \x1b[0;0m  modified\x1b[0m (esc)
+  \x1b[0;31;1mR \x1b[0m\x1b[0;31;1mremoved\x1b[0m (esc)
+  \x1b[0;36;1;4m! \x1b[0m\x1b[0;36;1;4mdeleted\x1b[0m (esc)
+  \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4munknown\x1b[0m (esc)
+  \x1b[0;30;1mI \x1b[0m\x1b[0;30;1mignored\x1b[0m (esc)
+  \x1b[0;0mC \x1b[0m\x1b[0;0m.hgignore\x1b[0m (esc)
+  \x1b[0;0mC \x1b[0m\x1b[0;0mmodified\x1b[0m (esc)
+
 #endif
 
 
diff --git a/tests/hgterm-dumb.ti b/tests/hgterm-dumb.ti
new file mode 100644
--- /dev/null
+++ b/tests/hgterm-dumb.ti
@@ -0,0 +1,4 @@ 
+hgterm-dumb,
+	am,
+	cols#80,
+	bel=^G, cr=^M, cud1=^J, ind=^J,
diff --git a/mercurial/help/config.txt b/mercurial/help/config.txt
--- a/mercurial/help/config.txt
+++ b/mercurial/help/config.txt
@@ -412,22 +412,26 @@ 
 Configure the Mercurial color mode. For details about how to define your custom
 effect and style see :hg:`help color`.
 
+``autoterminfo``
+    Make ``color.mode=auto`` attempt ``terminfo`` before falling back to
+    ``ansi``. Does not have an effect on Windows systems. (default: False)
+
 ``mode``
     String: control the method used to output color. One of ``auto``, ``ansi``,
-    ``win32``, ``terminfo`` or ``debug``. In auto mode, Mercurial will
-    use ANSI mode by default (or win32 mode prior to Windows 10) if it detects a
-    terminal. Any invalid value will disable color.
+    ``win32``, ``terminfo`` or ``debug``. In auto mode, Mercurial will change
+    its behavior depending on the OS and the value of autoterminfo, by default
+    it uses ANSI mode (win32 mode prior to Windows 10) if it detects a terminal.
+    Any invalid value will disable color.
 
 ``pagermode``
     String: optional override of ``color.mode`` used with pager.
 
     On some systems, terminfo mode may cause problems when using
     color with ``less -R`` as a pager program. less with the -R option
     will only display ECMA-48 color codes, and terminfo mode may sometimes
     emit codes that less doesn't understand. You can work around this by
-    either using ansi mode (or auto mode), or by using less -r (which will
-    pass through all terminal control codes, not just color control
-    codes).
+    specifying ``ansi`` here, or by using less -r (which will pass through all
+    terminal control codes, not just color control codes).
 
     On some systems (such as MSYS in Windows), the terminal may support
     a different color mode than the pager program.
diff --git a/mercurial/color.py b/mercurial/color.py
--- a/mercurial/color.py
+++ b/mercurial/color.py
@@ -237,7 +237,11 @@ 
         elif mode == 'ansi' and w32effects and not ansienviron:
             win32.enablevtmode()
     elif mode == 'auto':
-        realmode = 'ansi'
+        if ui.configbool('color', 'autoterminfo', False):
+            # If terminfo setup fails, we will still fallback to ansi, below.
+            realmode = 'terminfo'
+        else:
+            realmode = 'ansi'
 
     def modewarn():
         # only warn if color.mode was explicitly set and we're in