mercurial/ui.py
changeset 45942 89a2afe31e82
parent 45929 87e7dd8e7734
child 46030 2cf61e66c6d0
equal deleted inserted replaced
45941:346af7687c6f 45942:89a2afe31e82
   923         for section in cfg.sections():
   923         for section in cfg.sections():
   924             for name, value in self.configitems(section, untrusted):
   924             for name, value in self.configitems(section, untrusted):
   925                 yield section, name, value
   925                 yield section, name, value
   926 
   926 
   927     def plain(self, feature=None):
   927     def plain(self, feature=None):
   928         '''is plain mode active?
   928         """is plain mode active?
   929 
   929 
   930         Plain mode means that all configuration variables which affect
   930         Plain mode means that all configuration variables which affect
   931         the behavior and output of Mercurial should be
   931         the behavior and output of Mercurial should be
   932         ignored. Additionally, the output should be stable,
   932         ignored. Additionally, the output should be stable,
   933         reproducible and suitable for use in scripts or applications.
   933         reproducible and suitable for use in scripts or applications.
   937 
   937 
   938         The return value can either be
   938         The return value can either be
   939         - False if HGPLAIN is not set, or feature is in HGPLAINEXCEPT
   939         - False if HGPLAIN is not set, or feature is in HGPLAINEXCEPT
   940         - False if feature is disabled by default and not included in HGPLAIN
   940         - False if feature is disabled by default and not included in HGPLAIN
   941         - True otherwise
   941         - True otherwise
   942         '''
   942         """
   943         if (
   943         if (
   944             b'HGPLAIN' not in encoding.environ
   944             b'HGPLAIN' not in encoding.environ
   945             and b'HGPLAINEXCEPT' not in encoding.environ
   945             and b'HGPLAINEXCEPT' not in encoding.environ
   946         ):
   946         ):
   947             return False
   947             return False
  1110         '''check if write calls with labels are batchable'''
  1110         '''check if write calls with labels are batchable'''
  1111         # Windows color printing is special, see ``write``.
  1111         # Windows color printing is special, see ``write``.
  1112         return self._colormode != b'win32'
  1112         return self._colormode != b'win32'
  1113 
  1113 
  1114     def write(self, *args, **opts):
  1114     def write(self, *args, **opts):
  1115         '''write args to output
  1115         """write args to output
  1116 
  1116 
  1117         By default, this method simply writes to the buffer or stdout.
  1117         By default, this method simply writes to the buffer or stdout.
  1118         Color mode can be set on the UI class to have the output decorated
  1118         Color mode can be set on the UI class to have the output decorated
  1119         with color modifier before being written to stdout.
  1119         with color modifier before being written to stdout.
  1120 
  1120 
  1131         in a pipe.
  1131         in a pipe.
  1132 
  1132 
  1133         When labeling output for a specific command, a label of
  1133         When labeling output for a specific command, a label of
  1134         "cmdname.type" is recommended. For example, status issues
  1134         "cmdname.type" is recommended. For example, status issues
  1135         a label of "status.modified" for modified files.
  1135         a label of "status.modified" for modified files.
  1136         '''
  1136         """
  1137         dest = self._fout
  1137         dest = self._fout
  1138 
  1138 
  1139         # inlined _write() for speed
  1139         # inlined _write() for speed
  1140         if self._buffers:
  1140         if self._buffers:
  1141             label = opts.get('label', b'')
  1141             label = opts.get('label', b'')
  1451     @property
  1451     @property
  1452     def _exithandlers(self):
  1452     def _exithandlers(self):
  1453         return _reqexithandlers
  1453         return _reqexithandlers
  1454 
  1454 
  1455     def atexit(self, func, *args, **kwargs):
  1455     def atexit(self, func, *args, **kwargs):
  1456         '''register a function to run after dispatching a request
  1456         """register a function to run after dispatching a request
  1457 
  1457 
  1458         Handlers do not stay registered across request boundaries.'''
  1458         Handlers do not stay registered across request boundaries."""
  1459         self._exithandlers.append((func, args, kwargs))
  1459         self._exithandlers.append((func, args, kwargs))
  1460         return func
  1460         return func
  1461 
  1461 
  1462     def interface(self, feature):
  1462     def interface(self, feature):
  1463         """what interface to use for interactive console features?
  1463         """what interface to use for interactive console features?
  1482         the default curses interface (crecord at the moment).
  1482         the default curses interface (crecord at the moment).
  1483         """
  1483         """
  1484         alldefaults = frozenset([b"text", b"curses"])
  1484         alldefaults = frozenset([b"text", b"curses"])
  1485 
  1485 
  1486         featureinterfaces = {
  1486         featureinterfaces = {
  1487             b"chunkselector": [b"text", b"curses",],
  1487             b"chunkselector": [
  1488             b"histedit": [b"text", b"curses",],
  1488                 b"text",
       
  1489                 b"curses",
       
  1490             ],
       
  1491             b"histedit": [
       
  1492                 b"text",
       
  1493                 b"curses",
       
  1494             ],
  1489         }
  1495         }
  1490 
  1496 
  1491         # Feature-specific interface
  1497         # Feature-specific interface
  1492         if feature not in featureinterfaces.keys():
  1498         if feature not in featureinterfaces.keys():
  1493             # Programming error, not user error
  1499             # Programming error, not user error
  1530             )
  1536             )
  1531 
  1537 
  1532         return choseninterface
  1538         return choseninterface
  1533 
  1539 
  1534     def interactive(self):
  1540     def interactive(self):
  1535         '''is interactive input allowed?
  1541         """is interactive input allowed?
  1536 
  1542 
  1537         An interactive session is a session where input can be reasonably read
  1543         An interactive session is a session where input can be reasonably read
  1538         from `sys.stdin'. If this function returns false, any attempt to read
  1544         from `sys.stdin'. If this function returns false, any attempt to read
  1539         from stdin should fail with an error, unless a sensible default has been
  1545         from stdin should fail with an error, unless a sensible default has been
  1540         specified.
  1546         specified.
  1542         Interactiveness is triggered by the value of the `ui.interactive'
  1548         Interactiveness is triggered by the value of the `ui.interactive'
  1543         configuration variable or - if it is unset - when `sys.stdin' points
  1549         configuration variable or - if it is unset - when `sys.stdin' points
  1544         to a terminal device.
  1550         to a terminal device.
  1545 
  1551 
  1546         This function refers to input only; for output, see `ui.formatted()'.
  1552         This function refers to input only; for output, see `ui.formatted()'.
  1547         '''
  1553         """
  1548         i = self.configbool(b"ui", b"interactive")
  1554         i = self.configbool(b"ui", b"interactive")
  1549         if i is None:
  1555         if i is None:
  1550             # some environments replace stdin without implementing isatty
  1556             # some environments replace stdin without implementing isatty
  1551             # usually those are non-interactive
  1557             # usually those are non-interactive
  1552             return self._isatty(self._fin)
  1558             return self._isatty(self._fin)
  1553 
  1559 
  1554         return i
  1560         return i
  1555 
  1561 
  1556     def termwidth(self):
  1562     def termwidth(self):
  1557         '''how wide is the terminal in columns?
  1563         """how wide is the terminal in columns?"""
  1558         '''
       
  1559         if b'COLUMNS' in encoding.environ:
  1564         if b'COLUMNS' in encoding.environ:
  1560             try:
  1565             try:
  1561                 return int(encoding.environ[b'COLUMNS'])
  1566                 return int(encoding.environ[b'COLUMNS'])
  1562             except ValueError:
  1567             except ValueError:
  1563                 pass
  1568                 pass
  1564         return scmutil.termsize(self)[0]
  1569         return scmutil.termsize(self)[0]
  1565 
  1570 
  1566     def formatted(self):
  1571     def formatted(self):
  1567         '''should formatted output be used?
  1572         """should formatted output be used?
  1568 
  1573 
  1569         It is often desirable to format the output to suite the output medium.
  1574         It is often desirable to format the output to suite the output medium.
  1570         Examples of this are truncating long lines or colorizing messages.
  1575         Examples of this are truncating long lines or colorizing messages.
  1571         However, this is not often not desirable when piping output into other
  1576         However, this is not often not desirable when piping output into other
  1572         utilities, e.g. `grep'.
  1577         utilities, e.g. `grep'.
  1577         considered an implementation detail; it is not intended for use outside
  1582         considered an implementation detail; it is not intended for use outside
  1578         Mercurial or its extensions.
  1583         Mercurial or its extensions.
  1579 
  1584 
  1580         This function refers to output only; for input, see `ui.interactive()'.
  1585         This function refers to output only; for input, see `ui.interactive()'.
  1581         This function always returns false when in plain mode, see `ui.plain()'.
  1586         This function always returns false when in plain mode, see `ui.plain()'.
  1582         '''
  1587         """
  1583         if self.plain():
  1588         if self.plain():
  1584             return False
  1589             return False
  1585 
  1590 
  1586         i = self.configbool(b"ui", b"formatted")
  1591         i = self.configbool(b"ui", b"formatted")
  1587         if i is None:
  1592         if i is None:
  1744                     return encoding.strtolocal(getpass.getpass(''))
  1749                     return encoding.strtolocal(getpass.getpass(''))
  1745         except EOFError:
  1750         except EOFError:
  1746             raise error.ResponseExpected()
  1751             raise error.ResponseExpected()
  1747 
  1752 
  1748     def status(self, *msg, **opts):
  1753     def status(self, *msg, **opts):
  1749         '''write status message to output (if ui.quiet is False)
  1754         """write status message to output (if ui.quiet is False)
  1750 
  1755 
  1751         This adds an output label of "ui.status".
  1756         This adds an output label of "ui.status".
  1752         '''
  1757         """
  1753         if not self.quiet:
  1758         if not self.quiet:
  1754             self._writemsg(self._fmsgout, type=b'status', *msg, **opts)
  1759             self._writemsg(self._fmsgout, type=b'status', *msg, **opts)
  1755 
  1760 
  1756     def warn(self, *msg, **opts):
  1761     def warn(self, *msg, **opts):
  1757         '''write warning message to output (stderr)
  1762         """write warning message to output (stderr)
  1758 
  1763 
  1759         This adds an output label of "ui.warning".
  1764         This adds an output label of "ui.warning".
  1760         '''
  1765         """
  1761         self._writemsg(self._fmsgerr, type=b'warning', *msg, **opts)
  1766         self._writemsg(self._fmsgerr, type=b'warning', *msg, **opts)
  1762 
  1767 
  1763     def error(self, *msg, **opts):
  1768     def error(self, *msg, **opts):
  1764         '''write error message to output (stderr)
  1769         """write error message to output (stderr)
  1765 
  1770 
  1766         This adds an output label of "ui.error".
  1771         This adds an output label of "ui.error".
  1767         '''
  1772         """
  1768         self._writemsg(self._fmsgerr, type=b'error', *msg, **opts)
  1773         self._writemsg(self._fmsgerr, type=b'error', *msg, **opts)
  1769 
  1774 
  1770     def note(self, *msg, **opts):
  1775     def note(self, *msg, **opts):
  1771         '''write note to output (if ui.verbose is True)
  1776         """write note to output (if ui.verbose is True)
  1772 
  1777 
  1773         This adds an output label of "ui.note".
  1778         This adds an output label of "ui.note".
  1774         '''
  1779         """
  1775         if self.verbose:
  1780         if self.verbose:
  1776             self._writemsg(self._fmsgout, type=b'note', *msg, **opts)
  1781             self._writemsg(self._fmsgout, type=b'note', *msg, **opts)
  1777 
  1782 
  1778     def debug(self, *msg, **opts):
  1783     def debug(self, *msg, **opts):
  1779         '''write debug message to output (if ui.debugflag is True)
  1784         """write debug message to output (if ui.debugflag is True)
  1780 
  1785 
  1781         This adds an output label of "ui.debug".
  1786         This adds an output label of "ui.debug".
  1782         '''
  1787         """
  1783         if self.debugflag:
  1788         if self.debugflag:
  1784             self._writemsg(self._fmsgout, type=b'debug', *msg, **opts)
  1789             self._writemsg(self._fmsgout, type=b'debug', *msg, **opts)
  1785             self.log(b'debug', b'%s', b''.join(msg))
  1790             self.log(b'debug', b'%s', b''.join(msg))
  1786 
  1791 
  1787     # Aliases to defeat check-code.
  1792     # Aliases to defeat check-code.
  1873         cwd=None,
  1878         cwd=None,
  1874         onerr=None,
  1879         onerr=None,
  1875         errprefix=None,
  1880         errprefix=None,
  1876         blockedtag=None,
  1881         blockedtag=None,
  1877     ):
  1882     ):
  1878         '''execute shell command with appropriate output stream. command
  1883         """execute shell command with appropriate output stream. command
  1879         output will be redirected if fout is not stdout.
  1884         output will be redirected if fout is not stdout.
  1880 
  1885 
  1881         if command fails and onerr is None, return status, else raise onerr
  1886         if command fails and onerr is None, return status, else raise onerr
  1882         object as exception.
  1887         object as exception.
  1883         '''
  1888         """
  1884         if blockedtag is None:
  1889         if blockedtag is None:
  1885             # Long cmds tend to be because of an absolute path on cmd. Keep
  1890             # Long cmds tend to be because of an absolute path on cmd. Keep
  1886             # the tail end instead
  1891             # the tail end instead
  1887             cmdsuffix = cmd.translate(None, _keepalnum)[-85:]
  1892             cmdsuffix = cmd.translate(None, _keepalnum)[-85:]
  1888             blockedtag = b'unknown_system_' + cmdsuffix
  1893             blockedtag = b'unknown_system_' + cmdsuffix
  1905         """actually execute the given shell command (can be overridden by
  1910         """actually execute the given shell command (can be overridden by
  1906         extensions like chg)"""
  1911         extensions like chg)"""
  1907         return procutil.system(cmd, environ=environ, cwd=cwd, out=out)
  1912         return procutil.system(cmd, environ=environ, cwd=cwd, out=out)
  1908 
  1913 
  1909     def traceback(self, exc=None, force=False):
  1914     def traceback(self, exc=None, force=False):
  1910         '''print exception traceback if traceback printing enabled or forced.
  1915         """print exception traceback if traceback printing enabled or forced.
  1911         only to call in exception handler. returns true if traceback
  1916         only to call in exception handler. returns true if traceback
  1912         printed.'''
  1917         printed."""
  1913         if self.tracebackflag or force:
  1918         if self.tracebackflag or force:
  1914             if exc is None:
  1919             if exc is None:
  1915                 exc = sys.exc_info()
  1920                 exc = sys.exc_info()
  1916             cause = getattr(exc[1], 'cause', None)
  1921             cause = getattr(exc[1], 'cause', None)
  1917 
  1922 
  2009         name to uniquely identify the logger instance.
  2014         name to uniquely identify the logger instance.
  2010         """
  2015         """
  2011         self._loggers[name] = logger
  2016         self._loggers[name] = logger
  2012 
  2017 
  2013     def log(self, event, msgfmt, *msgargs, **opts):
  2018     def log(self, event, msgfmt, *msgargs, **opts):
  2014         '''hook for logging facility extensions
  2019         """hook for logging facility extensions
  2015 
  2020 
  2016         event should be a readily-identifiable subsystem, which will
  2021         event should be a readily-identifiable subsystem, which will
  2017         allow filtering.
  2022         allow filtering.
  2018 
  2023 
  2019         msgfmt should be a newline-terminated format string to log, and
  2024         msgfmt should be a newline-terminated format string to log, and
  2020         *msgargs are %-formatted into it.
  2025         *msgargs are %-formatted into it.
  2021 
  2026 
  2022         **opts currently has no defined meanings.
  2027         **opts currently has no defined meanings.
  2023         '''
  2028         """
  2024         if not self._loggers:
  2029         if not self._loggers:
  2025             return
  2030             return
  2026         activeloggers = [
  2031         activeloggers = [
  2027             l for l in pycompat.itervalues(self._loggers) if l.tracked(event)
  2032             l for l in pycompat.itervalues(self._loggers) if l.tracked(event)
  2028         ]
  2033         ]
  2038                 logger.log(self, event, msg, opts)
  2043                 logger.log(self, event, msg, opts)
  2039         finally:
  2044         finally:
  2040             self._loggers = registeredloggers
  2045             self._loggers = registeredloggers
  2041 
  2046 
  2042     def label(self, msg, label):
  2047     def label(self, msg, label):
  2043         '''style msg based on supplied label
  2048         """style msg based on supplied label
  2044 
  2049 
  2045         If some color mode is enabled, this will add the necessary control
  2050         If some color mode is enabled, this will add the necessary control
  2046         characters to apply such color. In addition, 'debug' color mode adds
  2051         characters to apply such color. In addition, 'debug' color mode adds
  2047         markup showing which label affects a piece of text.
  2052         markup showing which label affects a piece of text.
  2048 
  2053 
  2049         ui.write(s, 'label') is equivalent to
  2054         ui.write(s, 'label') is equivalent to
  2050         ui.write(ui.label(s, 'label')).
  2055         ui.write(ui.label(s, 'label')).
  2051         '''
  2056         """
  2052         if self._colormode is not None:
  2057         if self._colormode is not None:
  2053             return color.colorlabel(self, msg, label)
  2058             return color.colorlabel(self, msg, label)
  2054         return msg
  2059         return msg
  2055 
  2060 
  2056     def develwarn(self, msg, stacklevel=1, config=None):
  2061     def develwarn(self, msg, stacklevel=1, config=None):