comparison mercurial/ui.py @ 40637:83dd8c63a0c6

ui: extract helpers to write message with type or label This provides a 'type' attribute to command-server clients, which seems more solid than relying on 'ui.<type>' labels. In future patches, type='progress' will be added to send raw progress information.
author Yuya Nishihara <yuya@tcha.org>
date Sun, 18 Jan 2015 17:55:28 +0900
parents 054d0fcba2c4
children 83e571ea06a9
comparison
equal deleted inserted replaced
40636:054d0fcba2c4 40637:83dd8c63a0c6
1037 raise error.StdioError(err) 1037 raise error.StdioError(err)
1038 finally: 1038 finally:
1039 self._blockedtimes['stdio_blocked'] += \ 1039 self._blockedtimes['stdio_blocked'] += \
1040 (util.timer() - starttime) * 1000 1040 (util.timer() - starttime) * 1000
1041 1041
1042 def _writemsg(self, dest, *args, **opts):
1043 _writemsgwith(self._write, dest, *args, **opts)
1044
1045 def _writemsgnobuf(self, dest, *args, **opts):
1046 _writemsgwith(self._writenobuf, dest, *args, **opts)
1047
1042 def flush(self): 1048 def flush(self):
1043 # opencode timeblockedsection because this is a critical path 1049 # opencode timeblockedsection because this is a critical path
1044 starttime = util.timer() 1050 starttime = util.timer()
1045 try: 1051 try:
1046 try: 1052 try:
1383 def prompt(self, msg, default="y"): 1389 def prompt(self, msg, default="y"):
1384 """Prompt user with msg, read response. 1390 """Prompt user with msg, read response.
1385 If ui is not interactive, the default is returned. 1391 If ui is not interactive, the default is returned.
1386 """ 1392 """
1387 if not self.interactive(): 1393 if not self.interactive():
1388 self._write(self._fmsgout, msg, ' ', label='ui.prompt') 1394 self._writemsg(self._fmsgout, msg, ' ', type='prompt')
1389 self._write(self._fmsgout, default or '', "\n", 1395 self._writemsg(self._fmsgout, default or '', "\n",
1390 label='ui.promptecho') 1396 type='promptecho')
1391 return default 1397 return default
1392 self._writenobuf(self._fmsgout, msg, label='ui.prompt') 1398 self._writemsgnobuf(self._fmsgout, msg, type='prompt')
1393 self.flush() 1399 self.flush()
1394 try: 1400 try:
1395 r = self._readline() 1401 r = self._readline()
1396 if not r: 1402 if not r:
1397 r = default 1403 r = default
1398 if self.configbool('ui', 'promptecho'): 1404 if self.configbool('ui', 'promptecho'):
1399 self._write(self._fmsgout, r, "\n", label='ui.promptecho') 1405 self._writemsg(self._fmsgout, r, "\n", type='promptecho')
1400 return r 1406 return r
1401 except EOFError: 1407 except EOFError:
1402 raise error.ResponseExpected() 1408 raise error.ResponseExpected()
1403 1409
1404 @staticmethod 1410 @staticmethod
1445 while True: 1451 while True:
1446 r = self.prompt(msg, resps[default]) 1452 r = self.prompt(msg, resps[default])
1447 if r.lower() in resps: 1453 if r.lower() in resps:
1448 return resps.index(r.lower()) 1454 return resps.index(r.lower())
1449 # TODO: shouldn't it be a warning? 1455 # TODO: shouldn't it be a warning?
1450 self._write(self._fmsgout, _("unrecognized response\n")) 1456 self._writemsg(self._fmsgout, _("unrecognized response\n"))
1451 1457
1452 def getpass(self, prompt=None, default=None): 1458 def getpass(self, prompt=None, default=None):
1453 if not self.interactive(): 1459 if not self.interactive():
1454 return default 1460 return default
1455 try: 1461 try:
1456 self._write(self._fmsgerr, prompt or _('password: '), 1462 self._writemsg(self._fmsgerr, prompt or _('password: '),
1457 label='ui.prompt') 1463 type='prompt')
1458 # disable getpass() only if explicitly specified. it's still valid 1464 # disable getpass() only if explicitly specified. it's still valid
1459 # to interact with tty even if fin is not a tty. 1465 # to interact with tty even if fin is not a tty.
1460 with self.timeblockedsection('stdio'): 1466 with self.timeblockedsection('stdio'):
1461 if self.configbool('ui', 'nontty'): 1467 if self.configbool('ui', 'nontty'):
1462 l = self._fin.readline() 1468 l = self._fin.readline()
1472 '''write status message to output (if ui.quiet is False) 1478 '''write status message to output (if ui.quiet is False)
1473 1479
1474 This adds an output label of "ui.status". 1480 This adds an output label of "ui.status".
1475 ''' 1481 '''
1476 if not self.quiet: 1482 if not self.quiet:
1477 opts[r'label'] = opts.get(r'label', '') + ' ui.status' 1483 self._writemsg(self._fmsgout, type='status', *msg, **opts)
1478 self._write(self._fmsgout, *msg, **opts)
1479 1484
1480 def warn(self, *msg, **opts): 1485 def warn(self, *msg, **opts):
1481 '''write warning message to output (stderr) 1486 '''write warning message to output (stderr)
1482 1487
1483 This adds an output label of "ui.warning". 1488 This adds an output label of "ui.warning".
1484 ''' 1489 '''
1485 opts[r'label'] = opts.get(r'label', '') + ' ui.warning' 1490 self._writemsg(self._fmsgerr, type='warning', *msg, **opts)
1486 self._write(self._fmsgerr, *msg, **opts)
1487 1491
1488 def error(self, *msg, **opts): 1492 def error(self, *msg, **opts):
1489 '''write error message to output (stderr) 1493 '''write error message to output (stderr)
1490 1494
1491 This adds an output label of "ui.error". 1495 This adds an output label of "ui.error".
1492 ''' 1496 '''
1493 opts[r'label'] = opts.get(r'label', '') + ' ui.error' 1497 self._writemsg(self._fmsgerr, type='error', *msg, **opts)
1494 self._write(self._fmsgerr, *msg, **opts)
1495 1498
1496 def note(self, *msg, **opts): 1499 def note(self, *msg, **opts):
1497 '''write note to output (if ui.verbose is True) 1500 '''write note to output (if ui.verbose is True)
1498 1501
1499 This adds an output label of "ui.note". 1502 This adds an output label of "ui.note".
1500 ''' 1503 '''
1501 if self.verbose: 1504 if self.verbose:
1502 opts[r'label'] = opts.get(r'label', '') + ' ui.note' 1505 self._writemsg(self._fmsgout, type='note', *msg, **opts)
1503 self._write(self._fmsgout, *msg, **opts)
1504 1506
1505 def debug(self, *msg, **opts): 1507 def debug(self, *msg, **opts):
1506 '''write debug message to output (if ui.debugflag is True) 1508 '''write debug message to output (if ui.debugflag is True)
1507 1509
1508 This adds an output label of "ui.debug". 1510 This adds an output label of "ui.debug".
1509 ''' 1511 '''
1510 if self.debugflag: 1512 if self.debugflag:
1511 opts[r'label'] = opts.get(r'label', '') + ' ui.debug' 1513 self._writemsg(self._fmsgout, type='debug', *msg, **opts)
1512 self._write(self._fmsgout, *msg, **opts)
1513 1514
1514 def edit(self, text, user, extra=None, editform=None, pending=None, 1515 def edit(self, text, user, extra=None, editform=None, pending=None,
1515 repopath=None, action=None): 1516 repopath=None, action=None):
1516 if action is None: 1517 if action is None:
1517 self.develwarn('action is None but will soon be a required ' 1518 self.develwarn('action is None but will soon be a required '
1976 if name == b'stdio': 1977 if name == b'stdio':
1977 return ui.fout, ui.ferr 1978 return ui.fout, ui.ferr
1978 if name == b'stderr': 1979 if name == b'stderr':
1979 return ui.ferr, ui.ferr 1980 return ui.ferr, ui.ferr
1980 raise error.Abort(b'invalid ui.message-output destination: %s' % name) 1981 raise error.Abort(b'invalid ui.message-output destination: %s' % name)
1982
1983 def _writemsgwith(write, dest, *args, **opts):
1984 """Write ui message with the given ui._write*() function
1985
1986 The specified message type is translated to 'ui.<type>' label if the dest
1987 isn't a structured channel, so that the message will be colorized.
1988 """
1989 # TODO: maybe change 'type' to a mandatory option
1990 if r'type' in opts and not getattr(dest, 'structured', False):
1991 opts[r'label'] = opts.get(r'label', '') + ' ui.%s' % opts.pop(r'type')
1992 write(dest, *args, **opts)