pager: set some environment variables if they're not set
authorJun Wu <quark@fb.com>
Thu, 13 Apr 2017 08:27:19 -0700
changeset 31954 e518192d6bac
parent 31953 cc2382b60007
child 31955 4c2c30bc38b4
pager: set some environment variables if they're not set Git did this already [1] [2]. We want this behavior too [3]. This provides a better default user experience (like, supporting colors) if users have things like "PAGER=less" set, which is not uncommon. The environment variables are provided by a method so extensions can override them on demand. [1]: https://github.com/git/git/blob/6a5ff7acb5965718cc7016c0ab6c601454fd7cde/pager.c#L87 [2]: https://github.com/git/git/blob/6a5ff7acb5965718cc7016c0ab6c601454fd7cde/Makefile#L1545 [3]: https://www.mercurial-scm.org/pipermail/mercurial-devel/2017-March/094780.html
mercurial/chgserver.py
mercurial/rcutil.py
mercurial/ui.py
tests/test-pager.t
--- a/mercurial/chgserver.py	Thu Apr 13 14:48:18 2017 -0400
+++ b/mercurial/chgserver.py	Thu Apr 13 08:27:19 2017 -0700
@@ -190,8 +190,8 @@
             self.flush()
             return self._csystem(cmd, util.shellenviron(environ), cwd)
 
-        def _runpager(self, cmd):
-            self._csystem(cmd, util.shellenviron(), type='pager',
+        def _runpager(self, cmd, env=None):
+            self._csystem(cmd, util.shellenviron(env), type='pager',
                           cmdtable={'attachio': attachio})
             return True
 
--- a/mercurial/rcutil.py	Thu Apr 13 14:48:18 2017 -0400
+++ b/mercurial/rcutil.py	Thu Apr 13 08:27:19 2017 -0700
@@ -90,3 +90,9 @@
         _rccomponents.append(envrc)
         _rccomponents.extend(normpaths(userrcpath()))
     return _rccomponents
+
+def defaultpagerenv():
+    '''return a dict of default environment variables and their values,
+    intended to be set before starting a pager.
+    '''
+    return {'LESS': 'FRX', 'LV': '-c'}
--- a/mercurial/ui.py	Thu Apr 13 14:48:18 2017 -0400
+++ b/mercurial/ui.py	Thu Apr 13 08:27:19 2017 -0700
@@ -854,13 +854,18 @@
         if not pagercmd:
             return
 
+        pagerenv = {}
+        for name, value in rcutil.defaultpagerenv().items():
+            if name not in encoding.environ:
+                pagerenv[name] = value
+
         self.debug('starting pager for command %r\n' % command)
         self.flush()
 
         wasformatted = self.formatted()
         if util.safehasattr(signal, "SIGPIPE"):
             signal.signal(signal.SIGPIPE, _catchterm)
-        if self._runpager(pagercmd):
+        if self._runpager(pagercmd, pagerenv):
             self.pageractive = True
             # Preserve the formatted-ness of the UI. This is important
             # because we mess with stdout, which might confuse
@@ -879,7 +884,7 @@
             # warning about a missing pager command.
             self.disablepager()
 
-    def _runpager(self, command):
+    def _runpager(self, command, env=None):
         """Actually start the pager and set up file descriptors.
 
         This is separate in part so that extensions (like chg) can
@@ -912,7 +917,8 @@
             pager = subprocess.Popen(
                 command, shell=shell, bufsize=-1,
                 close_fds=util.closefds, stdin=subprocess.PIPE,
-                stdout=util.stdout, stderr=util.stderr)
+                stdout=util.stdout, stderr=util.stderr,
+                env=util.shellenviron(env))
         except OSError as e:
             if e.errno == errno.ENOENT and not shell:
                 self.warn(_("missing pager command '%s', skipping pager\n")
--- a/tests/test-pager.t	Thu Apr 13 14:48:18 2017 -0400
+++ b/tests/test-pager.t	Thu Apr 13 08:27:19 2017 -0700
@@ -254,3 +254,29 @@
    8: a 8
    9: a 9
   10: a 10
+
+Environment variables like LESS and LV are set automatically:
+  $ cat > $TESTTMP/printlesslv.py <<EOF
+  > import os, sys
+  > sys.stdin.read()
+  > for name in ['LESS', 'LV']:
+  >     sys.stdout.write(('%s=%s\n') % (name, os.environ.get(name, '-')))
+  > sys.stdout.flush()
+  > EOF
+
+  $ cat >> $HGRCPATH <<EOF
+  > [alias]
+  > noop = log -r 0 -T ''
+  > [ui]
+  > formatted=1
+  > [pager]
+  > pager = $PYTHON $TESTTMP/printlesslv.py
+  > EOF
+  $ unset LESS
+  $ unset LV
+  $ hg noop --pager=on
+  LESS=FRX
+  LV=-c
+  $ LESS=EFGH hg noop --pager=on
+  LESS=EFGH
+  LV=-c