##// END OF EJS Templates
progress: use 'encoding.colwidth' to get column width of items correctly...
FUJIWARA Katsunori -
r21863:f9c91c63 default
parent child Browse files
Show More
@@ -1,305 +1,305
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 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 """show progress bars for some actions
9 9
10 10 This extension uses the progress information logged by hg commands
11 11 to draw progress bars that are as informative as possible. Some progress
12 12 bars only offer indeterminate information, while others have a definite
13 13 end point.
14 14
15 15 The following settings are available::
16 16
17 17 [progress]
18 18 delay = 3 # number of seconds (float) before showing the progress bar
19 19 changedelay = 1 # changedelay: minimum delay before showing a new topic.
20 20 # If set to less than 3 * refresh, that value will
21 21 # be used instead.
22 22 refresh = 0.1 # time in seconds between refreshes of the progress bar
23 23 format = topic bar number estimate # format of the progress bar
24 24 width = <none> # if set, the maximum width of the progress information
25 25 # (that is, min(width, term width) will be used)
26 26 clear-complete = True # clear the progress bar after it's done
27 27 disable = False # if true, don't show a progress bar
28 28 assume-tty = False # if true, ALWAYS show a progress bar, unless
29 29 # disable is given
30 30
31 31 Valid entries for the format field are topic, bar, number, unit,
32 32 estimate, speed, and item. item defaults to the last 20 characters of
33 33 the item, but this can be changed by adding either ``-<num>`` which
34 34 would take the last num characters, or ``+<num>`` for the first num
35 35 characters.
36 36 """
37 37
38 38 import sys
39 39 import time
40 40
41 41 from mercurial.i18n import _
42 42 testedwith = 'internal'
43 43
44 44 from mercurial import encoding
45 45
46 46 def spacejoin(*args):
47 47 return ' '.join(s for s in args if s)
48 48
49 49 def shouldprint(ui):
50 50 return not ui.plain() and (ui._isatty(sys.stderr) or
51 51 ui.configbool('progress', 'assume-tty'))
52 52
53 53 def fmtremaining(seconds):
54 54 if seconds < 60:
55 55 # i18n: format XX seconds as "XXs"
56 56 return _("%02ds") % (seconds)
57 57 minutes = seconds // 60
58 58 if minutes < 60:
59 59 seconds -= minutes * 60
60 60 # i18n: format X minutes and YY seconds as "XmYYs"
61 61 return _("%dm%02ds") % (minutes, seconds)
62 62 # we're going to ignore seconds in this case
63 63 minutes += 1
64 64 hours = minutes // 60
65 65 minutes -= hours * 60
66 66 if hours < 30:
67 67 # i18n: format X hours and YY minutes as "XhYYm"
68 68 return _("%dh%02dm") % (hours, minutes)
69 69 # we're going to ignore minutes in this case
70 70 hours += 1
71 71 days = hours // 24
72 72 hours -= days * 24
73 73 if days < 15:
74 74 # i18n: format X days and YY hours as "XdYYh"
75 75 return _("%dd%02dh") % (days, hours)
76 76 # we're going to ignore hours in this case
77 77 days += 1
78 78 weeks = days // 7
79 79 days -= weeks * 7
80 80 if weeks < 55:
81 81 # i18n: format X weeks and YY days as "XwYYd"
82 82 return _("%dw%02dd") % (weeks, days)
83 83 # we're going to ignore days and treat a year as 52 weeks
84 84 weeks += 1
85 85 years = weeks // 52
86 86 weeks -= years * 52
87 87 # i18n: format X years and YY weeks as "XyYYw"
88 88 return _("%dy%02dw") % (years, weeks)
89 89
90 90 class progbar(object):
91 91 def __init__(self, ui):
92 92 self.ui = ui
93 93 self.resetstate()
94 94
95 95 def resetstate(self):
96 96 self.topics = []
97 97 self.topicstates = {}
98 98 self.starttimes = {}
99 99 self.startvals = {}
100 100 self.printed = False
101 101 self.lastprint = time.time() + float(self.ui.config(
102 102 'progress', 'delay', default=3))
103 103 self.lasttopic = None
104 104 self.indetcount = 0
105 105 self.refresh = float(self.ui.config(
106 106 'progress', 'refresh', default=0.1))
107 107 self.changedelay = max(3 * self.refresh,
108 108 float(self.ui.config(
109 109 'progress', 'changedelay', default=1)))
110 110 self.order = self.ui.configlist(
111 111 'progress', 'format',
112 112 default=['topic', 'bar', 'number', 'estimate'])
113 113
114 114 def show(self, now, topic, pos, item, unit, total):
115 115 if not shouldprint(self.ui):
116 116 return
117 117 termwidth = self.width()
118 118 self.printed = True
119 119 head = ''
120 120 needprogress = False
121 121 tail = ''
122 122 for indicator in self.order:
123 123 add = ''
124 124 if indicator == 'topic':
125 125 add = topic
126 126 elif indicator == 'number':
127 127 if total:
128 128 add = ('% ' + str(len(str(total))) +
129 129 's/%s') % (pos, total)
130 130 else:
131 131 add = str(pos)
132 132 elif indicator.startswith('item') and item:
133 133 slice = 'end'
134 134 if '-' in indicator:
135 135 wid = int(indicator.split('-')[1])
136 136 elif '+' in indicator:
137 137 slice = 'beginning'
138 138 wid = int(indicator.split('+')[1])
139 139 else:
140 140 wid = 20
141 141 if slice == 'end':
142 142 add = encoding.trim(item, wid, leftside=True)
143 143 else:
144 144 add = encoding.trim(item, wid)
145 add += (wid - len(add)) * ' '
145 add += (wid - encoding.colwidth(add)) * ' '
146 146 elif indicator == 'bar':
147 147 add = ''
148 148 needprogress = True
149 149 elif indicator == 'unit' and unit:
150 150 add = unit
151 151 elif indicator == 'estimate':
152 152 add = self.estimate(topic, pos, total, now)
153 153 elif indicator == 'speed':
154 154 add = self.speed(topic, pos, unit, now)
155 155 if not needprogress:
156 156 head = spacejoin(head, add)
157 157 else:
158 158 tail = spacejoin(tail, add)
159 159 if needprogress:
160 160 used = 0
161 161 if head:
162 162 used += encoding.colwidth(head) + 1
163 163 if tail:
164 164 used += encoding.colwidth(tail) + 1
165 165 progwidth = termwidth - used - 3
166 166 if total and pos <= total:
167 167 amt = pos * progwidth // total
168 168 bar = '=' * (amt - 1)
169 169 if amt > 0:
170 170 bar += '>'
171 171 bar += ' ' * (progwidth - amt)
172 172 else:
173 173 progwidth -= 3
174 174 self.indetcount += 1
175 175 # mod the count by twice the width so we can make the
176 176 # cursor bounce between the right and left sides
177 177 amt = self.indetcount % (2 * progwidth)
178 178 amt -= progwidth
179 179 bar = (' ' * int(progwidth - abs(amt)) + '<=>' +
180 180 ' ' * int(abs(amt)))
181 181 prog = ''.join(('[', bar , ']'))
182 182 out = spacejoin(head, prog, tail)
183 183 else:
184 184 out = spacejoin(head, tail)
185 185 sys.stderr.write('\r' + encoding.trim(out, termwidth))
186 186 self.lasttopic = topic
187 187 sys.stderr.flush()
188 188
189 189 def clear(self):
190 190 if not shouldprint(self.ui):
191 191 return
192 192 sys.stderr.write('\r%s\r' % (' ' * self.width()))
193 193
194 194 def complete(self):
195 195 if not shouldprint(self.ui):
196 196 return
197 197 if self.ui.configbool('progress', 'clear-complete', default=True):
198 198 self.clear()
199 199 else:
200 200 sys.stderr.write('\n')
201 201 sys.stderr.flush()
202 202
203 203 def width(self):
204 204 tw = self.ui.termwidth()
205 205 return min(int(self.ui.config('progress', 'width', default=tw)), tw)
206 206
207 207 def estimate(self, topic, pos, total, now):
208 208 if total is None:
209 209 return ''
210 210 initialpos = self.startvals[topic]
211 211 target = total - initialpos
212 212 delta = pos - initialpos
213 213 if delta > 0:
214 214 elapsed = now - self.starttimes[topic]
215 215 if elapsed > float(
216 216 self.ui.config('progress', 'estimate', default=2)):
217 217 seconds = (elapsed * (target - delta)) // delta + 1
218 218 return fmtremaining(seconds)
219 219 return ''
220 220
221 221 def speed(self, topic, pos, unit, now):
222 222 initialpos = self.startvals[topic]
223 223 delta = pos - initialpos
224 224 elapsed = now - self.starttimes[topic]
225 225 if elapsed > float(
226 226 self.ui.config('progress', 'estimate', default=2)):
227 227 return _('%d %s/sec') % (delta / elapsed, unit)
228 228 return ''
229 229
230 230 def progress(self, topic, pos, item='', unit='', total=None):
231 231 now = time.time()
232 232 if pos is None:
233 233 self.starttimes.pop(topic, None)
234 234 self.startvals.pop(topic, None)
235 235 self.topicstates.pop(topic, None)
236 236 # reset the progress bar if this is the outermost topic
237 237 if self.topics and self.topics[0] == topic and self.printed:
238 238 self.complete()
239 239 self.resetstate()
240 240 # truncate the list of topics assuming all topics within
241 241 # this one are also closed
242 242 if topic in self.topics:
243 243 self.topics = self.topics[:self.topics.index(topic)]
244 244 # reset the last topic to the one we just unwound to,
245 245 # so that higher-level topics will be stickier than
246 246 # lower-level topics
247 247 if self.topics:
248 248 self.lasttopic = self.topics[-1]
249 249 else:
250 250 self.lasttopic = None
251 251 else:
252 252 if topic not in self.topics:
253 253 self.starttimes[topic] = now
254 254 self.startvals[topic] = pos
255 255 self.topics.append(topic)
256 256 self.topicstates[topic] = pos, item, unit, total
257 257 if now - self.lastprint >= self.refresh and self.topics:
258 258 if (self.lasttopic is None # first time we printed
259 259 # not a topic change
260 260 or topic == self.lasttopic
261 261 # it's been long enough we should print anyway
262 262 or now - self.lastprint >= self.changedelay):
263 263 self.lastprint = now
264 264 self.show(now, topic, *self.topicstates[topic])
265 265
266 266 _singleton = None
267 267
268 268 def uisetup(ui):
269 269 global _singleton
270 270 class progressui(ui.__class__):
271 271 _progbar = None
272 272
273 273 def _quiet(self):
274 274 return self.debugflag or self.quiet
275 275
276 276 def progress(self, *args, **opts):
277 277 if not self._quiet():
278 278 self._progbar.progress(*args, **opts)
279 279 return super(progressui, self).progress(*args, **opts)
280 280
281 281 def write(self, *args, **opts):
282 282 if not self._quiet() and self._progbar.printed:
283 283 self._progbar.clear()
284 284 return super(progressui, self).write(*args, **opts)
285 285
286 286 def write_err(self, *args, **opts):
287 287 if not self._quiet() and self._progbar.printed:
288 288 self._progbar.clear()
289 289 return super(progressui, self).write_err(*args, **opts)
290 290
291 291 # Apps that derive a class from ui.ui() can use
292 292 # setconfig('progress', 'disable', 'True') to disable this extension
293 293 if ui.configbool('progress', 'disable'):
294 294 return
295 295 if shouldprint(ui) and not ui.debugflag and not ui.quiet:
296 296 ui.__class__ = progressui
297 297 # we instantiate one globally shared progress bar to avoid
298 298 # competing progress bars when multiple UI objects get created
299 299 if not progressui._progbar:
300 300 if _singleton is None:
301 301 _singleton = progbar(ui)
302 302 progressui._progbar = _singleton
303 303
304 304 def reposetup(ui, repo):
305 305 uisetup(repo.ui)
@@ -1,336 +1,339
1 1
2 2 $ cat > loop.py <<EOF
3 3 > from mercurial import cmdutil, commands
4 4 > import time
5 5 >
6 6 > cmdtable = {}
7 7 > command = cmdutil.command(cmdtable)
8 8 >
9 9 > class incrementingtime(object):
10 10 > def __init__(self):
11 11 > self._time = 0.0
12 12 > def __call__(self):
13 13 > self._time += 0.25
14 14 > return self._time
15 15 > time.time = incrementingtime()
16 16 >
17 17 > @command('loop',
18 18 > [('', 'total', '', 'override for total'),
19 19 > ('', 'nested', False, 'show nested results'),
20 20 > ('', 'parallel', False, 'show parallel sets of results')],
21 21 > 'hg loop LOOPS',
22 22 > norepo=True)
23 23 > def loop(ui, loops, **opts):
24 24 > loops = int(loops)
25 25 > total = None
26 26 > if loops >= 0:
27 27 > total = loops
28 28 > if opts.get('total', None):
29 29 > total = int(opts.get('total'))
30 30 > nested = False
31 31 > if opts.get('nested', None):
32 32 > nested = True
33 33 > loops = abs(loops)
34 34 >
35 35 > for i in range(loops):
36 36 > ui.progress(topiclabel, i, getloopitem(i), 'loopnum', total)
37 37 > if opts.get('parallel'):
38 38 > ui.progress('other', i, 'other.%d' % i, 'othernum', total)
39 39 > if nested:
40 40 > nested_steps = 2
41 41 > if i and i % 4 == 0:
42 42 > nested_steps = 5
43 43 > for j in range(nested_steps):
44 44 > ui.progress(
45 45 > 'nested', j, 'nested.%d' % j, 'nestnum', nested_steps)
46 46 > ui.progress(
47 47 > 'nested', None, 'nested.done', 'nestnum', nested_steps)
48 48 > ui.progress(topiclabel, None, 'loop.done', 'loopnum', total)
49 49 >
50 50 > topiclabel = 'loop'
51 51 > def getloopitem(i):
52 52 > return 'loop.%d' % i
53 53 >
54 54 > EOF
55 55
56 56 $ cp $HGRCPATH $HGRCPATH.orig
57 57 $ echo "[extensions]" >> $HGRCPATH
58 58 $ echo "progress=" >> $HGRCPATH
59 59 $ echo "loop=`pwd`/loop.py" >> $HGRCPATH
60 60 $ echo "[progress]" >> $HGRCPATH
61 61 $ echo "format = topic bar number" >> $HGRCPATH
62 62 $ echo "assume-tty=1" >> $HGRCPATH
63 63 $ echo "width=60" >> $HGRCPATH
64 64
65 65 test default params, display nothing because of delay
66 66
67 67 $ hg -y loop 3
68 68 $ echo "delay=0" >> $HGRCPATH
69 69 $ echo "refresh=0" >> $HGRCPATH
70 70
71 71 test with delay=0, refresh=0
72 72
73 73 $ hg -y loop 3
74 74 \r (no-eol) (esc)
75 75 loop [ ] 0/3\r (no-eol) (esc)
76 76 loop [===============> ] 1/3\r (no-eol) (esc)
77 77 loop [===============================> ] 2/3\r (no-eol) (esc)
78 78 \r (no-eol) (esc)
79 79
80 80
81 81 test nested short-lived topics (which shouldn't display with nestdelay):
82 82
83 83 $ hg -y loop 3 --nested
84 84 \r (no-eol) (esc)
85 85 loop [ ] 0/3\r (no-eol) (esc)
86 86 loop [===============> ] 1/3\r (no-eol) (esc)
87 87 loop [===============================> ] 2/3\r (no-eol) (esc)
88 88 \r (no-eol) (esc)
89 89
90 90 Test nested long-lived topic which has the same name as a short-lived
91 91 peer. We shouldn't get stuck showing the short-lived inner steps, and
92 92 should go back to skipping the inner steps when the slow nested step
93 93 finishes.
94 94
95 95 $ hg -y loop 7 --nested
96 96 \r (no-eol) (esc)
97 97 loop [ ] 0/7\r (no-eol) (esc)
98 98 loop [=====> ] 1/7\r (no-eol) (esc)
99 99 loop [============> ] 2/7\r (no-eol) (esc)
100 100 loop [===================> ] 3/7\r (no-eol) (esc)
101 101 loop [==========================> ] 4/7\r (no-eol) (esc)
102 102 nested [==========================> ] 3/5\r (no-eol) (esc)
103 103 nested [===================================> ] 4/5\r (no-eol) (esc)
104 104 loop [=================================> ] 5/7\r (no-eol) (esc)
105 105 loop [========================================> ] 6/7\r (no-eol) (esc)
106 106 \r (no-eol) (esc)
107 107
108 108
109 109 $ hg --config progress.changedelay=0 -y loop 3 --nested
110 110 \r (no-eol) (esc)
111 111 loop [ ] 0/3\r (no-eol) (esc)
112 112 nested [ ] 0/2\r (no-eol) (esc)
113 113 nested [======================> ] 1/2\r (no-eol) (esc)
114 114 loop [===============> ] 1/3\r (no-eol) (esc)
115 115 nested [ ] 0/2\r (no-eol) (esc)
116 116 nested [======================> ] 1/2\r (no-eol) (esc)
117 117 loop [===============================> ] 2/3\r (no-eol) (esc)
118 118 nested [ ] 0/2\r (no-eol) (esc)
119 119 nested [======================> ] 1/2\r (no-eol) (esc)
120 120 \r (no-eol) (esc)
121 121
122 122
123 123 test two topics being printed in parallel (as when we're doing a local
124 124 --pull clone, where you get the unbundle and bundle progress at the
125 125 same time):
126 126 $ hg loop 3 --parallel
127 127 \r (no-eol) (esc)
128 128 loop [ ] 0/3\r (no-eol) (esc)
129 129 loop [===============> ] 1/3\r (no-eol) (esc)
130 130 loop [===============================> ] 2/3\r (no-eol) (esc)
131 131 \r (no-eol) (esc)
132 132 test refresh is taken in account
133 133
134 134 $ hg -y --config progress.refresh=100 loop 3
135 135
136 136 test format options 1
137 137
138 138 $ hg -y --config 'progress.format=number topic item+2' loop 2
139 139 \r (no-eol) (esc)
140 140 0/2 loop lo\r (no-eol) (esc)
141 141 1/2 loop lo\r (no-eol) (esc)
142 142 \r (no-eol) (esc)
143 143
144 144 test format options 2
145 145
146 146 $ hg -y --config 'progress.format=number item-3 bar' loop 2
147 147 \r (no-eol) (esc)
148 148 0/2 p.0 [ ]\r (no-eol) (esc)
149 149 1/2 p.1 [=======================> ]\r (no-eol) (esc)
150 150 \r (no-eol) (esc)
151 151
152 152 test format options and indeterminate progress
153 153
154 154 $ hg -y --config 'progress.format=number item bar' loop -- -2
155 155 \r (no-eol) (esc)
156 156 0 loop.0 [ <=> ]\r (no-eol) (esc)
157 157 1 loop.1 [ <=> ]\r (no-eol) (esc)
158 158 \r (no-eol) (esc)
159 159
160 160 make sure things don't fall over if count > total
161 161
162 162 $ hg -y loop --total 4 6
163 163 \r (no-eol) (esc)
164 164 loop [ ] 0/4\r (no-eol) (esc)
165 165 loop [===========> ] 1/4\r (no-eol) (esc)
166 166 loop [=======================> ] 2/4\r (no-eol) (esc)
167 167 loop [===================================> ] 3/4\r (no-eol) (esc)
168 168 loop [===============================================>] 4/4\r (no-eol) (esc)
169 169 loop [ <=> ] 5/4\r (no-eol) (esc)
170 170 \r (no-eol) (esc)
171 171
172 172 test immediate progress completion
173 173
174 174 $ hg -y loop 0
175 175
176 176 test delay time estimates
177 177
178 178 $ cat > mocktime.py <<EOF
179 179 > import os
180 180 > import time
181 181 >
182 182 > class mocktime(object):
183 183 > def __init__(self, increment):
184 184 > self.time = 0
185 185 > self.increment = increment
186 186 > def __call__(self):
187 187 > self.time += self.increment
188 188 > return self.time
189 189 >
190 190 > def uisetup(ui):
191 191 > time.time = mocktime(int(os.environ.get('MOCKTIME', '11')))
192 192 > EOF
193 193
194 194 $ cp $HGRCPATH.orig $HGRCPATH
195 195 $ echo "[extensions]" >> $HGRCPATH
196 196 $ echo "mocktime=`pwd`/mocktime.py" >> $HGRCPATH
197 197 $ echo "progress=" >> $HGRCPATH
198 198 $ echo "loop=`pwd`/loop.py" >> $HGRCPATH
199 199 $ echo "[progress]" >> $HGRCPATH
200 200 $ echo "assume-tty=1" >> $HGRCPATH
201 201 $ echo "delay=25" >> $HGRCPATH
202 202 $ echo "width=60" >> $HGRCPATH
203 203
204 204 $ hg -y loop 8
205 205 \r (no-eol) (esc)
206 206 loop [=========> ] 2/8 1m07s\r (no-eol) (esc)
207 207 loop [===============> ] 3/8 56s\r (no-eol) (esc)
208 208 loop [=====================> ] 4/8 45s\r (no-eol) (esc)
209 209 loop [==========================> ] 5/8 34s\r (no-eol) (esc)
210 210 loop [================================> ] 6/8 23s\r (no-eol) (esc)
211 211 loop [=====================================> ] 7/8 12s\r (no-eol) (esc)
212 212 \r (no-eol) (esc)
213 213
214 214 $ MOCKTIME=10000 hg -y loop 4
215 215 \r (no-eol) (esc)
216 216 loop [ ] 0/4\r (no-eol) (esc)
217 217 loop [=========> ] 1/4 8h21m\r (no-eol) (esc)
218 218 loop [====================> ] 2/4 5h34m\r (no-eol) (esc)
219 219 loop [==============================> ] 3/4 2h47m\r (no-eol) (esc)
220 220 \r (no-eol) (esc)
221 221
222 222 $ MOCKTIME=1000000 hg -y loop 4
223 223 \r (no-eol) (esc)
224 224 loop [ ] 0/4\r (no-eol) (esc)
225 225 loop [=========> ] 1/4 5w00d\r (no-eol) (esc)
226 226 loop [====================> ] 2/4 3w03d\r (no-eol) (esc)
227 227 loop [=============================> ] 3/4 11d14h\r (no-eol) (esc)
228 228 \r (no-eol) (esc)
229 229
230 230
231 231 $ MOCKTIME=14000000 hg -y loop 4
232 232 \r (no-eol) (esc)
233 233 loop [ ] 0/4\r (no-eol) (esc)
234 234 loop [=========> ] 1/4 1y18w\r (no-eol) (esc)
235 235 loop [===================> ] 2/4 46w03d\r (no-eol) (esc)
236 236 loop [=============================> ] 3/4 23w02d\r (no-eol) (esc)
237 237 \r (no-eol) (esc)
238 238
239 239 Time estimates should not fail when there's no end point:
240 240 $ hg -y loop -- -4
241 241 \r (no-eol) (esc)
242 242 loop [ <=> ] 2\r (no-eol) (esc)
243 243 loop [ <=> ] 3\r (no-eol) (esc)
244 244 \r (no-eol) (esc)
245 245
246 246 test line trimming by '[progress] width', when progress topic contains
247 247 multi-byte characters, of which length of byte sequence and columns in
248 248 display are different from each other.
249 249
250 250 $ cp $HGRCPATH.orig $HGRCPATH
251 251 $ cat >> $HGRCPATH <<EOF
252 252 > [extensions]
253 253 > progress=
254 254 > loop=`pwd`/loop.py
255 255 > [progress]
256 256 > assume-tty = 1
257 257 > delay = 0
258 258 > refresh = 0
259 259 > EOF
260 260
261 261 $ rm -f loop.pyc
262 262 $ cat >> loop.py <<EOF
263 263 > # use non-ascii characters as topic label of progress
264 264 > # 2 x 4 = 8 columns, but 3 x 4 = 12 bytes
265 265 > topiclabel = u'\u3042\u3044\u3046\u3048'.encode('utf-8')
266 266 > EOF
267 267
268 268 $ cat >> $HGRCPATH <<EOF
269 269 > [progress]
270 270 > format = topic number
271 271 > width= 12
272 272 > EOF
273 273
274 274 $ hg --encoding utf-8 -y loop --total 3 3
275 275 \r (no-eol) (esc)
276 276 \xe3\x81\x82\xe3\x81\x84\xe3\x81\x86\xe3\x81\x88 0/3\r (no-eol) (esc)
277 277 \xe3\x81\x82\xe3\x81\x84\xe3\x81\x86\xe3\x81\x88 1/3\r (no-eol) (esc)
278 278 \xe3\x81\x82\xe3\x81\x84\xe3\x81\x86\xe3\x81\x88 2/3\r (no-eol) (esc)
279 279 \r (no-eol) (esc)
280 280
281 281 test calculation of bar width, when progress topic contains multi-byte
282 282 characters, of which length of byte sequence and columns in display
283 283 are different from each other.
284 284
285 285 $ cat >> $HGRCPATH <<EOF
286 286 > [progress]
287 287 > format = topic bar
288 288 > width= 21
289 289 > # progwidth should be 9 (= 21 - (8+1) - 3)
290 290 > EOF
291 291
292 292 $ hg --encoding utf-8 -y loop --total 3 3
293 293 \r (no-eol) (esc)
294 294 \xe3\x81\x82\xe3\x81\x84\xe3\x81\x86\xe3\x81\x88 [ ]\r (no-eol) (esc)
295 295 \xe3\x81\x82\xe3\x81\x84\xe3\x81\x86\xe3\x81\x88 [==> ]\r (no-eol) (esc)
296 296 \xe3\x81\x82\xe3\x81\x84\xe3\x81\x86\xe3\x81\x88 [=====> ]\r (no-eol) (esc)
297 297 \r (no-eol) (esc)
298 298
299 299 test triming progress items, when they contain multi-byte characters,
300 300 of which length of byte sequence and columns in display are different
301 301 from each other.
302 302
303 303 $ rm -f loop.pyc
304 304 $ cat >> loop.py <<EOF
305 305 > # use non-ascii characters as loop items of progress
306 306 > loopitems = [
307 > u'\u3042\u3044'.encode('utf-8'), # 2 x 2 = 4 columns
307 308 > u'\u3042\u3044\u3046'.encode('utf-8'), # 2 x 3 = 6 columns
308 309 > u'\u3042\u3044\u3046\u3048'.encode('utf-8'), # 2 x 4 = 8 columns
309 310 > ]
310 311 > def getloopitem(i):
311 312 > return loopitems[i % len(loopitems)]
312 313 > EOF
313 314
314 315 $ cat >> $HGRCPATH <<EOF
315 316 > [progress]
316 317 > # trim at tail side
317 318 > format = item+6
318 319 > EOF
319 320
320 $ hg --encoding utf-8 -y loop --total 2 2
321 $ hg --encoding utf-8 -y loop --total 3 3
321 322 \r (no-eol) (esc)
323 \xe3\x81\x82\xe3\x81\x84 \r (no-eol) (esc)
322 324 \xe3\x81\x82\xe3\x81\x84\xe3\x81\x86\r (no-eol) (esc)
323 325 \xe3\x81\x82\xe3\x81\x84\xe3\x81\x86\r (no-eol) (esc)
324 326 \r (no-eol) (esc)
325 327
326 328 $ cat >> $HGRCPATH <<EOF
327 329 > [progress]
328 330 > # trim at left side
329 331 > format = item-6
330 332 > EOF
331 333
332 $ hg --encoding utf-8 -y loop --total 2 2
334 $ hg --encoding utf-8 -y loop --total 3 3
333 335 \r (no-eol) (esc)
336 \xe3\x81\x82\xe3\x81\x84 \r (no-eol) (esc)
334 337 \xe3\x81\x82\xe3\x81\x84\xe3\x81\x86\r (no-eol) (esc)
335 338 \xe3\x81\x84\xe3\x81\x86\xe3\x81\x88\r (no-eol) (esc)
336 339 \r (no-eol) (esc)
General Comments 0
You need to be logged in to leave comments. Login now