##// END OF EJS Templates
progress: use inline literals in help string
Martin Geisler -
r10471:132eb712 stable
parent child Browse files
Show More
@@ -1,183 +1,183 b''
1 # progress.py show progress bars for some actions
1 # progress.py show progress bars for some actions
2 #
2 #
3 # Copyright (C) 2010 Augie Fackler <durin42@gmail.com>
3 # Copyright (C) 2010 Augie Fackler <durin42@gmail.com>
4 #
4 #
5 # This program is free software; you can redistribute it and/or modify it
5 # This program is free software; you can redistribute it and/or modify it
6 # under the terms of the GNU General Public License as published by the
6 # under the terms of the GNU General Public License as published by the
7 # Free Software Foundation; either version 2 of the License, or (at your
7 # Free Software Foundation; either version 2 of the License, or (at your
8 # option) any later version.
8 # option) any later version.
9 #
9 #
10 # This program is distributed in the hope that it will be useful, but
10 # This program is distributed in the hope that it will be useful, but
11 # WITHOUT ANY WARRANTY; without even the implied warranty of
11 # WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
13 # Public License for more details.
13 # Public License for more details.
14 #
14 #
15 # You should have received a copy of the GNU General Public License along
15 # You should have received a copy of the GNU General Public License along
16 # with this program; if not, write to the Free Software Foundation, Inc.,
16 # with this program; if not, write to the Free Software Foundation, Inc.,
17 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18
18
19 """show progress bars for some actions
19 """show progress bars for some actions
20
20
21 This extension uses the progress information logged by hg commands
21 This extension uses the progress information logged by hg commands
22 to draw progress bars that are as informative as possible. Some progress
22 to draw progress bars that are as informative as possible. Some progress
23 bars only offer indeterminate information, while others have a definite
23 bars only offer indeterminate information, while others have a definite
24 end point.
24 end point.
25
25
26 The following settings are available::
26 The following settings are available::
27
27
28 [progress]
28 [progress]
29 delay = 3 # number of seconds (float) before showing the progress bar
29 delay = 3 # number of seconds (float) before showing the progress bar
30 refresh = 0.1 # time in seconds between refreshes of the progress bar
30 refresh = 0.1 # time in seconds between refreshes of the progress bar
31 format = topic bar number # format of the progress bar
31 format = topic bar number # format of the progress bar
32 width = <none> # if set, the maximum width of the progress information
32 width = <none> # if set, the maximum width of the progress information
33 # (that is, min(width, term width) will be used)
33 # (that is, min(width, term width) will be used)
34 clear-complete = True # clear the progress bar after it's done
34 clear-complete = True # clear the progress bar after it's done
35
35
36 Valid entries for the format field are topic, bar, number, unit, and item.
36 Valid entries for the format field are topic, bar, number, unit, and
37 item defaults to the last 20 characters of the item, but this can be
37 item. item defaults to the last 20 characters of the item, but this
38 changed by adding either -<num> which would take the last num characters,
38 can be changed by adding either ``-<num>`` which would take the last
39 or +<num> for the first num characters.
39 num characters, or ``+<num>`` for the first num characters.
40 """
40 """
41
41
42 import sys
42 import sys
43 import time
43 import time
44
44
45 from mercurial import extensions
45 from mercurial import extensions
46 from mercurial import util
46 from mercurial import util
47
47
48 def spacejoin(*args):
48 def spacejoin(*args):
49 return ' '.join(s for s in args if s)
49 return ' '.join(s for s in args if s)
50
50
51 class progbar(object):
51 class progbar(object):
52 def __init__(self, ui):
52 def __init__(self, ui):
53 self.ui = ui
53 self.ui = ui
54 self.resetstate()
54 self.resetstate()
55
55
56 def resetstate(self):
56 def resetstate(self):
57 self.topics = []
57 self.topics = []
58 self.printed = False
58 self.printed = False
59 self.lastprint = time.time() + float(self.ui.config(
59 self.lastprint = time.time() + float(self.ui.config(
60 'progress', 'delay', default=3))
60 'progress', 'delay', default=3))
61 self.indetcount = 0
61 self.indetcount = 0
62 self.refresh = float(self.ui.config(
62 self.refresh = float(self.ui.config(
63 'progress', 'refresh', default=0.1))
63 'progress', 'refresh', default=0.1))
64 self.order = self.ui.configlist(
64 self.order = self.ui.configlist(
65 'progress', 'format',
65 'progress', 'format',
66 default=['topic', 'bar', 'number'])
66 default=['topic', 'bar', 'number'])
67
67
68 def show(self, topic, pos, item, unit, total):
68 def show(self, topic, pos, item, unit, total):
69 termwidth = self.width()
69 termwidth = self.width()
70 self.printed = True
70 self.printed = True
71 head = ''
71 head = ''
72 needprogress = False
72 needprogress = False
73 tail = ''
73 tail = ''
74 for indicator in self.order:
74 for indicator in self.order:
75 add = ''
75 add = ''
76 if indicator == 'topic':
76 if indicator == 'topic':
77 add = topic
77 add = topic
78 elif indicator == 'number':
78 elif indicator == 'number':
79 if total:
79 if total:
80 add = ('% ' + str(len(str(total))) +
80 add = ('% ' + str(len(str(total))) +
81 's/%s') % (pos, total)
81 's/%s') % (pos, total)
82 else:
82 else:
83 add = str(pos)
83 add = str(pos)
84 elif indicator.startswith('item') and item:
84 elif indicator.startswith('item') and item:
85 slice = 'end'
85 slice = 'end'
86 if '-' in indicator:
86 if '-' in indicator:
87 wid = int(indicator.split('-')[1])
87 wid = int(indicator.split('-')[1])
88 elif '+' in indicator:
88 elif '+' in indicator:
89 slice = 'beginning'
89 slice = 'beginning'
90 wid = int(indicator.split('+')[1])
90 wid = int(indicator.split('+')[1])
91 else:
91 else:
92 wid = 20
92 wid = 20
93 if slice == 'end':
93 if slice == 'end':
94 add = item[-wid:]
94 add = item[-wid:]
95 else:
95 else:
96 add = item[:wid]
96 add = item[:wid]
97 add += (wid - len(add)) * ' '
97 add += (wid - len(add)) * ' '
98 elif indicator == 'bar':
98 elif indicator == 'bar':
99 add = ''
99 add = ''
100 needprogress = True
100 needprogress = True
101 elif indicator == 'unit' and unit:
101 elif indicator == 'unit' and unit:
102 add = unit
102 add = unit
103 if not needprogress:
103 if not needprogress:
104 head = spacejoin(head, add)
104 head = spacejoin(head, add)
105 else:
105 else:
106 tail = spacejoin(add, tail)
106 tail = spacejoin(add, tail)
107 if needprogress:
107 if needprogress:
108 used = 0
108 used = 0
109 if head:
109 if head:
110 used += len(head) + 1
110 used += len(head) + 1
111 if tail:
111 if tail:
112 used += len(tail) + 1
112 used += len(tail) + 1
113 progwidth = termwidth - used - 3
113 progwidth = termwidth - used - 3
114 if total:
114 if total:
115 amt = pos * progwidth // total
115 amt = pos * progwidth // total
116 bar = '=' * (amt - 1)
116 bar = '=' * (amt - 1)
117 if amt > 0:
117 if amt > 0:
118 bar += '>'
118 bar += '>'
119 bar += ' ' * (progwidth - amt)
119 bar += ' ' * (progwidth - amt)
120 else:
120 else:
121 progwidth -= 3
121 progwidth -= 3
122 self.indetcount += 1
122 self.indetcount += 1
123 # mod the count by twice the width so we can make the
123 # mod the count by twice the width so we can make the
124 # cursor bounce between the right and left sides
124 # cursor bounce between the right and left sides
125 amt = self.indetcount % (2 * progwidth)
125 amt = self.indetcount % (2 * progwidth)
126 amt -= progwidth
126 amt -= progwidth
127 bar = (' ' * int(progwidth - abs(amt)) + '<=>' +
127 bar = (' ' * int(progwidth - abs(amt)) + '<=>' +
128 ' ' * int(abs(amt)))
128 ' ' * int(abs(amt)))
129 prog = ''.join(('[', bar , ']'))
129 prog = ''.join(('[', bar , ']'))
130 out = spacejoin(head, prog, tail)
130 out = spacejoin(head, prog, tail)
131 else:
131 else:
132 out = spacejoin(head, tail)
132 out = spacejoin(head, tail)
133 sys.stdout.write('\r' + out[:termwidth])
133 sys.stdout.write('\r' + out[:termwidth])
134 sys.stdout.flush()
134 sys.stdout.flush()
135
135
136 def clear(self):
136 def clear(self):
137 sys.stdout.write('\r%s\r' % (' ' * self.width()))
137 sys.stdout.write('\r%s\r' % (' ' * self.width()))
138
138
139 def complete(self):
139 def complete(self):
140 if self.ui.configbool('progress', 'clear-complete', default=True):
140 if self.ui.configbool('progress', 'clear-complete', default=True):
141 self.clear()
141 self.clear()
142 else:
142 else:
143 sys.stdout.write('\n')
143 sys.stdout.write('\n')
144 sys.stdout.flush()
144 sys.stdout.flush()
145
145
146 def width(self):
146 def width(self):
147 tw = util.termwidth()
147 tw = util.termwidth()
148 return min(int(self.ui.config('progress', 'width', default=tw)), tw)
148 return min(int(self.ui.config('progress', 'width', default=tw)), tw)
149
149
150 def progress(self, orig, topic, pos, item='', unit='', total=None):
150 def progress(self, orig, topic, pos, item='', unit='', total=None):
151 if pos is None:
151 if pos is None:
152 if self.topics and self.topics[-1] == topic and self.printed:
152 if self.topics and self.topics[-1] == topic and self.printed:
153 self.complete()
153 self.complete()
154 self.resetstate()
154 self.resetstate()
155 else:
155 else:
156 if topic not in self.topics:
156 if topic not in self.topics:
157 self.topics.append(topic)
157 self.topics.append(topic)
158 now = time.time()
158 now = time.time()
159 if (now - self.lastprint >= self.refresh
159 if (now - self.lastprint >= self.refresh
160 and topic == self.topics[-1]):
160 and topic == self.topics[-1]):
161 self.lastprint = now
161 self.lastprint = now
162 self.show(topic, pos, item, unit, total)
162 self.show(topic, pos, item, unit, total)
163 return orig(topic, pos, item=item, unit=unit, total=total)
163 return orig(topic, pos, item=item, unit=unit, total=total)
164
164
165 def write(self, orig, *args):
165 def write(self, orig, *args):
166 if self.printed:
166 if self.printed:
167 self.clear()
167 self.clear()
168 return orig(*args)
168 return orig(*args)
169
169
170 sharedprog = None
170 sharedprog = None
171
171
172 def uisetup(ui):
172 def uisetup(ui):
173 if ui.interactive() and not ui.debugflag:
173 if ui.interactive() and not ui.debugflag:
174 # we instantiate one globally shared progress bar to avoid
174 # we instantiate one globally shared progress bar to avoid
175 # competing progress bars when multiple UI objects get created
175 # competing progress bars when multiple UI objects get created
176 global sharedprog
176 global sharedprog
177 if not sharedprog:
177 if not sharedprog:
178 sharedprog = progbar(ui)
178 sharedprog = progbar(ui)
179 extensions.wrapfunction(ui, 'progress', sharedprog.progress)
179 extensions.wrapfunction(ui, 'progress', sharedprog.progress)
180 extensions.wrapfunction(ui, 'write', sharedprog.write)
180 extensions.wrapfunction(ui, 'write', sharedprog.write)
181
181
182 def reposetup(ui, repo):
182 def reposetup(ui, repo):
183 uisetup(repo.ui)
183 uisetup(repo.ui)
General Comments 0
You need to be logged in to leave comments. Login now