[PATCH] Log, annotate and diff use an environment pager if available

David Soria Parra sn_ at gmx.net
Thu Mar 6 06:37:09 CST 2008


fixed

---

# HG changeset patch
# User David Soria Parra <dsp at php.net>
# Date 1204806802 -3600
# Node ID 2e9e86b1c7386153607c5b4b12e2cfdcbcc13f99
# Parent  0068809347d72e552f980487ee669ace9a82d214
Log, annotate and diff use an environment pager if available

Unix systems usually have a PAGER environment variable set.
If it is set, mercurial will use this to display annotate, logs
or diffs instead of just writing them out

diff -r 0068809347d7 -r 2e9e86b1c738 mercurial/cmdutil.py
--- a/mercurial/cmdutil.py	Fri Feb 29 14:48:21 2008 -0800
+++ b/mercurial/cmdutil.py	Thu Mar 06 13:33:22 2008 +0100
@@ -9,6 +9,7 @@ from i18n import _
 from i18n import _
 import os, sys, bisect, stat
 import mdiff, bdiff, util, templater, templatefilters, patch, errno
+import ui.pager as pager

 revrangesep = ':'

@@ -558,6 +559,8 @@ class changeset_printer(object):
     '''show changeset information when templating not requested.'''

     def __init__(self, ui, repo, patch, buffered):
+        self.pager = pager(ui)
+
         self.ui = ui
         self.repo = repo
         self.buffered = buffered
@@ -571,10 +574,10 @@ class changeset_printer(object):
             h = self.header[rev]
             if h != self.lastheader:
                 self.lastheader = h
-                self.ui.write(h)
+                self.pager.write(h)
             del self.header[rev]
         if rev in self.hunk:
-            self.ui.write(self.hunk[rev])
+            self.pager.write(self.hunk[rev])
             del self.hunk[rev]
             return 1
         return 0
diff -r 0068809347d7 -r 2e9e86b1c738 mercurial/commands.py
--- a/mercurial/commands.py	Fri Feb 29 14:48:21 2008 -0800
+++ b/mercurial/commands.py	Thu Mar 06 13:33:22 2008 +0100
@@ -12,6 +12,7 @@ import difflib, patch, time, help, mdiff
 import difflib, patch, time, help, mdiff, tempfile
 import errno, version, socket
 import archival, changegroup, cmdutil, hgweb.server, sshserver, hbisect
+import ui.pager as pager

 # Commands start here, listed alphabetically

@@ -919,12 +920,17 @@ def diff(ui, repo, *pats, **opts):
     it detects as binary. With -a, diff will generate a diff anyway,
     probably with undesirable results.
     """
+    ui = pager(ui)
+    repo.ui = ui
+
     node1, node2 = cmdutil.revpair(repo, opts['rev'])
+

     fns, matchfn, anypats = cmdutil.matchpats(repo, pats, opts)

     patch.diff(repo, node1, node2, fns, match=matchfn,
                opts=patch.diffopts(ui, opts))
+

 def export(ui, repo, *changesets, **opts):
     """dump the header and diffs for one or more changesets
@@ -1193,6 +1199,7 @@ def help_(ui, name=None, with_version=Fa
     commands it provides."""
     option_lists = []

+    ui = pager(ui)
     def addglobalopts(aliases):
         if ui.verbose:
             option_lists.append((_("global options:"), globalopts))
@@ -1226,6 +1233,7 @@ def help_(ui, name=None, with_version=Fa
         doc = i[0].__doc__
         if not doc:
             doc = _("(No help text available)")
+
         if ui.quiet:
             doc = doc.splitlines(0)[0]
         ui.write("\n%s\n" % doc.rstrip())
diff -r 0068809347d7 -r 2e9e86b1c738 mercurial/ui.py
--- a/mercurial/ui.py	Fri Feb 29 14:48:21 2008 -0800
+++ b/mercurial/ui.py	Thu Mar 06 13:33:22 2008 +0100
@@ -1,6 +1,7 @@
 # ui.py - user interface bits for mercurial
 #
 # Copyright 2005-2007 Matt Mackall <mpm at selenic.com>
+# Copyright 2008 David Soria Parra <sn_ at gmx.net>
 #
 # This software may be used and distributed according to the terms
 # of the GNU General Public License, incorporated herein by reference.
@@ -478,3 +479,56 @@ class ui(object):
                 os.environ.get("VISUAL") or
                 os.environ.get("EDITOR", "vi"))

+class pager(object):
+    """
+    Use the environment pager that is usually set on
+    UNIX like systems to display the contents of e.g. the revlog
+
+    the pager is not used if the output is not bigger than min_lines
+    but instead just print to stdout.
+    if min_lines is 0, the pager is always used
+    """
+    def __init__(self, ui, min_lines=25):
+        self.buffer = []
+        self.ui = ui
+        self.min_lines = min_lines
+
+    def __del__(self):
+        if len(self.buffer) < self.min_lines:
+            self.ui.write(os.linesep.join(self.buffer) + os.linesep)
+        elif self.proc:
+            try:
+                self.proc.close()
+            except IOError:
+                # we might get into an broken pipe if the users quit
+                # the pager before we finished io
+                pass
+
+    def __getattr__(self, key):
+        try:
+            return getattr(self.ui, key)
+        except AttributeError:
+            pass
+
+    def write(self, w):
+        self.buffer.extend(w.splitlines())
+        if len(self.buffer) >= self.min_lines and not self.buffer_written:
+            # we reached the limit and not yet written the buffer
+            self.buffer_written = True
+            if self.getpager() and not self.proc:
+                # we now that we need a process only if
+                # we already reach the min_lines limit
+                self.proc = os.popen(self.getpager(), "w")
+                self.proc.write(os.linesep.join(self.buffer))
+            else:
+                self.ui.write(os.linesep.join(self.buffer))
+        elif self.buffer_written:
+            if self.proc:
+                self.proc.write(w)
+            else:
+                self.ui.write(w)
+
+    def getpager(self):
+        '''return a pager'''
+        return (os.environ.get("PAGER") or
+                self.config("ui", "pager"))



More information about the Mercurial-devel mailing list