/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/ui/text.py

  • Committer: Andrew Bennetts
  • Date: 2009-12-18 08:22:42 UTC
  • mfrom: (4906 +trunk)
  • mto: This revision was merged to the branch mainline in revision 4909.
  • Revision ID: andrew.bennetts@canonical.com-20091218082242-f7wy9tlk0yxvkkju
MergeĀ lp:bzr.

Show diffs side-by-side

added added

removed removed

Lines of Context:
18
18
"""Text UI, write output to the console.
19
19
"""
20
20
 
 
21
import codecs
21
22
import getpass
22
23
import os
23
24
import sys
82
83
                # end-of-file; possibly should raise an error here instead
83
84
                return None
84
85
 
 
86
    def get_integer(self, prompt):
 
87
        while True:
 
88
            self.prompt(prompt)
 
89
            line = self.stdin.readline()
 
90
            try:
 
91
                return int(line)
 
92
            except ValueError:
 
93
                pass
 
94
 
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():
146
156
        else:
147
157
            return NullProgressView()
148
158
 
 
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)
 
166
                if fileno:
 
167
                    import msvcrt
 
168
                    msvcrt.setmode(fileno(), os.O_BINARY)
 
169
            return TextUIOutputStream(self, self.stdout)
 
170
        else:
 
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)
 
178
 
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
234
264
 
235
265
    def _show_line(self, s):
236
266
        # sys.stderr.write("progress %r\n" % s)
237
 
        if self._width is not None:
238
 
            n = self._width - 1
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
 
270
            width = width - 1
 
271
            s = '%-*.*s' % (width, width, s)
240
272
        self._term_file.write('\r' + s + '\r')
241
273
 
242
274
    def clear(self):
246
278
 
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
369
402
            self._repaint()
 
403
 
 
404
 
 
405
class TextUIOutputStream(object):
 
406
    """Decorates an output stream so that the terminal is cleared before writing.
 
407
 
 
408
    This is supposed to ensure that the progress bar does not conflict with bulk
 
409
    text output.
 
410
    """
 
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
 
415
 
 
416
    # XXX: might need to wrap more methods
 
417
 
 
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)
 
425
 
 
426
    def flush(self):
 
427
        self.ui_factory.clear_term()
 
428
        self.wrapped_stream.flush()
 
429
 
 
430
    def write(self, to_write):
 
431
        self.ui_factory.clear_term()
 
432
        self.wrapped_stream.write(to_write)
 
433
 
 
434
    def writelines(self, lines):
 
435
        self.ui_factory.clear_term()
 
436
        self.wrapped_stream.writelines(lines)