##// END OF EJS Templates
pager: improve help for --pager=...
timeless -
r27128:efceacd6 default
parent child Browse files
Show More
@@ -1,154 +1,158 b''
1 1 # pager.py - display output using a pager
2 2 #
3 3 # Copyright 2008 David Soria Parra <dsp@php.net>
4 4 #
5 5 # This software may be used and distributed according to the terms of the
6 6 # GNU General Public License version 2 or any later version.
7 7 #
8 8 # To load the extension, add it to your configuration file:
9 9 #
10 10 # [extension]
11 11 # pager =
12 12 #
13 13 # Run "hg help pager" to get info on configuration.
14 14
15 15 '''browse command output with an external pager
16 16
17 17 To set the pager that should be used, set the application variable::
18 18
19 19 [pager]
20 20 pager = less -FRX
21 21
22 22 If no pager is set, the pager extensions uses the environment variable
23 23 $PAGER. If neither pager.pager, nor $PAGER is set, no pager is used.
24 24
25 25 You can disable the pager for certain commands by adding them to the
26 26 pager.ignore list::
27 27
28 28 [pager]
29 29 ignore = version, help, update
30 30
31 31 You can also enable the pager only for certain commands using
32 32 pager.attend. Below is the default list of commands to be paged::
33 33
34 34 [pager]
35 35 attend = annotate, cat, diff, export, glog, log, qdiff
36 36
37 37 Setting pager.attend to an empty value will cause all commands to be
38 38 paged.
39 39
40 40 If pager.attend is present, pager.ignore will be ignored.
41 41
42 42 Lastly, you can enable and disable paging for individual commands with
43 43 the attend-<command> option. This setting takes precedence over
44 44 existing attend and ignore options and defaults::
45 45
46 46 [pager]
47 47 attend-cat = false
48 48
49 49 To ignore global commands like :hg:`version` or :hg:`help`, you have
50 50 to specify them in your user configuration file.
51 51
52 The --pager=... option can also be used to control when the pager is
53 used. Use a boolean value like yes, no, on, off, or use auto for
54 normal behavior.
52 To control whether the pager is used at all for an individual command,
53 you can use --pager=<value>::
54
55 - use as needed: `auto`.
56 - require the pager: `yes` or `on`.
57 - suppress the pager: `no` or `off` (any unrecognized value
58 will also work).
55 59
56 60 '''
57 61
58 62 import atexit, sys, os, signal, subprocess
59 63 from mercurial import commands, dispatch, util, extensions, cmdutil
60 64 from mercurial.i18n import _
61 65
62 66 # Note for extension authors: ONLY specify testedwith = 'internal' for
63 67 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
64 68 # be specifying the version(s) of Mercurial they are tested with, or
65 69 # leave the attribute unspecified.
66 70 testedwith = 'internal'
67 71
68 72 def _runpager(ui, p):
69 73 pager = subprocess.Popen(p, shell=True, bufsize=-1,
70 74 close_fds=util.closefds, stdin=subprocess.PIPE,
71 75 stdout=sys.stdout, stderr=sys.stderr)
72 76
73 77 # back up original file objects and descriptors
74 78 olduifout = ui.fout
75 79 oldstdout = sys.stdout
76 80 stdoutfd = os.dup(sys.stdout.fileno())
77 81 stderrfd = os.dup(sys.stderr.fileno())
78 82
79 83 # create new line-buffered stdout so that output can show up immediately
80 84 ui.fout = sys.stdout = newstdout = os.fdopen(sys.stdout.fileno(), 'wb', 1)
81 85 os.dup2(pager.stdin.fileno(), sys.stdout.fileno())
82 86 if ui._isatty(sys.stderr):
83 87 os.dup2(pager.stdin.fileno(), sys.stderr.fileno())
84 88
85 89 @atexit.register
86 90 def killpager():
87 91 if util.safehasattr(signal, "SIGINT"):
88 92 signal.signal(signal.SIGINT, signal.SIG_IGN)
89 93 pager.stdin.close()
90 94 ui.fout = olduifout
91 95 sys.stdout = oldstdout
92 96 # close new stdout while it's associated with pager; otherwise stdout
93 97 # fd would be closed when newstdout is deleted
94 98 newstdout.close()
95 99 # restore original fds: stdout is open again
96 100 os.dup2(stdoutfd, sys.stdout.fileno())
97 101 os.dup2(stderrfd, sys.stderr.fileno())
98 102 pager.wait()
99 103
100 104 def uisetup(ui):
101 105 if '--debugger' in sys.argv or not ui.formatted():
102 106 return
103 107
104 108 def pagecmd(orig, ui, options, cmd, cmdfunc):
105 109 p = ui.config("pager", "pager", os.environ.get("PAGER"))
106 110 usepager = False
107 111 always = util.parsebool(options['pager'])
108 112 auto = options['pager'] == 'auto'
109 113
110 114 if not p:
111 115 pass
112 116 elif always:
113 117 usepager = True
114 118 elif not auto:
115 119 usepager = False
116 120 else:
117 121 attend = ui.configlist('pager', 'attend', attended)
118 122 ignore = ui.configlist('pager', 'ignore')
119 123 cmds, _ = cmdutil.findcmd(cmd, commands.table)
120 124
121 125 for cmd in cmds:
122 126 var = 'attend-%s' % cmd
123 127 if ui.config('pager', var):
124 128 usepager = ui.configbool('pager', var)
125 129 break
126 130 if (cmd in attend or
127 131 (cmd not in ignore and not attend)):
128 132 usepager = True
129 133 break
130 134
131 135 setattr(ui, 'pageractive', usepager)
132 136
133 137 if usepager:
134 138 ui.setconfig('ui', 'formatted', ui.formatted(), 'pager')
135 139 ui.setconfig('ui', 'interactive', False, 'pager')
136 140 if util.safehasattr(signal, "SIGPIPE"):
137 141 signal.signal(signal.SIGPIPE, signal.SIG_DFL)
138 142 _runpager(ui, p)
139 143 return orig(ui, options, cmd, cmdfunc)
140 144
141 145 # Wrap dispatch._runcommand after color is loaded so color can see
142 146 # ui.pageractive. Otherwise, if we loaded first, color's wrapped
143 147 # dispatch._runcommand would run without having access to ui.pageractive.
144 148 def afterloaded(loaded):
145 149 extensions.wrapfunction(dispatch, '_runcommand', pagecmd)
146 150 extensions.afterloaded('color', afterloaded)
147 151
148 152 def extsetup(ui):
149 153 commands.globalopts.append(
150 154 ('', 'pager', 'auto',
151 155 _("when to paginate (boolean, always, auto, or never)"),
152 156 _('TYPE')))
153 157
154 158 attended = ['annotate', 'cat', 'diff', 'export', 'glog', 'log', 'qdiff']
General Comments 0
You need to be logged in to leave comments. Login now