[PATCH] Use the pager given by the environment to display long output

David Soria Parra sn_ at gmx.net
Sun Mar 16 19:09:06 CDT 2008

I tried to follow all advices from the people who replied to the last thread about paging.
Therfore the pager is now included in the ui and disabled by default unless ui.usepager is set to True.

Also the pager doesn't buffer the output itself, but instead gives all the decision to the pager
application. The problem with this easier approach is that it will result in 'hg update' to be
paged. It would work prefectly for 70% of the use cases if we set the os.environ['LESS'] variable to
'FSRX' (people can set this in theiry bashrc), but in my opinion this is too much 'less' and
linux/unices depending. Implementing it in python would blow up the code a lot if we want to do it
as nice as less.


# HG changeset patch
# User David Soria Parra <dsp at php.net>
# Date 1205712184 -3600
# Node ID 4030b85c139cbe03b5405e7481a268e3bc7a78e1
# Parent  c50ac875ffcb8ae53beeeeee119a4dae677c4d23
Use the pager given by the environment to display long output

Unix systems usually have a PAGER environment variable set.
If it is set, mercurial will use the pager application to display

Two configuration variables are available to influence the behaviour of the
pager. ui.pager sets the pager application. The pager is
only used if ui.usepager is true. By default ui.usepager is disabled.

diff -r c50ac875ffcb -r 4030b85c139c doc/hgrc.5.txt
--- a/doc/hgrc.5.txt	Sat Mar 15 16:51:53 2008 -0500
+++ b/doc/hgrc.5.txt	Mon Mar 17 01:03:04 2008 +0100
@@ -522,6 +522,12 @@
     Print debugging information.  True or False.  Default is False.
     The editor to use during a commit.  Default is $EDITOR or "vi".
+  pager;;
+    The pager that is used when displaying long output.
+    Default is $PAGER. If not set, the output is written to the
+    stdandard output.
+  usepager;;
+    If set to true, the system pager is used. True or False. Default is False.
     Encoding to try if it's not possible to decode the changelog using
     UTF-8.  Default is ISO-8859-1.
diff -r c50ac875ffcb -r 4030b85c139c mercurial/ui.py
--- a/mercurial/ui.py	Sat Mar 15 16:51:53 2008 -0500
+++ b/mercurial/ui.py	Mon Mar 17 01:03:04 2008 +0100
@@ -31,6 +31,7 @@
         self.overlay = None
         self.buffers = []
+        self.pager = None
         if parentui is None:
             # this is the parent of all ui children
             self.parentui = None
@@ -63,6 +64,15 @@

     def __getattr__(self, key):
         return getattr(self.parentui, key)
+    def __del__(self):
+        if self.pager:
+            try:
+                self.pager.close()
+            except IOError:
+                # we might get into an broken pipe if the users quit
+                # the pager before we finished io
+                pass

     def isatty(self):
         if ui._isatty is None:
@@ -370,11 +380,17 @@
         return "".join(self.buffers.pop())

     def write(self, *args):
+        """Write to a pager if available, otherwise to stdout"""
         if self.buffers:
             self.buffers[-1].extend([str(a) for a in args])
+            if self.getpager() and not self.pager:
+                self.pager = os.popen(self.getpager(), "w")
             for a in args:
-                sys.stdout.write(str(a))
+                if self.pager:
+                    self.pager.write(a)
+                else:
+                    sys.stdout.write(str(a))

     def write_err(self, *args):
@@ -389,6 +405,8 @@

     def flush(self):
+        try: self.pager.flush()
+        except: pass
         try: sys.stdout.flush()
         except: pass
         try: sys.stderr.flush()
@@ -478,3 +496,8 @@
                 os.environ.get("VISUAL") or
                 os.environ.get("EDITOR", "vi"))

+    def getpager(self):
+        '''return a pager'''
+        if self.configbool("ui", "usepager", False):
+            return (self.config("ui", "pager")
+                    or os.environ.get("PAGER"))

More information about the Mercurial-devel mailing list