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

David Soria Parra sn_ at gmx.net
Wed Mar 5 19:11:29 CST 2008


4 files changed, 62 insertions(+), 6 deletions(-)
mercurial/cmdutil.py  |   13 +++++++++----
mercurial/commands.py |   13 ++++++++++++-
mercurial/pager.py    |   30 ++++++++++++++++++++++++++++++
mercurial/ui.py       |   12 +++++++++++-


# HG changeset patch
# User David Soria Parra <sn_ at gmx.net>
# Date 1204765357 -3600
# Node ID 7dbaf6e3b5da2b71ce56b28cefa94af0b8f29a25
# Parent  9d6ad26fab10e06768858ed1a74eff80207cb0f5
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 9d6ad26fab10 -r 7dbaf6e3b5da mercurial/cmdutil.py
--- a/mercurial/cmdutil.py	Tue Dec 18 15:40:46 2007 -0600
+++ b/mercurial/cmdutil.py	Thu Mar 06 02:02:37 2008 +0100
@@ -8,7 +8,7 @@ from node import *
 from node import *
 from i18n import _
 import os, sys, bisect, stat
-import mdiff, bdiff, util, templater, patch, errno
+import mdiff, bdiff, util, templater, patch, errno, pager
 
 revrangesep = ':'
 
@@ -534,6 +534,8 @@ class changeset_printer(object):
     '''show changeset information when templating not requested.'''
 
     def __init__(self, ui, repo, patch, buffered):
+        self.pager = ui.getpager_instance() 
+
         self.ui = ui
         self.repo = repo
         self.buffered = buffered
@@ -542,18 +544,21 @@ class changeset_printer(object):
         self.hunk = {}
         self.lastheader = None
 
-    def flush(self, rev):
+    def write(self, rev):
         if rev in self.header:
             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
+
+    def flush(self):
+        self.pager.flush()
 
     def show(self, rev=0, changenode=None, copies=(), **props):
         if self.buffered:
diff -r 9d6ad26fab10 -r 7dbaf6e3b5da mercurial/commands.py
--- a/mercurial/commands.py	Tue Dec 18 15:40:46 2007 -0600
+++ b/mercurial/commands.py	Thu Mar 06 02:02:37 2008 +0100
@@ -72,6 +72,8 @@ def annotate(ui, repo, *pats, **opts):
     detects as binary. With -a, annotate will generate an annotation
     anyway, probably with undesirable results.
     """
+    ui = ui.getpager_instance()
+
     getdate = util.cachefunc(lambda x: util.datestr(x[0].date()))
 
     if not pats:
@@ -119,6 +121,7 @@ def annotate(ui, repo, *pats, **opts):
         if pieces:
             for p, l in zip(zip(*pieces), lines):
                 ui.write("%s: %s" % (" ".join(p), l[1]))
+    ui.flush()
 
 def archive(ui, repo, dest, **opts):
     '''create unversioned archive of a repository revision
@@ -824,12 +827,18 @@ def diff(ui, repo, *pats, **opts):
     it detects as binary. With -a, diff will generate a diff anyway,
     probably with undesirable results.
     """
+    ui = ui.getpager_instance()
+    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))
+    
+    ui.flush()
 
 def export(ui, repo, *changesets, **opts):
     """dump the header and diffs for one or more changesets
@@ -1124,6 +1133,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("%s\n" % doc.rstrip())
@@ -1677,8 +1687,9 @@ def log(ui, repo, *pats, **opts):
             displayer.show(rev, changenode, copies=copies)
         elif st == 'iter':
             if count == limit: break
-            if displayer.flush(rev):
+            if displayer.write(rev):
                 count += 1
+    displayer.flush()
 
 def manifest(ui, repo, node=None, rev=None):
     """output the current or given revision of the project manifest
diff -r 9d6ad26fab10 -r 7dbaf6e3b5da mercurial/pager.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mercurial/pager.py	Thu Mar 06 02:02:37 2008 +0100
@@ -0,0 +1,30 @@
+# pager.py - use the environment pager
+#
+# 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.
+
+import subprocess
+
+class pager(object):
+    """
+    Use the environment pager that is usually set on
+    UNIX like systems to display the contents of e.g. a log
+    """
+    def __init__(self, ui):
+        self.buffer = []
+        self.ui = ui
+
+    def __getattr__(self, key):
+        try:
+            return getattr(self.ui, key)
+        except AttributeError:
+            pass
+
+    def write(self, w):
+        self.buffer.append(w)
+
+    def flush(self):
+        proc = subprocess.Popen(self.ui.getpager(), stdin=subprocess.PIPE)
+        proc.communicate("".join(self.buffer))
diff -r 9d6ad26fab10 -r 7dbaf6e3b5da mercurial/ui.py
--- a/mercurial/ui.py	Tue Dec 18 15:40:46 2007 -0600
+++ b/mercurial/ui.py	Thu Mar 06 02:02:37 2008 +0100
@@ -7,7 +7,7 @@
 
 from i18n import _
 import errno, getpass, os, re, socket, sys, tempfile
-import ConfigParser, traceback, util
+import ConfigParser, traceback, util, pager
 
 def dupconfig(orig):
     new = util.configparser(orig.defaults())
@@ -470,3 +470,13 @@ class ui(object):
                 os.environ.get("VISUAL") or
                 os.environ.get("EDITOR", "vi"))
 
+    def getpager(self):
+        '''return a pager'''
+        return (os.environ.get("PAGER") or
+                self.config("ui", "pager"))
+
+    def getpager_instance(self):
+        if self.getpager():
+            return pager.pager(self)
+        else:
+            return self


More information about the Mercurial-devel mailing list