hgext/pager.py
changeset 12695 05077896ffe2
parent 12694 04f6de46bf3a
child 12876 a3b182dd548a
equal deleted inserted replaced
12694:04f6de46bf3a 12695:05077896ffe2
    19   [pager]
    19   [pager]
    20   pager = LESS='FSRX' less
    20   pager = LESS='FSRX' less
    21 
    21 
    22 If no pager is set, the pager extensions uses the environment variable
    22 If no pager is set, the pager extensions uses the environment variable
    23 $PAGER. If neither pager.pager, nor $PAGER is set, no pager is used.
    23 $PAGER. If neither pager.pager, nor $PAGER is set, no pager is used.
       
    24 
       
    25 By default, the pager is only executed if a command has output. To
       
    26 force the pager to run even if a command prints nothing, set::
       
    27 
       
    28   [pager]
       
    29   force = True
    24 
    30 
    25 If you notice "BROKEN PIPE" error messages, you can disable them by
    31 If you notice "BROKEN PIPE" error messages, you can disable them by
    26 setting::
    32 setting::
    27 
    33 
    28   [pager]
    34   [pager]
    55 
    61 
    56 import sys, os, signal, shlex, errno
    62 import sys, os, signal, shlex, errno
    57 from mercurial import commands, dispatch, util, extensions
    63 from mercurial import commands, dispatch, util, extensions
    58 from mercurial.i18n import _
    64 from mercurial.i18n import _
    59 
    65 
    60 def _runpager(p):
    66 def _runpager(p, sigpipe=False):
    61     if not hasattr(os, 'fork'):
    67     if not hasattr(os, 'fork'):
    62         sys.stderr = sys.stdout = util.popen(p, 'wb')
    68         sys.stderr = sys.stdout = util.popen(p, 'wb')
    63         return
    69         return
    64     fdin, fdout = os.pipe()
    70     fdin, fdout = os.pipe()
    65     pid = os.fork()
    71     pid = os.fork()
    66     if pid == 0:
    72     if pid == 0:
    67         os.close(fdin)
    73         os.close(fdin)
    68         os.dup2(fdout, sys.stdout.fileno())
    74         os.dup2(fdout, sys.stdout.fileno())
    69         os.dup2(fdout, sys.stderr.fileno())
    75         os.dup2(fdout, sys.stderr.fileno())
    70         os.close(fdout)
    76         os.close(fdout)
       
    77         if sigpipe:
       
    78             signal.signal(signal.SIGPIPE, signal.SIG_DFL)
    71         return
    79         return
    72     os.dup2(fdin, sys.stdin.fileno())
    80     os.dup2(fdin, sys.stdin.fileno())
    73     os.close(fdin)
    81     os.close(fdin)
    74     os.close(fdout)
    82     os.close(fdout)
    75     try:
    83     try:
    84 
    92 
    85 def uisetup(ui):
    93 def uisetup(ui):
    86     if ui.plain():
    94     if ui.plain():
    87         return
    95         return
    88 
    96 
       
    97     class pagerui(ui.__class__):
       
    98         _pager = None
       
    99         _pagerstarted = False
       
   100 
       
   101         def write(self, *args, **opts):
       
   102             if self._pager and not self._pagerstarted:
       
   103                 self._pagerstarted = True
       
   104                 self._pager()
       
   105             return super(pagerui, self).write(*args, **opts)
       
   106 
       
   107         def write_err(self, *args, **opts):
       
   108             if self._pager and not self._pagerstarted:
       
   109                 self._pagerstarted = True
       
   110                 self._pager()
       
   111             return super(pagerui, self).write(*args, **opts)
       
   112     ui.__class__ = pagerui
       
   113 
    89     def pagecmd(orig, ui, options, cmd, cmdfunc):
   114     def pagecmd(orig, ui, options, cmd, cmdfunc):
    90         p = ui.config("pager", "pager", os.environ.get("PAGER"))
   115         p = ui.config("pager", "pager", os.environ.get("PAGER"))
    91         if p and sys.stdout.isatty() and '--debugger' not in sys.argv:
   116         if p and sys.stdout.isatty() and '--debugger' not in sys.argv:
    92             attend = ui.configlist('pager', 'attend', attended)
   117             attend = ui.configlist('pager', 'attend', attended)
    93             auto = options['pager'] == 'auto'
   118             auto = options['pager'] == 'auto'
    95             if (always or auto and
   120             if (always or auto and
    96                 (cmd in attend or
   121                 (cmd in attend or
    97                  (cmd not in ui.configlist('pager', 'ignore') and not attend))):
   122                  (cmd not in ui.configlist('pager', 'ignore') and not attend))):
    98                 ui.setconfig('ui', 'formatted', ui.formatted())
   123                 ui.setconfig('ui', 'formatted', ui.formatted())
    99                 ui.setconfig('ui', 'interactive', False)
   124                 ui.setconfig('ui', 'interactive', False)
   100                 _runpager(p)
   125                 sigpipe = ui.configbool('pager', 'quiet')
   101                 if ui.configbool('pager', 'quiet'):
   126                 if ui.configbool('pager', 'force'):
   102                     signal.signal(signal.SIGPIPE, signal.SIG_DFL)
   127                     _runpager(p, sigpipe)
       
   128                 else:
       
   129                     ui._pager = lambda: _runpager(p, sigpipe)
   103         return orig(ui, options, cmd, cmdfunc)
   130         return orig(ui, options, cmd, cmdfunc)
   104 
   131 
   105     extensions.wrapfunction(dispatch, '_runcommand', pagecmd)
   132     extensions.wrapfunction(dispatch, '_runcommand', pagecmd)
   106 
   133 
   107 def extsetup(ui):
   134 def extsetup(ui):