[PATCH 2 of 2 resend] pager: don't run pager if nothing is written to stdout/stderr

Brodie Rao brodie at bitheap.org
Sun Oct 10 11:46:19 CDT 2010


# HG changeset patch
# User Brodie Rao <brodie at bitheap.org>
# Date 1286728503 18000
# Node ID f79b96c0014274fc5476cc52f0ddd2f1f2d6b4a0
# Parent  c507bc88f90f7264f654e8f888eff0345c0e146e
pager: don't run pager if nothing is written to stdout/stderr

This decides when to run the pager based on the first call to
ui.write() and ui.write_err(). This has the side effect of not the
output of subprocesses that write output before hg does.

diff --git a/hgext/pager.py b/hgext/pager.py
--- a/hgext/pager.py
+++ b/hgext/pager.py
@@ -22,6 +22,12 @@ To set the pager that should be used, se
 If no pager is set, the pager extensions uses the environment variable
 $PAGER. If neither pager.pager, nor $PAGER is set, no pager is used.
 
+By default, the pager is only executed if a command has output. To
+force the pager to run even if a command prints nothing, set::
+
+  [pager]
+  force = True
+
 If you notice "BROKEN PIPE" error messages, you can disable them by
 setting::
 
@@ -57,7 +63,7 @@ import sys, os, signal, shlex, errno
 from mercurial import commands, dispatch, util, extensions
 from mercurial.i18n import _
 
-def _runpager(p):
+def _runpager(p, sigpipe=False):
     if not hasattr(os, 'fork'):
         sys.stderr = sys.stdout = util.popen(p, 'wb')
         return
@@ -68,6 +74,8 @@ def _runpager(p):
         os.dup2(fdout, sys.stdout.fileno())
         os.dup2(fdout, sys.stderr.fileno())
         os.close(fdout)
+        if sigpipe:
+            signal.signal(signal.SIGPIPE, signal.SIG_DFL)
         return
     os.dup2(fdin, sys.stdin.fileno())
     os.close(fdin)
@@ -86,6 +94,23 @@ def uisetup(ui):
     if ui.plain():
         return
 
+    class pagerui(ui.__class__):
+        _pager = None
+        _pagerstarted = False
+
+        def write(self, *args, **opts):
+            if self._pager and not self._pagerstarted:
+                self._pagerstarted = True
+                self._pager()
+            return super(pagerui, self).write(*args, **opts)
+
+        def write_err(self, *args, **opts):
+            if self._pager and not self._pagerstarted:
+                self._pagerstarted = True
+                self._pager()
+            return super(pagerui, self).write(*args, **opts)
+    ui.__class__ = pagerui
+
     def pagecmd(orig, ui, options, cmd, cmdfunc):
         p = ui.config("pager", "pager", os.environ.get("PAGER"))
         if p and sys.stdout.isatty() and '--debugger' not in sys.argv:
@@ -97,9 +122,11 @@ def uisetup(ui):
                  (cmd not in ui.configlist('pager', 'ignore') and not attend))):
                 ui.setconfig('ui', 'formatted', ui.formatted())
                 ui.setconfig('ui', 'interactive', False)
-                _runpager(p)
-                if ui.configbool('pager', 'quiet'):
-                    signal.signal(signal.SIGPIPE, signal.SIG_DFL)
+                sigpipe = ui.configbool('pager', 'quiet')
+                if ui.configbool('pager', 'force'):
+                    _runpager(p, sigpipe)
+                else:
+                    ui._pager = lambda: _runpager(p, sigpipe)
         return orig(ui, options, cmd, cmdfunc)
 
     extensions.wrapfunction(dispatch, '_runcommand', pagecmd)


More information about the Mercurial-devel mailing list