mercurial/ui.py
changeset 1920 b7cc0f323a4c
parent 1903 e4abeafd6eb1
parent 1893 6569651a4f1e
child 1938 36c6e4c3ff43
equal deleted inserted replaced
1919:8f565af14095 1920:b7cc0f323a4c
     3 # Copyright 2005 Matt Mackall <mpm@selenic.com>
     3 # Copyright 2005 Matt Mackall <mpm@selenic.com>
     4 #
     4 #
     5 # This software may be used and distributed according to the terms
     5 # This software may be used and distributed according to the terms
     6 # of the GNU General Public License, incorporated herein by reference.
     6 # of the GNU General Public License, incorporated herein by reference.
     7 
     7 
     8 import os, ConfigParser
     8 import ConfigParser
     9 from i18n import gettext as _
     9 from i18n import gettext as _
    10 from demandload import *
    10 from demandload import *
    11 demandload(globals(), "re socket sys util")
    11 demandload(globals(), "os re socket sys util")
    12 
    12 
    13 class ui(object):
    13 class ui(object):
    14     def __init__(self, verbose=False, debug=False, quiet=False,
    14     def __init__(self, verbose=False, debug=False, quiet=False,
    15                  interactive=True):
    15                  interactive=True, parentui=None):
    16         self.overlay = {}
    16         self.overlay = {}
    17         self.cdata = ConfigParser.SafeConfigParser()
    17         if parentui is None:
    18         self.readconfig(util.rcpath)
    18             # this is the parent of all ui children
    19 
    19             self.parentui = None
    20         self.quiet = self.configbool("ui", "quiet")
    20             self.cdata = ConfigParser.SafeConfigParser()
    21         self.verbose = self.configbool("ui", "verbose")
    21             self.readconfig(util.rcpath)
    22         self.debugflag = self.configbool("ui", "debug")
    22 
    23         self.interactive = self.configbool("ui", "interactive", True)
    23             self.quiet = self.configbool("ui", "quiet")
    24 
    24             self.verbose = self.configbool("ui", "verbose")
    25         self.updateopts(verbose, debug, quiet, interactive)
    25             self.debugflag = self.configbool("ui", "debug")
    26         self.diffcache = None
    26             self.interactive = self.configbool("ui", "interactive", True)
       
    27 
       
    28             self.updateopts(verbose, debug, quiet, interactive)
       
    29             self.diffcache = None
       
    30         else:
       
    31             # parentui may point to an ui object which is already a child
       
    32             self.parentui = parentui.parentui or parentui
       
    33             parent_cdata = self.parentui.cdata
       
    34             self.cdata = ConfigParser.SafeConfigParser(parent_cdata.defaults())
       
    35             # make interpolation work
       
    36             for section in parent_cdata.sections():
       
    37                 self.cdata.add_section(section)
       
    38                 for name, value in parent_cdata.items(section, raw=True):
       
    39                     self.cdata.set(section, name, value)
       
    40 
       
    41     def __getattr__(self, key):
       
    42         return getattr(self.parentui, key)
    27 
    43 
    28     def updateopts(self, verbose=False, debug=False, quiet=False,
    44     def updateopts(self, verbose=False, debug=False, quiet=False,
    29                  interactive=True):
    45                  interactive=True):
    30         self.quiet = (self.quiet or quiet) and not verbose and not debug
    46         self.quiet = (self.quiet or quiet) and not verbose and not debug
    31         self.verbose = (self.verbose or verbose) or debug
    47         self.verbose = (self.verbose or verbose) or debug
    32         self.debugflag = (self.debugflag or debug)
    48         self.debugflag = (self.debugflag or debug)
    33         self.interactive = (self.interactive and interactive)
    49         self.interactive = (self.interactive and interactive)
    34 
    50 
    35     def readconfig(self, fn):
    51     def readconfig(self, fn, root=None):
    36         if isinstance(fn, basestring):
    52         if isinstance(fn, basestring):
    37             fn = [fn]
    53             fn = [fn]
    38         for f in fn:
    54         for f in fn:
    39             try:
    55             try:
    40                 self.cdata.read(f)
    56                 self.cdata.read(f)
    41             except ConfigParser.ParsingError, inst:
    57             except ConfigParser.ParsingError, inst:
    42                 raise util.Abort(_("Failed to parse %s\n%s") % (f, inst))
    58                 raise util.Abort(_("Failed to parse %s\n%s") % (f, inst))
       
    59         # translate paths relative to root (or home) into absolute paths
       
    60         if root is None:
       
    61             root = os.path.expanduser('~')
       
    62         for name, path in self.configitems("paths"):
       
    63             if path.find("://") == -1 and not os.path.isabs(path):
       
    64                 self.cdata.set("paths", name, os.path.join(root, path))
    43 
    65 
    44     def setconfig(self, section, name, val):
    66     def setconfig(self, section, name, val):
    45         self.overlay[(section, name)] = val
    67         self.overlay[(section, name)] = val
    46 
    68 
    47     def config(self, section, name, default=None):
    69     def config(self, section, name, default=None):
    48         if self.overlay.has_key((section, name)):
    70         if self.overlay.has_key((section, name)):
    49             return self.overlay[(section, name)]
    71             return self.overlay[(section, name)]
    50         if self.cdata.has_option(section, name):
    72         if self.cdata.has_option(section, name):
    51             return self.cdata.get(section, name)
    73             try:
    52         return default
    74                 return self.cdata.get(section, name)
       
    75             except ConfigParser.InterpolationError, inst:
       
    76                 raise util.Abort(_("Error in configuration:\n%s") % inst)
       
    77         if self.parentui is None:
       
    78             return default
       
    79         else:
       
    80             return self.parentui.config(section, name, default)
    53 
    81 
    54     def configbool(self, section, name, default=False):
    82     def configbool(self, section, name, default=False):
    55         if self.overlay.has_key((section, name)):
    83         if self.overlay.has_key((section, name)):
    56             return self.overlay[(section, name)]
    84             return self.overlay[(section, name)]
    57         if self.cdata.has_option(section, name):
    85         if self.cdata.has_option(section, name):
    58             return self.cdata.getboolean(section, name)
    86             try:
    59         return default
    87                 return self.cdata.getboolean(section, name)
       
    88             except ConfigParser.InterpolationError, inst:
       
    89                 raise util.Abort(_("Error in configuration:\n%s") % inst)
       
    90         if self.parentui is None:
       
    91             return default
       
    92         else:
       
    93             return self.parentui.configbool(section, name, default)
    60 
    94 
    61     def configitems(self, section):
    95     def configitems(self, section):
       
    96         items = {}
       
    97         if self.parentui is not None:
       
    98             items = dict(self.parentui.configitems(section))
    62         if self.cdata.has_section(section):
    99         if self.cdata.has_section(section):
    63             return self.cdata.items(section)
   100             try:
    64         return []
   101                 items.update(dict(self.cdata.items(section)))
    65 
   102             except ConfigParser.InterpolationError, inst:
    66     def walkconfig(self):
   103                 raise util.Abort(_("Error in configuration:\n%s") % inst)
    67         seen = {}
   104         x = items.items()
       
   105         x.sort()
       
   106         return x
       
   107 
       
   108     def walkconfig(self, seen=None):
       
   109         if seen is None:
       
   110             seen = {}
    68         for (section, name), value in self.overlay.iteritems():
   111         for (section, name), value in self.overlay.iteritems():
    69             yield section, name, value
   112             yield section, name, value
    70             seen[section, name] = 1
   113             seen[section, name] = 1
    71         for section in self.cdata.sections():
   114         for section in self.cdata.sections():
    72             for name, value in self.cdata.items(section):
   115             for name, value in self.cdata.items(section):
    73                 if (section, name) in seen: continue
   116                 if (section, name) in seen: continue
    74                 yield section, name, value.replace('\n', '\\n')
   117                 yield section, name, value.replace('\n', '\\n')
    75                 seen[section, name] = 1
   118                 seen[section, name] = 1
       
   119         if self.parentui is not None:
       
   120             for parent in self.parentui.walkconfig(seen):
       
   121                 yield parent
    76 
   122 
    77     def extensions(self):
   123     def extensions(self):
    78         return self.configitems("extensions")
   124         return self.configitems("extensions")
    79 
   125 
    80     def diffopts(self):
   126     def diffopts(self):
   105     def shortuser(self, user):
   151     def shortuser(self, user):
   106         """Return a short representation of a user name or email address."""
   152         """Return a short representation of a user name or email address."""
   107         if not self.verbose: user = util.shortuser(user)
   153         if not self.verbose: user = util.shortuser(user)
   108         return user
   154         return user
   109 
   155 
   110     def expandpath(self, loc, root=""):
   156     def expandpath(self, loc):
   111         paths = {}
   157         """Return repository location relative to cwd or from [paths]"""
   112         for name, path in self.configitems("paths"):
   158         if loc.find("://") != -1 or os.path.exists(loc):
   113             m = path.find("://")
   159             return loc
   114             if m == -1:
   160 
   115                     path = os.path.join(root, path)
   161         return self.config("paths", loc, loc)
   116             paths[name] = path
       
   117 
       
   118         return paths.get(loc, loc)
       
   119 
   162 
   120     def write(self, *args):
   163     def write(self, *args):
   121         for a in args:
   164         for a in args:
   122             sys.stdout.write(str(a))
   165             sys.stdout.write(str(a))
   123 
   166 
   124     def write_err(self, *args):
   167     def write_err(self, *args):
   125         if not sys.stdout.closed: sys.stdout.flush()
   168         if not sys.stdout.closed: sys.stdout.flush()
   126         for a in args:
   169         for a in args:
   127             sys.stderr.write(str(a))
   170             sys.stderr.write(str(a))
       
   171 
       
   172     def flush(self):
       
   173         try:
       
   174             sys.stdout.flush()
       
   175         finally:
       
   176             sys.stderr.flush()
   128 
   177 
   129     def readline(self):
   178     def readline(self):
   130         return sys.stdin.readline()[:-1]
   179         return sys.stdin.readline()[:-1]
   131     def prompt(self, msg, pat, default="y"):
   180     def prompt(self, msg, pat, default="y"):
   132         if not self.interactive: return default
   181         if not self.interactive: return default
   155         editor = (os.environ.get("HGEDITOR") or
   204         editor = (os.environ.get("HGEDITOR") or
   156                   self.config("ui", "editor") or
   205                   self.config("ui", "editor") or
   157                   os.environ.get("EDITOR", "vi"))
   206                   os.environ.get("EDITOR", "vi"))
   158 
   207 
   159         os.environ["HGUSER"] = self.username()
   208         os.environ["HGUSER"] = self.username()
   160         util.system("%s \"%s\"" % (editor, name), errprefix=_("edit failed"))
   209         util.system("%s \"%s\"" % (editor, name),
       
   210                     environ={'HGUSER': self.username()},
       
   211                     onerr=util.Abort, errprefix=_("edit failed"))
   161 
   212 
   162         t = open(name).read()
   213         t = open(name).read()
   163         t = re.sub("(?m)^HG:.*\n", "", t)
   214         t = re.sub("(?m)^HG:.*\n", "", t)
   164 
   215 
   165         os.unlink(name)
   216         os.unlink(name)