mercurial/ui.py
author mpm@selenic.com
Thu, 08 Sep 2005 17:09:31 -0700
changeset 1225 ea90162e210c
parent 1147 d32b91ebad5d
child 1292 141951276ba1
permissions -rw-r--r--
Add --debugger global option With this option, hg will drop into the Python debugger on execution. Running 'continue' will execute normally, and the debugger will be reinvoked if an exception is raised.

# ui.py - user interface bits for mercurial
#
# Copyright 2005 Matt Mackall <mpm@selenic.com>
#
# This software may be used and distributed according to the terms
# of the GNU General Public License, incorporated herein by reference.

import os, ConfigParser
from demandload import *
demandload(globals(), "re socket sys util")

class ui:
    def __init__(self, verbose=False, debug=False, quiet=False,
                 interactive=True):
        self.overlay = {}
        self.cdata = ConfigParser.SafeConfigParser()
        self.cdata.read([os.path.normpath(hgrc) for hgrc in
                         "/etc/mercurial/hgrc", os.path.expanduser("~/.hgrc")])

        self.quiet = self.configbool("ui", "quiet")
        self.verbose = self.configbool("ui", "verbose")
        self.debugflag = self.configbool("ui", "debug")
        self.interactive = self.configbool("ui", "interactive", True)

        self.updateopts(verbose, debug, quiet, interactive)

    def updateopts(self, verbose=False, debug=False, quiet=False,
                 interactive=True):
        self.quiet = (self.quiet or quiet) and not verbose and not debug
        self.verbose = (self.verbose or verbose) or debug
        self.debugflag = (self.debugflag or debug)
        self.interactive = (self.interactive and interactive)

    def readconfig(self, fp):
        self.cdata.readfp(fp)

    def setconfig(self, section, name, val):
        self.overlay[(section, name)] = val

    def config(self, section, name, default=None):
        if self.overlay.has_key((section, name)):
            return self.overlay[(section, name)]
        if self.cdata.has_option(section, name):
            return self.cdata.get(section, name)
        return default

    def configbool(self, section, name, default=False):
        if self.overlay.has_key((section, name)):
            return self.overlay[(section, name)]
        if self.cdata.has_option(section, name):
            return self.cdata.getboolean(section, name)
        return default

    def configitems(self, section):
        if self.cdata.has_section(section):
            return self.cdata.items(section)
        return []

    def walkconfig(self):
        seen = {}
        for (section, name), value in self.overlay.iteritems():
            yield section, name, value
            seen[section, name] = 1
        for section in self.cdata.sections():
            for name, value in self.cdata.items(section):
                if (section, name) in seen: continue
                yield section, name, value.replace('\n', '\\n')
                seen[section, name] = 1

    def extensions(self):
        return self.configitems("extensions")

    def username(self):
        return (os.environ.get("HGUSER") or
                self.config("ui", "username") or
                os.environ.get("EMAIL") or
                (os.environ.get("LOGNAME",
                                os.environ.get("USERNAME", "unknown"))
                 + '@' + socket.getfqdn()))

    def shortuser(self, user):
        """Return a short representation of a user name or email address."""
        if not self.verbose:
            f = user.find('@')
            if f >= 0:
                user = user[:f]
            f = user.find('<')
            if f >= 0:
                user = user[f+1:]
        return user

    def expandpath(self, loc):
        paths = {}
        for name, path in self.configitems("paths"):
            paths[name] = path

        return paths.get(loc, loc)

    def write(self, *args):
        for a in args:
            sys.stdout.write(str(a))

    def write_err(self, *args):
        sys.stdout.flush()
        for a in args:
            sys.stderr.write(str(a))

    def readline(self):
        return sys.stdin.readline()[:-1]
    def prompt(self, msg, pat, default="y"):
        if not self.interactive: return default
        while 1:
            self.write(msg, " ")
            r = self.readline()
            if re.match(pat, r):
                return r
            else:
                self.write("unrecognized response\n")
    def status(self, *msg):
        if not self.quiet: self.write(*msg)
    def warn(self, *msg):
        self.write_err(*msg)
    def note(self, *msg):
        if self.verbose: self.write(*msg)
    def debug(self, *msg):
        if self.debugflag: self.write(*msg)
    def edit(self, text):
        import tempfile
        (fd, name) = tempfile.mkstemp("hg")
        f = os.fdopen(fd, "w")
        f.write(text)
        f.close()

        editor = (os.environ.get("HGEDITOR") or
                  self.config("ui", "editor") or
                  os.environ.get("EDITOR", "vi"))

        os.environ["HGUSER"] = self.username()
        util.system("%s %s" % (editor, name), errprefix="edit failed")

        t = open(name).read()
        t = re.sub("(?m)^HG:.*\n", "", t)

        os.unlink(name)

        return t