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