Staging
v0.8.1
v0.8.1
https://foss.heptapod.net/mercurial/hgview
Tip revision: c68e0fb6b97cfca3376a8daaf162ce12c4c4fdc9 authored by Julien Cristau on 15 May 2014, 13:25:06 UTC
[debian] prepare release
[debian] prepare release
Tip revision: c68e0fb
config.py
# -*- coding: utf-8 -*-
# Copyright (c) 2003-2012 LOGILAB S.A. (Paris, FRANCE).
# http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation; either version 2 of the License, or (at your option) any later
# version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along with
# this program. If not, see <http://www.gnu.org/licenses/>.
#
# pylint: disable=C0103
"""
Module for managing configuration parameters of hgview using Hg's
configuration system
"""
from functools import partial
import os
import re
import shlex
def cached(meth):
"""
decorator to cache config values once they are read
"""
name = meth.func_name
def wrapper(self, *args, **kw):
if name in self._cache:
return self._cache[name]
res = meth(self, *args, **kw)
self._cache[name] = res
return res
wrapper.__doc__ = meth.__doc__
return wrapper
class HgConfig(object):
"""
Class managing user configuration from hg standard configuration system (.hgrc)
"""
def __init__(self, ui, section="hgview"):
self.ui = ui
self.section = section
self._cache = {}
def _fromconfig(self, name, default):
'''allow per-interface configuration.
look for ``interface.config`` then for ``config`` if the first were not
found'''
out = self.ui.config(self.section,
'.'.join((self.ui.opts.interface, name)),
None)
if out is not None:
return out
return self.ui.config(self.section, name, default)
@cached
def getFancyReplace(self):
r"""
fancyreplace: ``"patt" "repl"`` used to modify description by replacing
``patt`` by ``repl`` using regular expression (``re.sub`` for instance).
Ex: "#(\d+)":"`#\\1 <http://www.logilab.org/ticket/\\1>`_"
"""
data = self._fromconfig('fancyreplace', None)
if data is None:
return data
data = shlex.split(data)
assert len(data) == 2
patt, repl = data
return partial(re.compile(patt).sub, repl)
@cached
def getFont(self, default='Monospace'):
"""
font: default font used to display diffs and files. Use Qt4 format.
"""
return self._fromconfig('font', default)
@cached
def getFontSize(self, default=9):
"""
fontsize: text size in file content viewer
"""
return int(self._fromconfig('fontsize', default))
@cached
def getDescriptionStylePath(self, default=None):
"""
descriptionstylepath:
stylesheet file path used to format the revision description.
You should found a copy of the default style sheet in the documentation
files location of your system (ex. /usr/share/doc/hgview/examples).
"""
return self._fromconfig('descriptionstylepath', default)
@cached
def getDotRadius(self, default=8):
"""
dotradius: radius (in pixels) of the dot in the revision graph
"""
return int(self._fromconfig('dotradius', default))
@cached
def getUsers(self):
"""
users: path of the file holding users configurations
"""
users = {}
aliases = {}
usersfile = self._fromconfig('users', os.path.join('~', ".hgusers"))
cfgfile = None
if usersfile:
try:
cfgfile = open(os.path.expanduser(usersfile))
except IOError:
cfgfile = None
if cfgfile:
currid = None
for line in cfgfile:
line = line.strip()
if not line or line.startswith('#'):
continue
cmd, val = line.split('=', 1)
if cmd == 'id':
currid = val
if currid in users:
print "W: user %s is defined several times" % currid
users[currid] = {'aliases': set()}
elif cmd == "alias":
users[currid]['aliases'].add(val)
if val in aliases:
print ("W: alias %s is used in several "
"user definitions" % val)
aliases[val] = currid
else:
users[currid][cmd] = val
return users, aliases
@cached
def getFileDescriptionView(self, default='persistent'):
"""
descriptionview:
:asfile: compact view with changeset description in the file list
:persistent: persistent view with changeset description always visible (default)
"""
return self._fromconfig('descriptionview', default).lower()
@cached
def getFileDescriptionColor(self, default='magenta'):
"""
filedescriptioncolor: display color of the "description" entry
"""
return self._fromconfig('filedescriptioncolor', default)
@cached
def getFileModifiedColor(self, default='blue'):
"""
filemodifiedcolor: display color of a modified file
"""
return self._fromconfig('filemodifiedcolor', default)
@cached
def getFileRemovedColor(self, default='red'):
"""
fileremovedcolor: display color of a removed file
"""
return self._fromconfig('fileremovededcolor', default)
@cached
def getFileDeletedColor(self, default='darkred'):
"""
filedeletedcolor: display color of a deleted file
"""
return self._fromconfig('filedeletedcolor', default)
@cached
def getFileAddedColor(self, default='green'):
"""
fileaddedcolor: display color of an added file
"""
return self._fromconfig('fileaddedcolor', default)
@cached
def getRowHeight(self, default=20):
"""
rowheight: height (in pixels) on a row of the revision table
"""
return int(self._fromconfig('rowheight', default))
@cached
def getHideFindDelay(self, default=10000):
"""
hidefinddelay: delay (in ms) after which the find bar will disappear
"""
return int(self._fromconfig('hidefindddelay', default))
@cached
def getFillingStep(self, default=300):
"""
fillingstep: number of nodes 'loaded' at a time when updating repo graph log
"""
return int(self._fromconfig('fillingstep', default))
@cached
def getChangelogColumns(self, default=None):
"""
changelogcolumns: ordered list of displayed columns in changelog views;
defaults to ID, Branch, Log, Author, Date, Tags
"""
cols = self._fromconfig('changelogcolumns', default)
if cols is None:
return None
return [col.strip() for col in cols.split(',') if col.strip()]
@cached
def getFilelogColumns(self, default=None):
"""
filelogcolumns: ordered list of displayed columns in filelog views;
defaults to ID, Log, Author, Date
"""
cols = self._fromconfig('filelogcolumns', default)
if cols is None:
return None
return [col.strip() for col in cols.split(',') if col.strip()]
@cached
def getDisplayDiffStats(self, default="yes"):
"""
displaydiffstats: flag controlling the appearance of the
'Diff' column in a revision's file list
"""
val = str(self._fromconfig('displaydiffstats', default))
return val.lower() in ['true', 'yes', '1', 'on']
@cached
def getMaxFileSize(self, default=100000):
"""
maxfilesize: max size of a file for diff computations, display content, etc.
(-1 means no max size)
"""
return int(self._fromconfig('maxfilesize', default))
@cached
def getDiffBGColor(self, default='black'):
"""
diffbgcolor: background color of diffs
"""
return self._fromconfig('diffbgcolor', default)
@cached
def getDiffFGColor(self, default='white'):
"""
difffgcolor: text color of diffs
"""
return self._fromconfig('difffgcolor', default)
@cached
def getDiffPlusColor(self, default='green'):
"""
diffpluscolor: text color of added lines in diffs
"""
return self._fromconfig('diffpluscolor', default)
@cached
def getDiffMinusColor(self, default='red'):
"""
diffminuscolor: text color of removed lines in diffs
"""
return self._fromconfig('diffminuscolor', default)
@cached
def getDiffSectionColor(self, default='magenta'):
"""
diffsectioncolor: text color of new section in diffs
"""
return self._fromconfig('diffsectioncolor', default)
@cached
def getMQFGColor(self, default='#ff8183'):
"""
mqfgcolor: bg color to highlight mq patches
"""
return self._fromconfig('mqfgcolor', default)
@cached
def getMQHideTags(self, default=False):
"""
mqhidetags: hide mq tags
"""
return self._fromconfig('mqhidetags', default)
@cached
def getContentAtStartUp(self, default=True):
"""
contentatstartup: show the content of changeset at startup (bottom part)
"""
return bool(self._fromconfig('contentatstartup', default))
@cached
def getShowHidden(self, default=False):
"""
showhidden: show hidden changeset at startup
"""
return bool(self._fromconfig('showhidden', default))
@cached
def getInterface(self, default=None):
"""
interface: which GUI interface to use (among "qt", "raw" and "curses")
"""
return self.ui.config(self.section, 'interface', default)
@cached
def getNonPublicOnTop(self, default=False):
"""
nonpublicontop: display non public changesets on top of the graph log
(disabled with *show hidden*)
"""
return bool(self._fromconfig('nonpublicontop', default))
@cached
def getShowObsolete(self, default=True):
"""
showobsolete: display obsolete relations
"""
return bool(self._fromconfig('showobsolete', default))
@cached
def getExportTemplate(self):
"""
exporttemplate: template used to serialize changeset metadata
while exporting into the window manager clipboard.
(default to `ui.logtemplate`)
"""
return self._fromconfig('exporttemplate', None) or \
self.ui.config('ui', 'logtemplate')
_HgConfig = HgConfig
# HgConfig is instantiated only once (singleton)
#
# this 'factory' is used to manage this (not using heavy guns of
# metaclass or so)
_hgconfig = None
def HgConfig(ui):
"""Factory to instantiate HgConfig class as a singleton
"""
# pylint: disable=E0102
global _hgconfig
if _hgconfig is None:
_hgconfig = _HgConfig(ui)
return _hgconfig
def get_option_descriptions(rest=False):
"""
Extract options descriptions (docstrings of HgConfig methods)
"""
options = []
for attr in dir(_HgConfig):
if attr.startswith('get'):
meth = getattr(_HgConfig, attr)
if callable(meth):
doc = meth.__doc__
if doc and doc.strip():
doc = doc.strip()
if rest:
doc = re.sub(r' *(?P<arg>.*) *: *(?P<desc>.*)', r'``\1`` \2', doc.strip())
doc = ' '.join(doc.split()) # remove \n and other multiple whitespaces
options.append(doc)
return options