Source

TPager / tpager.py

# tpager.py - browse command output with an external pager using temp files
#
# Copyright (C) 2008 David Soria Parra <dsp@php.net>
# Copyright (C) 2010 Eduard Stefan <alexandrul.ct@gmail.com>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.


'''browse command output with an external pager using temp files

This extension is based on the original Mercurial pager extension,
and uses the same format for the configuration section.

To set the pager that should be used, set the application variable::

  [pager]
  pager = LESS='FSRX' less

On Windows you must define the environment variable LESS = FSRX
using System Properties (Control Panel) and set the pager like::

  [pager]
  pager = c:\\tools\\less.exe

or you could specify the pager options on the same line::

  [pager]
  pager = c:\\tools\\less.exe -FSRX

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.

You can enable the pager only for certain commands using
pager.attend. Below is the default list of commands to be paged::

  [pager]
  attend = annotate, cat, diff, export, glog, help, log, qdiff, status, tip

Setting pager.attend to an empty value will disable paging.

For colored output on Mercurial 1.6+ the following options must be set::

  [color]
  mode = ansi

  [pager]
  hg16mode = yes
'''


import os
import signal
import subprocess
import sys
import tempfile

from mercurial import dispatch, util, extensions


def uisetup(ui):

    def pagecmd(orig, ui, options, cmd, cmdfunc):

        # check environment
        if (('HGPLAIN' in os.environ) or
            (ui.plain()) or
            ('--debugger' in sys.argv)):
            return orig(ui, options, cmd, cmdfunc)

        # check for tty
        t = False

        try:
            if sys.stdout.isatty():
                t = True
        except AttributeError:
            t = False

        if not t:
            return orig(ui, options, cmd, cmdfunc)

        # check Mercurial 1.6+ mode
        hg16mode = ui.config('pager', 'hg16mode', 'no')

        # check for pager app and valid command
        p = ui.config('pager', 'pager', os.environ.get('PAGER'))

        if ((not p) or
            (cmd not in ui.configlist('pager', 'attend', attended))):
            return orig(ui, options, cmd, cmdfunc)

        # running pager
        ui.setconfig('ui', 'interactive', False)

        ui.pushbuffer()
        exitcode = orig(ui, options, cmd, cmdfunc)

        if hg16mode == 'yes':
            pcontent = ui.popbuffer(True)
        else:
            pcontent = ui.popbuffer()

        fname = tempfile.NamedTemporaryFile().name

        f = open(fname, 'wb')

        # strip CR
        for line in pcontent:
            f.write(line.replace("\r", ""))

        f.flush()
        f.close()

        subprocess.call(p + " " + fname)

        os.remove(fname)

        return exitcode

    extensions.wrapfunction(dispatch, '_runcommand', pagecmd)

attended = ['annotate', 'bookmarks', 'cat', 'diff', 'export', 'glog', 'heads', 'help', 'log', 'parents', 'qdiff', 'status', 'summary', 'tip']