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