summaryrefslogtreecommitdiff
path: root/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/mercurial/ui.py
diff options
context:
space:
mode:
authorNishanth Amuluru2011-01-08 11:20:57 +0530
committerNishanth Amuluru2011-01-08 11:20:57 +0530
commit65411d01d448ff0cd4abd14eee14cf60b5f8fc20 (patch)
treeb4c404363c4c63a61d6e2f8bd26c5b057c1fb09d /eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/mercurial/ui.py
parent2e35094d43b4cc6974172e1febf76abb50f086ec (diff)
downloadpytask-65411d01d448ff0cd4abd14eee14cf60b5f8fc20.tar.gz
pytask-65411d01d448ff0cd4abd14eee14cf60b5f8fc20.tar.bz2
pytask-65411d01d448ff0cd4abd14eee14cf60b5f8fc20.zip
Added buildout stuff and made changes accordingly
--HG-- rename : profile/management/__init__.py => eggs/djangorecipe-0.20-py2.6.egg/EGG-INFO/dependency_links.txt rename : profile/management/__init__.py => eggs/djangorecipe-0.20-py2.6.egg/EGG-INFO/not-zip-safe rename : profile/management/__init__.py => eggs/infrae.subversion-1.4.5-py2.6.egg/EGG-INFO/dependency_links.txt rename : profile/management/__init__.py => eggs/infrae.subversion-1.4.5-py2.6.egg/EGG-INFO/not-zip-safe rename : profile/management/__init__.py => eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/EGG-INFO/dependency_links.txt rename : profile/management/__init__.py => eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/EGG-INFO/not-zip-safe rename : profile/management/__init__.py => eggs/py-1.4.0-py2.6.egg/EGG-INFO/dependency_links.txt rename : profile/management/__init__.py => eggs/py-1.4.0-py2.6.egg/EGG-INFO/not-zip-safe rename : profile/management/__init__.py => eggs/zc.buildout-1.5.2-py2.6.egg/EGG-INFO/dependency_links.txt rename : profile/management/__init__.py => eggs/zc.buildout-1.5.2-py2.6.egg/EGG-INFO/not-zip-safe rename : profile/management/__init__.py => eggs/zc.recipe.egg-1.3.2-py2.6.egg/EGG-INFO/dependency_links.txt rename : profile/management/__init__.py => eggs/zc.recipe.egg-1.3.2-py2.6.egg/EGG-INFO/not-zip-safe rename : profile/management/__init__.py => parts/django/Django.egg-info/dependency_links.txt rename : taskapp/models.py => parts/django/django/conf/app_template/models.py rename : taskapp/tests.py => parts/django/django/conf/app_template/tests.py rename : taskapp/views.py => parts/django/django/conf/app_template/views.py rename : taskapp/views.py => parts/django/django/contrib/gis/tests/geo3d/views.py rename : profile/management/__init__.py => parts/django/tests/modeltests/delete/__init__.py rename : profile/management/__init__.py => parts/django/tests/modeltests/files/__init__.py rename : profile/management/__init__.py => parts/django/tests/modeltests/invalid_models/__init__.py rename : profile/management/__init__.py => parts/django/tests/modeltests/m2m_signals/__init__.py rename : profile/management/__init__.py => parts/django/tests/modeltests/model_package/__init__.py rename : profile/management/__init__.py => parts/django/tests/regressiontests/bash_completion/__init__.py rename : profile/management/__init__.py => parts/django/tests/regressiontests/bash_completion/management/__init__.py rename : profile/management/__init__.py => parts/django/tests/regressiontests/bash_completion/management/commands/__init__.py rename : profile/management/__init__.py => parts/django/tests/regressiontests/bash_completion/models.py rename : profile/management/__init__.py => parts/django/tests/regressiontests/delete_regress/__init__.py rename : profile/management/__init__.py => parts/django/tests/regressiontests/file_storage/__init__.py rename : profile/management/__init__.py => parts/django/tests/regressiontests/max_lengths/__init__.py rename : profile/forms.py => pytask/profile/forms.py rename : profile/management/__init__.py => pytask/profile/management/__init__.py rename : profile/management/commands/seed_db.py => pytask/profile/management/commands/seed_db.py rename : profile/models.py => pytask/profile/models.py rename : profile/templatetags/user_tags.py => pytask/profile/templatetags/user_tags.py rename : taskapp/tests.py => pytask/profile/tests.py rename : profile/urls.py => pytask/profile/urls.py rename : profile/utils.py => pytask/profile/utils.py rename : profile/views.py => pytask/profile/views.py rename : static/css/base.css => pytask/static/css/base.css rename : taskapp/tests.py => pytask/taskapp/tests.py rename : taskapp/views.py => pytask/taskapp/views.py rename : templates/base.html => pytask/templates/base.html rename : templates/profile/browse_notifications.html => pytask/templates/profile/browse_notifications.html rename : templates/profile/edit.html => pytask/templates/profile/edit.html rename : templates/profile/view.html => pytask/templates/profile/view.html rename : templates/profile/view_notification.html => pytask/templates/profile/view_notification.html rename : templates/registration/activate.html => pytask/templates/registration/activate.html rename : templates/registration/activation_email.txt => pytask/templates/registration/activation_email.txt rename : templates/registration/activation_email_subject.txt => pytask/templates/registration/activation_email_subject.txt rename : templates/registration/logged_out.html => pytask/templates/registration/logged_out.html rename : templates/registration/login.html => pytask/templates/registration/login.html rename : templates/registration/logout.html => pytask/templates/registration/logout.html rename : templates/registration/password_change_done.html => pytask/templates/registration/password_change_done.html rename : templates/registration/password_change_form.html => pytask/templates/registration/password_change_form.html rename : templates/registration/password_reset_complete.html => pytask/templates/registration/password_reset_complete.html rename : templates/registration/password_reset_confirm.html => pytask/templates/registration/password_reset_confirm.html rename : templates/registration/password_reset_done.html => pytask/templates/registration/password_reset_done.html rename : templates/registration/password_reset_email.html => pytask/templates/registration/password_reset_email.html rename : templates/registration/password_reset_form.html => pytask/templates/registration/password_reset_form.html rename : templates/registration/registration_complete.html => pytask/templates/registration/registration_complete.html rename : templates/registration/registration_form.html => pytask/templates/registration/registration_form.html rename : utils.py => pytask/utils.py
Diffstat (limited to 'eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/mercurial/ui.py')
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/mercurial/ui.py626
1 files changed, 626 insertions, 0 deletions
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/mercurial/ui.py b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/mercurial/ui.py
new file mode 100644
index 0000000..cd43fc7
--- /dev/null
+++ b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/mercurial/ui.py
@@ -0,0 +1,626 @@
+# ui.py - user interface bits for mercurial
+#
+# Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2 or any later version.
+
+from i18n import _
+import errno, getpass, os, socket, sys, tempfile, traceback
+import config, util, error
+
+class ui(object):
+ def __init__(self, src=None):
+ self._buffers = []
+ self.quiet = self.verbose = self.debugflag = self.tracebackflag = False
+ self._reportuntrusted = True
+ self._ocfg = config.config() # overlay
+ self._tcfg = config.config() # trusted
+ self._ucfg = config.config() # untrusted
+ self._trustusers = set()
+ self._trustgroups = set()
+
+ if src:
+ self._tcfg = src._tcfg.copy()
+ self._ucfg = src._ucfg.copy()
+ self._ocfg = src._ocfg.copy()
+ self._trustusers = src._trustusers.copy()
+ self._trustgroups = src._trustgroups.copy()
+ self.environ = src.environ
+ self.fixconfig()
+ else:
+ # shared read-only environment
+ self.environ = os.environ
+ # we always trust global config files
+ for f in util.rcpath():
+ self.readconfig(f, trust=True)
+
+ def copy(self):
+ return self.__class__(self)
+
+ def _is_trusted(self, fp, f):
+ st = util.fstat(fp)
+ if util.isowner(st):
+ return True
+
+ tusers, tgroups = self._trustusers, self._trustgroups
+ if '*' in tusers or '*' in tgroups:
+ return True
+
+ user = util.username(st.st_uid)
+ group = util.groupname(st.st_gid)
+ if user in tusers or group in tgroups or user == util.username():
+ return True
+
+ if self._reportuntrusted:
+ self.warn(_('Not trusting file %s from untrusted '
+ 'user %s, group %s\n') % (f, user, group))
+ return False
+
+ def readconfig(self, filename, root=None, trust=False,
+ sections=None, remap=None):
+ try:
+ fp = open(filename)
+ except IOError:
+ if not sections: # ignore unless we were looking for something
+ return
+ raise
+
+ cfg = config.config()
+ trusted = sections or trust or self._is_trusted(fp, filename)
+
+ try:
+ cfg.read(filename, fp, sections=sections, remap=remap)
+ except error.ConfigError, inst:
+ if trusted:
+ raise
+ self.warn(_("Ignored: %s\n") % str(inst))
+
+ if self.plain():
+ for k in ('debug', 'fallbackencoding', 'quiet', 'slash',
+ 'logtemplate', 'style',
+ 'traceback', 'verbose'):
+ if k in cfg['ui']:
+ del cfg['ui'][k]
+ for k, v in cfg.items('alias'):
+ del cfg['alias'][k]
+ for k, v in cfg.items('defaults'):
+ del cfg['defaults'][k]
+
+ if trusted:
+ self._tcfg.update(cfg)
+ self._tcfg.update(self._ocfg)
+ self._ucfg.update(cfg)
+ self._ucfg.update(self._ocfg)
+
+ if root is None:
+ root = os.path.expanduser('~')
+ self.fixconfig(root=root)
+
+ def fixconfig(self, root=None, section=None):
+ if section in (None, 'paths'):
+ # expand vars and ~
+ # translate paths relative to root (or home) into absolute paths
+ root = root or os.getcwd()
+ for c in self._tcfg, self._ucfg, self._ocfg:
+ for n, p in c.items('paths'):
+ if not p:
+ continue
+ if '%%' in p:
+ self.warn(_("(deprecated '%%' in path %s=%s from %s)\n")
+ % (n, p, self.configsource('paths', n)))
+ p = p.replace('%%', '%')
+ p = util.expandpath(p)
+ if '://' not in p and not os.path.isabs(p):
+ p = os.path.normpath(os.path.join(root, p))
+ c.set("paths", n, p)
+
+ if section in (None, 'ui'):
+ # update ui options
+ self.debugflag = self.configbool('ui', 'debug')
+ self.verbose = self.debugflag or self.configbool('ui', 'verbose')
+ self.quiet = not self.debugflag and self.configbool('ui', 'quiet')
+ if self.verbose and self.quiet:
+ self.quiet = self.verbose = False
+ self._reportuntrusted = self.configbool("ui", "report_untrusted",
+ True)
+ self.tracebackflag = self.configbool('ui', 'traceback', False)
+
+ if section in (None, 'trusted'):
+ # update trust information
+ self._trustusers.update(self.configlist('trusted', 'users'))
+ self._trustgroups.update(self.configlist('trusted', 'groups'))
+
+ def setconfig(self, section, name, value, overlay=True):
+ if overlay:
+ self._ocfg.set(section, name, value)
+ self._tcfg.set(section, name, value)
+ self._ucfg.set(section, name, value)
+ self.fixconfig(section=section)
+
+ def _data(self, untrusted):
+ return untrusted and self._ucfg or self._tcfg
+
+ def configsource(self, section, name, untrusted=False):
+ return self._data(untrusted).source(section, name) or 'none'
+
+ def config(self, section, name, default=None, untrusted=False):
+ value = self._data(untrusted).get(section, name, default)
+ if self.debugflag and not untrusted and self._reportuntrusted:
+ uvalue = self._ucfg.get(section, name)
+ if uvalue is not None and uvalue != value:
+ self.debug(_("ignoring untrusted configuration option "
+ "%s.%s = %s\n") % (section, name, uvalue))
+ return value
+
+ def configbool(self, section, name, default=False, untrusted=False):
+ v = self.config(section, name, None, untrusted)
+ if v is None:
+ return default
+ if isinstance(v, bool):
+ return v
+ b = util.parsebool(v)
+ if b is None:
+ raise error.ConfigError(_("%s.%s not a boolean ('%s')")
+ % (section, name, v))
+ return b
+
+ def configlist(self, section, name, default=None, untrusted=False):
+ """Return a list of comma/space separated strings"""
+
+ def _parse_plain(parts, s, offset):
+ whitespace = False
+ while offset < len(s) and (s[offset].isspace() or s[offset] == ','):
+ whitespace = True
+ offset += 1
+ if offset >= len(s):
+ return None, parts, offset
+ if whitespace:
+ parts.append('')
+ if s[offset] == '"' and not parts[-1]:
+ return _parse_quote, parts, offset + 1
+ elif s[offset] == '"' and parts[-1][-1] == '\\':
+ parts[-1] = parts[-1][:-1] + s[offset]
+ return _parse_plain, parts, offset + 1
+ parts[-1] += s[offset]
+ return _parse_plain, parts, offset + 1
+
+ def _parse_quote(parts, s, offset):
+ if offset < len(s) and s[offset] == '"': # ""
+ parts.append('')
+ offset += 1
+ while offset < len(s) and (s[offset].isspace() or
+ s[offset] == ','):
+ offset += 1
+ return _parse_plain, parts, offset
+
+ while offset < len(s) and s[offset] != '"':
+ if (s[offset] == '\\' and offset + 1 < len(s)
+ and s[offset + 1] == '"'):
+ offset += 1
+ parts[-1] += '"'
+ else:
+ parts[-1] += s[offset]
+ offset += 1
+
+ if offset >= len(s):
+ real_parts = _configlist(parts[-1])
+ if not real_parts:
+ parts[-1] = '"'
+ else:
+ real_parts[0] = '"' + real_parts[0]
+ parts = parts[:-1]
+ parts.extend(real_parts)
+ return None, parts, offset
+
+ offset += 1
+ while offset < len(s) and s[offset] in [' ', ',']:
+ offset += 1
+
+ if offset < len(s):
+ if offset + 1 == len(s) and s[offset] == '"':
+ parts[-1] += '"'
+ offset += 1
+ else:
+ parts.append('')
+ else:
+ return None, parts, offset
+
+ return _parse_plain, parts, offset
+
+ def _configlist(s):
+ s = s.rstrip(' ,')
+ if not s:
+ return []
+ parser, parts, offset = _parse_plain, [''], 0
+ while parser:
+ parser, parts, offset = parser(parts, s, offset)
+ return parts
+
+ result = self.config(section, name, untrusted=untrusted)
+ if result is None:
+ result = default or []
+ if isinstance(result, basestring):
+ result = _configlist(result.lstrip(' ,\n'))
+ if result is None:
+ result = default or []
+ return result
+
+ def has_section(self, section, untrusted=False):
+ '''tell whether section exists in config.'''
+ return section in self._data(untrusted)
+
+ def configitems(self, section, untrusted=False):
+ items = self._data(untrusted).items(section)
+ if self.debugflag and not untrusted and self._reportuntrusted:
+ for k, v in self._ucfg.items(section):
+ if self._tcfg.get(section, k) != v:
+ self.debug(_("ignoring untrusted configuration option "
+ "%s.%s = %s\n") % (section, k, v))
+ return items
+
+ def walkconfig(self, untrusted=False):
+ cfg = self._data(untrusted)
+ for section in cfg.sections():
+ for name, value in self.configitems(section, untrusted):
+ yield section, name, str(value).replace('\n', '\\n')
+
+ def plain(self):
+ '''is plain mode active?
+
+ Plain mode means that all configuration variables which affect the
+ behavior and output of Mercurial should be ignored. Additionally, the
+ output should be stable, reproducible and suitable for use in scripts or
+ applications.
+
+ The only way to trigger plain mode is by setting the `HGPLAIN'
+ environment variable.
+ '''
+ return 'HGPLAIN' in os.environ
+
+ def username(self):
+ """Return default username to be used in commits.
+
+ Searched in this order: $HGUSER, [ui] section of hgrcs, $EMAIL
+ and stop searching if one of these is set.
+ If not found and ui.askusername is True, ask the user, else use
+ ($LOGNAME or $USER or $LNAME or $USERNAME) + "@full.hostname".
+ """
+ user = os.environ.get("HGUSER")
+ if user is None:
+ user = self.config("ui", "username")
+ if user is not None:
+ user = os.path.expandvars(user)
+ if user is None:
+ user = os.environ.get("EMAIL")
+ if user is None and self.configbool("ui", "askusername"):
+ user = self.prompt(_("enter a commit username:"), default=None)
+ if user is None and not self.interactive():
+ try:
+ user = '%s@%s' % (util.getuser(), socket.getfqdn())
+ self.warn(_("No username found, using '%s' instead\n") % user)
+ except KeyError:
+ pass
+ if not user:
+ raise util.Abort(_('no username supplied (see "hg help config")'))
+ if "\n" in user:
+ raise util.Abort(_("username %s contains a newline\n") % repr(user))
+ return user
+
+ def shortuser(self, user):
+ """Return a short representation of a user name or email address."""
+ if not self.verbose:
+ user = util.shortuser(user)
+ return user
+
+ def expandpath(self, loc, default=None):
+ """Return repository location relative to cwd or from [paths]"""
+ if "://" in loc or os.path.isdir(os.path.join(loc, '.hg')):
+ return loc
+
+ path = self.config('paths', loc)
+ if not path and default is not None:
+ path = self.config('paths', default)
+ return path or loc
+
+ def pushbuffer(self):
+ self._buffers.append([])
+
+ def popbuffer(self, labeled=False):
+ '''pop the last buffer and return the buffered output
+
+ If labeled is True, any labels associated with buffered
+ output will be handled. By default, this has no effect
+ on the output returned, but extensions and GUI tools may
+ handle this argument and returned styled output. If output
+ is being buffered so it can be captured and parsed or
+ processed, labeled should not be set to True.
+ '''
+ return "".join(self._buffers.pop())
+
+ def write(self, *args, **opts):
+ '''write args to output
+
+ By default, this method simply writes to the buffer or stdout,
+ but extensions or GUI tools may override this method,
+ write_err(), popbuffer(), and label() to style output from
+ various parts of hg.
+
+ An optional keyword argument, "label", can be passed in.
+ This should be a string containing label names separated by
+ space. Label names take the form of "topic.type". For example,
+ ui.debug() issues a label of "ui.debug".
+
+ When labeling output for a specific command, a label of
+ "cmdname.type" is recommended. For example, status issues
+ a label of "status.modified" for modified files.
+ '''
+ if self._buffers:
+ self._buffers[-1].extend([str(a) for a in args])
+ else:
+ for a in args:
+ sys.stdout.write(str(a))
+
+ def write_err(self, *args, **opts):
+ try:
+ if not getattr(sys.stdout, 'closed', False):
+ sys.stdout.flush()
+ for a in args:
+ sys.stderr.write(str(a))
+ # stderr may be buffered under win32 when redirected to files,
+ # including stdout.
+ if not getattr(sys.stderr, 'closed', False):
+ sys.stderr.flush()
+ except IOError, inst:
+ if inst.errno not in (errno.EPIPE, errno.EIO):
+ raise
+
+ def flush(self):
+ try: sys.stdout.flush()
+ except: pass
+ try: sys.stderr.flush()
+ except: pass
+
+ def interactive(self):
+ '''is interactive input allowed?
+
+ An interactive session is a session where input can be reasonably read
+ from `sys.stdin'. If this function returns false, any attempt to read
+ from stdin should fail with an error, unless a sensible default has been
+ specified.
+
+ Interactiveness is triggered by the value of the `ui.interactive'
+ configuration variable or - if it is unset - when `sys.stdin' points
+ to a terminal device.
+
+ This function refers to input only; for output, see `ui.formatted()'.
+ '''
+ i = self.configbool("ui", "interactive", None)
+ if i is None:
+ try:
+ return sys.stdin.isatty()
+ except AttributeError:
+ # some environments replace stdin without implementing isatty
+ # usually those are non-interactive
+ return False
+
+ return i
+
+ def termwidth(self):
+ '''how wide is the terminal in columns?
+ '''
+ if 'COLUMNS' in os.environ:
+ try:
+ return int(os.environ['COLUMNS'])
+ except ValueError:
+ pass
+ return util.termwidth()
+
+ def formatted(self):
+ '''should formatted output be used?
+
+ It is often desirable to format the output to suite the output medium.
+ Examples of this are truncating long lines or colorizing messages.
+ However, this is not often not desirable when piping output into other
+ utilities, e.g. `grep'.
+
+ Formatted output is triggered by the value of the `ui.formatted'
+ configuration variable or - if it is unset - when `sys.stdout' points
+ to a terminal device. Please note that `ui.formatted' should be
+ considered an implementation detail; it is not intended for use outside
+ Mercurial or its extensions.
+
+ This function refers to output only; for input, see `ui.interactive()'.
+ This function always returns false when in plain mode, see `ui.plain()'.
+ '''
+ if self.plain():
+ return False
+
+ i = self.configbool("ui", "formatted", None)
+ if i is None:
+ try:
+ return sys.stdout.isatty()
+ except AttributeError:
+ # some environments replace stdout without implementing isatty
+ # usually those are non-interactive
+ return False
+
+ return i
+
+ def _readline(self, prompt=''):
+ if sys.stdin.isatty():
+ try:
+ # magically add command line editing support, where
+ # available
+ import readline
+ # force demandimport to really load the module
+ readline.read_history_file
+ # windows sometimes raises something other than ImportError
+ except Exception:
+ pass
+ line = raw_input(prompt)
+ # When stdin is in binary mode on Windows, it can cause
+ # raw_input() to emit an extra trailing carriage return
+ if os.linesep == '\r\n' and line and line[-1] == '\r':
+ line = line[:-1]
+ return line
+
+ def prompt(self, msg, default="y"):
+ """Prompt user with msg, read response.
+ If ui is not interactive, the default is returned.
+ """
+ if not self.interactive():
+ self.write(msg, ' ', default, "\n")
+ return default
+ try:
+ r = self._readline(msg + ' ')
+ if not r:
+ return default
+ return r
+ except EOFError:
+ raise util.Abort(_('response expected'))
+
+ def promptchoice(self, msg, choices, default=0):
+ """Prompt user with msg, read response, and ensure it matches
+ one of the provided choices. The index of the choice is returned.
+ choices is a sequence of acceptable responses with the format:
+ ('&None', 'E&xec', 'Sym&link') Responses are case insensitive.
+ If ui is not interactive, the default is returned.
+ """
+ resps = [s[s.index('&')+1].lower() for s in choices]
+ while True:
+ r = self.prompt(msg, resps[default])
+ if r.lower() in resps:
+ return resps.index(r.lower())
+ self.write(_("unrecognized response\n"))
+
+ def getpass(self, prompt=None, default=None):
+ if not self.interactive():
+ return default
+ try:
+ return getpass.getpass(prompt or _('password: '))
+ except EOFError:
+ raise util.Abort(_('response expected'))
+ def status(self, *msg, **opts):
+ '''write status message to output (if ui.quiet is False)
+
+ This adds an output label of "ui.status".
+ '''
+ if not self.quiet:
+ opts['label'] = opts.get('label', '') + ' ui.status'
+ self.write(*msg, **opts)
+ def warn(self, *msg, **opts):
+ '''write warning message to output (stderr)
+
+ This adds an output label of "ui.warning".
+ '''
+ opts['label'] = opts.get('label', '') + ' ui.warning'
+ self.write_err(*msg, **opts)
+ def note(self, *msg, **opts):
+ '''write note to output (if ui.verbose is True)
+
+ This adds an output label of "ui.note".
+ '''
+ if self.verbose:
+ opts['label'] = opts.get('label', '') + ' ui.note'
+ self.write(*msg, **opts)
+ def debug(self, *msg, **opts):
+ '''write debug message to output (if ui.debugflag is True)
+
+ This adds an output label of "ui.debug".
+ '''
+ if self.debugflag:
+ opts['label'] = opts.get('label', '') + ' ui.debug'
+ self.write(*msg, **opts)
+ def edit(self, text, user):
+ (fd, name) = tempfile.mkstemp(prefix="hg-editor-", suffix=".txt",
+ text=True)
+ try:
+ f = os.fdopen(fd, "w")
+ f.write(text)
+ f.close()
+
+ editor = self.geteditor()
+
+ util.system("%s \"%s\"" % (editor, name),
+ environ={'HGUSER': user},
+ onerr=util.Abort, errprefix=_("edit failed"))
+
+ f = open(name)
+ t = f.read()
+ f.close()
+ finally:
+ os.unlink(name)
+
+ return t
+
+ def traceback(self, exc=None):
+ '''print exception traceback if traceback printing enabled.
+ only to call in exception handler. returns true if traceback
+ printed.'''
+ if self.tracebackflag:
+ if exc:
+ traceback.print_exception(exc[0], exc[1], exc[2])
+ else:
+ traceback.print_exc()
+ return self.tracebackflag
+
+ def geteditor(self):
+ '''return editor to use'''
+ return (os.environ.get("HGEDITOR") or
+ self.config("ui", "editor") or
+ os.environ.get("VISUAL") or
+ os.environ.get("EDITOR", "vi"))
+
+ def progress(self, topic, pos, item="", unit="", total=None):
+ '''show a progress message
+
+ With stock hg, this is simply a debug message that is hidden
+ by default, but with extensions or GUI tools it may be
+ visible. 'topic' is the current operation, 'item' is a
+ non-numeric marker of the current position (ie the currently
+ in-process file), 'pos' is the current numeric position (ie
+ revision, bytes, etc.), unit is a corresponding unit label,
+ and total is the highest expected pos.
+
+ Multiple nested topics may be active at a time.
+
+ All topics should be marked closed by setting pos to None at
+ termination.
+ '''
+
+ if pos == None or not self.debugflag:
+ return
+
+ if unit:
+ unit = ' ' + unit
+ if item:
+ item = ' ' + item
+
+ if total:
+ pct = 100.0 * pos / total
+ self.debug('%s:%s %s/%s%s (%4.2f%%)\n'
+ % (topic, item, pos, total, unit, pct))
+ else:
+ self.debug('%s:%s %s%s\n' % (topic, item, pos, unit))
+
+ def log(self, service, message):
+ '''hook for logging facility extensions
+
+ service should be a readily-identifiable subsystem, which will
+ allow filtering.
+ message should be a newline-terminated string to log.
+ '''
+ pass
+
+ def label(self, msg, label):
+ '''style msg based on supplied label
+
+ Like ui.write(), this just returns msg unchanged, but extensions
+ and GUI tools can override it to allow styling output without
+ writing it.
+
+ ui.write(s, 'label') is equivalent to
+ ui.write(ui.label(s, 'label')).
+ '''
+ return msg