82
83
# end-of-file; possibly should raise an error here instead
86
def get_integer(self, prompt):
89
line = self.stdin.readline()
85
95
def get_non_echoed_password(self):
86
96
isatty = getattr(self.stdin, 'isatty', None)
87
97
if isatty is not None and isatty():
147
157
return NullProgressView()
159
def _make_output_stream_explicit(self, encoding, encoding_type):
160
if encoding_type == 'exact':
161
# force sys.stdout to be binary stream on win32;
162
# NB: this leaves the file set in that mode; may cause problems if
163
# one process tries to do binary and then text output
164
if sys.platform == 'win32':
165
fileno = getattr(self.stdout, 'fileno', None)
168
msvcrt.setmode(fileno(), os.O_BINARY)
169
return TextUIOutputStream(self, self.stdout)
171
encoded_stdout = codecs.getwriter(encoding)(self.stdout,
172
errors=encoding_type)
173
# For whatever reason codecs.getwriter() does not advertise its encoding
174
# it just returns the encoding of the wrapped file, which is completely
175
# bogus. So set the attribute, so we can find the correct encoding later.
176
encoded_stdout.encoding = encoding
177
return TextUIOutputStream(self, encoded_stdout)
149
179
def note(self, msg):
150
180
"""Write an already-formatted message, clearing the progress bar if necessary."""
151
181
self.clear_term()
218
248
self._term_file = term_file
219
249
# true when there's output on the screen we may need to clear
220
250
self._have_output = False
221
# XXX: We could listen for SIGWINCH and update the terminal width...
222
# https://launchpad.net/bugs/316357
223
self._width = osutils.terminal_width()
224
251
self._last_transport_msg = ''
225
252
self._spin_pos = 0
226
253
# time we last repainted the screen
231
258
self._total_byte_count = 0
232
259
self._bytes_since_update = 0
233
260
self._fraction = 0
261
# force the progress bar to be off, as at the moment it doesn't
262
# correspond reliably to overall command progress
263
self.enable_bar = False
235
265
def _show_line(self, s):
236
266
# sys.stderr.write("progress %r\n" % s)
237
if self._width is not None:
239
s = '%-*.*s' % (n, n, s)
267
width = osutils.terminal_width()
268
if width is not None:
269
# we need one extra space for terminals that wrap on last char
271
s = '%-*.*s' % (width, width, s)
240
272
self._term_file.write('\r' + s + '\r')
247
279
def _render_bar(self):
248
280
# return a string for the progress bar itself
249
if (self._last_task is None) or self._last_task.show_bar:
281
if self.enable_bar and (
282
(self._last_task is None) or self._last_task.show_bar):
250
283
# If there's no task object, we show space for the bar anyhow.
251
284
# That's because most invocations of bzr will end showing progress
252
285
# at some point, though perhaps only after doing some initial IO.
367
400
self._bytes_since_update = 0
368
401
self._last_transport_msg = msg
405
class TextUIOutputStream(object):
406
"""Decorates an output stream so that the terminal is cleared before writing.
408
This is supposed to ensure that the progress bar does not conflict with bulk
411
# XXX: this does not handle the case of writing part of a line, then doing
412
# progress bar output: the progress bar will probably write over it.
413
# one option is just to buffer that text until we have a full line;
414
# another is to save and restore it
416
# XXX: might need to wrap more methods
418
def __init__(self, ui_factory, wrapped_stream):
419
self.ui_factory = ui_factory
420
self.wrapped_stream = wrapped_stream
421
# this does no transcoding, but it must expose the underlying encoding
422
# because some callers need to know what can be written - see for
423
# example unescape_for_display.
424
self.encoding = getattr(wrapped_stream, 'encoding', None)
427
self.ui_factory.clear_term()
428
self.wrapped_stream.flush()
430
def write(self, to_write):
431
self.ui_factory.clear_term()
432
self.wrapped_stream.write(to_write)
434
def writelines(self, lines):
435
self.ui_factory.clear_term()
436
self.wrapped_stream.writelines(lines)