##// END OF EJS Templates
Added tag 4.1.3 for changeset 77eaf9539499
Added tag 4.1.3 for changeset 77eaf9539499

File last commit:

r31406:e83302d4 default
r32051:962f7cfb stable
Show More
pager.py
174 lines | 5.5 KiB | text/x-python | PythonLexer
David Soria Parra
Use the pager given by the environment to display long output...
r6323 # pager.py - display output using a pager
#
# Copyright 2008 David Soria Parra <dsp@php.net>
#
Martin Geisler
updated license to be explicit about GPL version 2
r8225 # This software may be used and distributed according to the terms of the
Matt Mackall
Update license to GPLv2+
r10263 # GNU General Public License version 2 or any later version.
David Soria Parra
Use the pager given by the environment to display long output...
r6323 #
Brodie Rao
help: refer to user configuration file more consistently...
r12083 # To load the extension, add it to your configuration file:
David Soria Parra
Use the pager given by the environment to display long output...
r6323 #
# [extension]
Martin Geisler
hgext: enable extensions without "hgext." prefix in help texts
r10112 # pager =
David Soria Parra
Use the pager given by the environment to display long output...
r6323 #
timeless
pager: use single quotes in use warning
r29967 # Run 'hg help pager' to get info on configuration.
Christian Ebert
pager: make config info accessible with "hg help pager"
r6462
Cédric Duval
extensions: improve the consistency of synopses...
r8894 '''browse command output with an external pager
Christian Ebert
pager: make config info accessible with "hg help pager"
r6462
Martin Geisler
pager: use reST syntax for literal blocks
r9212 To set the pager that should be used, set the application variable::
Christian Ebert
pager: make config info accessible with "hg help pager"
r6462
[pager]
Thomas Arendsen Hein
pager: drop -S option for less in example for pager configuration...
r17305 pager = less -FRX
Christian Ebert
pager: make config info accessible with "hg help pager"
r6462
Martin Geisler
pager: wrap docstrings at 70 characters
r9267 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.
Christian Ebert
pager: make config info accessible with "hg help pager"
r6462
You can disable the pager for certain commands by adding them to the
Martin Geisler
pager: use reST syntax for literal blocks
r9212 pager.ignore list::
Christian Ebert
pager: make config info accessible with "hg help pager"
r6462
[pager]
ignore = version, help, update
Martin Geisler
pager: wrap docstrings at 70 characters
r9267 You can also enable the pager only for certain commands using
Brodie Rao
pager: provide a default attend list...
r9841 pager.attend. Below is the default list of commands to be paged::
Christian Ebert
pager: make config info accessible with "hg help pager"
r6462
[pager]
Brodie Rao
pager: provide a default attend list...
r9841 attend = annotate, cat, diff, export, glog, log, qdiff
Setting pager.attend to an empty value will cause all commands to be
paged.
Christian Ebert
pager: make config info accessible with "hg help pager"
r6462
If pager.attend is present, pager.ignore will be ignored.
Matt Mackall
pager: add attend-<command> option...
r21281 Lastly, you can enable and disable paging for individual commands with
the attend-<command> option. This setting takes precedence over
existing attend and ignore options and defaults::
[pager]
attend-cat = false
Martin Geisler
Use hg role in help strings
r10973 To ignore global commands like :hg:`version` or :hg:`help`, you have
Brodie Rao
help: refer to user configuration file more consistently...
r12083 to specify them in your user configuration file.
Brodie Rao
pager: add global --pager=<auto/boolean> option
r12694
timeless
pager: improve help for --pager=...
r27128 To control whether the pager is used at all for an individual command,
you can use --pager=<value>::
- use as needed: `auto`.
- require the pager: `yes` or `on`.
- suppress the pager: `no` or `off` (any unrecognized value
will also work).
Matt Mackall
pager: add attend-<command> option...
r21281
Christian Ebert
pager: make config info accessible with "hg help pager"
r6462 '''
Augie Fackler
pager: use absolute_import
r28320 from __future__ import absolute_import
David Soria Parra
Use the pager given by the environment to display long output...
r6323
Augie Fackler
pager: use absolute_import
r28320 import atexit
import os
import signal
import subprocess
import sys
Yuya Nishihara
py3: move up symbol imports to enforce import-checker rules...
r29205 from mercurial.i18n import _
Augie Fackler
pager: use absolute_import
r28320 from mercurial import (
cmdutil,
commands,
dispatch,
Pulkit Goyal
py3: replace os.environ with encoding.environ (part 2 of 5)
r30635 encoding,
Augie Fackler
pager: use absolute_import
r28320 extensions,
util,
)
David Soria Parra
Use the pager given by the environment to display long output...
r6323
Augie Fackler
extensions: change magic "shipped with hg" string...
r29841 # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for
Augie Fackler
extensions: document that `testedwith = 'internal'` is special...
r25186 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
# be specifying the version(s) of Mercurial they are tested with, or
# leave the attribute unspecified.
Augie Fackler
extensions: change magic "shipped with hg" string...
r29841 testedwith = 'ships-with-hg-core'
Augie Fackler
hgext: mark all first-party extensions as such
r16743
Yuya Nishihara
pager: inline _pagersubprocess() into _runpager()...
r26452 def _runpager(ui, p):
Brodie Rao
pager: preserve Hg's exit code (and fix Windows support) (issue3225)...
r16631 pager = subprocess.Popen(p, shell=True, bufsize=-1,
close_fds=util.closefds, stdin=subprocess.PIPE,
Yuya Nishihara
py3: bulk replace sys.stdin/out/err by util's...
r30473 stdout=util.stdout, stderr=util.stderr)
Brodie Rao
pager: preserve Hg's exit code (and fix Windows support) (issue3225)...
r16631
Yuya Nishihara
pager: recreate stdout to make it line-buffered...
r26454 # back up original file objects and descriptors
olduifout = ui.fout
Yuya Nishihara
py3: bulk replace sys.stdin/out/err by util's...
r30473 oldstdout = util.stdout
stdoutfd = os.dup(util.stdout.fileno())
stderrfd = os.dup(util.stderr.fileno())
Yuya Nishihara
pager: recreate stdout to make it line-buffered...
r26454
# create new line-buffered stdout so that output can show up immediately
Yuya Nishihara
py3: bulk replace sys.stdin/out/err by util's...
r30473 ui.fout = util.stdout = newstdout = os.fdopen(util.stdout.fileno(), 'wb', 1)
os.dup2(pager.stdin.fileno(), util.stdout.fileno())
if ui._isatty(util.stderr):
os.dup2(pager.stdin.fileno(), util.stderr.fileno())
Brodie Rao
pager: preserve Hg's exit code (and fix Windows support) (issue3225)...
r16631
@atexit.register
def killpager():
Matt Mackall
pager: catch ctrl-c on exit (issue3834)
r18717 if util.safehasattr(signal, "SIGINT"):
signal.signal(signal.SIGINT, signal.SIG_IGN)
Brodie Rao
pager: preserve Hg's exit code (and fix Windows support) (issue3225)...
r16631 pager.stdin.close()
Yuya Nishihara
pager: recreate stdout to make it line-buffered...
r26454 ui.fout = olduifout
Yuya Nishihara
py3: bulk replace sys.stdin/out/err by util's...
r30473 util.stdout = oldstdout
Yuya Nishihara
pager: recreate stdout to make it line-buffered...
r26454 # close new stdout while it's associated with pager; otherwise stdout
# fd would be closed when newstdout is deleted
newstdout.close()
# restore original fds: stdout is open again
Yuya Nishihara
py3: bulk replace sys.stdin/out/err by util's...
r30473 os.dup2(stdoutfd, util.stdout.fileno())
os.dup2(stderrfd, util.stderr.fileno())
Brodie Rao
pager: preserve Hg's exit code (and fix Windows support) (issue3225)...
r16631 pager.wait()
Brodie Rao
pager: fork and exec pager as parent process...
r11182
David Soria Parra
Use the pager given by the environment to display long output...
r6323 def uisetup(ui):
Jun Wu
pager: wrap ui._runpager...
r30722 class pagerui(ui.__class__):
def _runpager(self, pagercmd):
_runpager(self, pagercmd)
ui.__class__ = pagerui
Matt Mackall
extensions: use new wrapper functions
r7216 def pagecmd(orig, ui, options, cmd, cmdfunc):
Pulkit Goyal
py3: replace os.environ with encoding.environ (part 2 of 5)
r30635 p = ui.config("pager", "pager", encoding.environ.get("PAGER"))
Matt Mackall
pager: break pager invocation out of command check loop
r21277 usepager = False
Matt Mackall
pager: break always out of command check loop
r21278 always = util.parsebool(options['pager'])
Matt Mackall
pager: break auto out of command check loop
r21279 auto = options['pager'] == 'auto'
Idan Kamara
util: add helper function isatty(fd) to check for tty-ness
r14515
Yuya Nishihara
pager: wrap _runcommand() no matter if stdout is redirected...
r30847 if not p or '--debugger' in sys.argv or not ui.formatted():
Matt Mackall
pager: break pager invocation out of command check loop
r21277 pass
Matt Mackall
pager: break always out of command check loop
r21278 elif always:
usepager = True
Matt Mackall
pager: break auto out of command check loop
r21279 elif not auto:
usepager = False
Matt Mackall
pager: break pager invocation out of command check loop
r21277 else:
Brodie Rao
pager: provide a default attend list...
r9841 attend = ui.configlist('pager', 'attend', attended)
Matt Mackall
pager: variable reorder
r21280 ignore = ui.configlist('pager', 'ignore')
David Soria Parra
pager: honour internal aliases...
r19940 cmds, _ = cmdutil.findcmd(cmd, commands.table)
for cmd in cmds:
Matt Mackall
pager: add attend-<command> option...
r21281 var = 'attend-%s' % cmd
if ui.config('pager', var):
usepager = ui.configbool('pager', var)
break
Matt Mackall
pager: break auto out of command check loop
r21279 if (cmd in attend or
(cmd not in ignore and not attend)):
Matt Mackall
pager: break pager invocation out of command check loop
r21277 usepager = True
David Soria Parra
pager: honour internal aliases...
r19940 break
Matt Mackall
pager: break pager invocation out of command check loop
r21277
Gregory Szorc
pager: set an attribute on ui indicating that a pager is active...
r24066 setattr(ui, 'pageractive', usepager)
Matt Mackall
pager: break pager invocation out of command check loop
r21277 if usepager:
ui.setconfig('ui', 'formatted', ui.formatted(), 'pager')
ui.setconfig('ui', 'interactive', False, 'pager')
if util.safehasattr(signal, "SIGPIPE"):
signal.signal(signal.SIGPIPE, signal.SIG_DFL)
Jun Wu
pager: wrap ui._runpager...
r30722 ui._runpager(p)
Matt Mackall
extensions: use new wrapper functions
r7216 return orig(ui, options, cmd, cmdfunc)
David Soria Parra <dsp <at> php.net>
pager: Add a configuration to enable/disable the pager for certain commands...
r6417
Gregory Szorc
pager: ensure wrapped dispatch._runcommand runs before color's...
r24067 # Wrap dispatch._runcommand after color is loaded so color can see
# ui.pageractive. Otherwise, if we loaded first, color's wrapped
# dispatch._runcommand would run without having access to ui.pageractive.
def afterloaded(loaded):
extensions.wrapfunction(dispatch, '_runcommand', pagecmd)
extensions.afterloaded('color', afterloaded)
Brodie Rao
pager: provide a default attend list...
r9841
Brodie Rao
pager: add global --pager=<auto/boolean> option
r12694 def extsetup(ui):
commands.globalopts.append(
('', 'pager', 'auto',
_("when to paginate (boolean, always, auto, or never)"),
_('TYPE')))
Brodie Rao
pager: provide a default attend list...
r9841 attended = ['annotate', 'cat', 'diff', 'export', 'glog', 'log', 'qdiff']