Rev 234: Merge support for color diff configuration from Adeodato. in file:///data/jelmer/bzr-gtk/trunk/
Jelmer Vernooij
jelmer at samba.org
Tue Jul 17 00:25:56 BST 2007
At file:///data/jelmer/bzr-gtk/trunk/
------------------------------------------------------------
revno: 234
revision-id: jelmer at samba.org-20070716232554-xq4mypahdh0pv0tn
parent: jelmer at samba.org-20070715221409-7uh7dx43o2e6fyur
parent: dato at net.com.org.es-20070716102735-kyxamu7okv8gf88a
committer: Jelmer Vernooij <jelmer at samba.org>
branch nick: trunk
timestamp: Tue 2007-07-17 01:25:54 +0200
message:
Merge support for color diff configuration from Adeodato.
added:
tests/test_diff.py test_diff.py-20070716102329-o1qvzd7v2fg9lyag-1
modified:
NEWS news-20070325173539-3va57o99cz3o57xe-1
README README-20051017002359-1debfab4c21afd00
diff.py diffwin.py-20051017070234-cb5c6dc4960142f5
tests/__init__.py __init__.py-20070201155018-mi2dl3spgj7fqdum-1
------------------------------------------------------------
revno: 232.1.4
revision-id: dato at net.com.org.es-20070716102735-kyxamu7okv8gf88a
parent: dato at net.com.org.es-20070705195044-rcrj8f27i386cvrv
committer: Adeodato Simó <dato at net.com.org.es>
branch nick: bzr-gtk
timestamp: Mon 2007-07-16 12:27:35 +0200
message:
Add a test for parse_colordiffrc, and fix the function to handle empty lines.
------------------------------------------------------------
revno: 232.1.3
revision-id: dato at net.com.org.es-20070705195044-rcrj8f27i386cvrv
parent: dato at net.com.org.es-20070705193512-23ze1o604e874bd6
committer: Adeodato Simó <dato at net.com.org.es>
branch nick: bzr-gtk
timestamp: Thu 2007-07-05 21:50:44 +0200
message:
Support setting diff colors from gedit's syntax highlighting config too.
------------------------------------------------------------
revno: 232.1.2
revision-id: dato at net.com.org.es-20070705193512-23ze1o604e874bd6
parent: dato at net.com.org.es-20070704165707-2w5sb6l8c8zis7f6
committer: Adeodato Simó <dato at net.com.org.es>
branch nick: bzr-gtk
timestamp: Thu 2007-07-05 21:35:12 +0200
message:
Rename apply_colordiffrc to apply_colordiff_colors, improve docstring.
------------------------------------------------------------
revno: 232.1.1
revision-id: dato at net.com.org.es-20070704165707-2w5sb6l8c8zis7f6
parent: jelmer at samba.org-20070715183952-y939vtf6e0skzihm
committer: Adeodato Simó <dato at net.com.org.es>
branch nick: bzr-gtk
timestamp: Wed 2007-07-04 18:57:07 +0200
message:
Read ~/.colordiffrc to set colors in the diff window.
=== added file 'tests/test_diff.py'
--- a/tests/test_diff.py 1970-01-01 00:00:00 +0000
+++ b/tests/test_diff.py 2007-07-16 10:27:35 +0000
@@ -0,0 +1,39 @@
+# -*- coding: utf-8 -*-
+# Copyright (C) 2007 Adeodato Simó <dato at net.com.org.es>
+#
+# 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, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+from cStringIO import StringIO
+
+from bzrlib.plugins.gtk.diff import DiffWindow
+from bzrlib.tests import TestCase
+
+class TestDiffWindow(TestCase):
+ def test_parse_colordiffrc(self):
+ colordiffrc = '''\
+newtext=blue
+oldtext = Red
+# now a comment and a blank line
+
+diffstuff = #ffff00
+ # another comment preceded by whitespace
+'''
+ colors = {
+ 'newtext': 'blue',
+ 'oldtext': 'Red',
+ 'diffstuff': '#ffff00',
+ }
+ parsed_colors = DiffWindow.parse_colordiffrc(StringIO(colordiffrc))
+ self.assertEqual(colors, parsed_colors)
=== modified file 'NEWS'
--- a/NEWS 2007-07-15 16:02:01 +0000
+++ b/NEWS 2007-07-05 19:50:44 +0000
@@ -1,3 +1,12 @@
+0.19.0 UNRELEASED
+
+ FEATURES
+
+ * Add support for customizing colors in the diff window via ~/.colordiffrc
+ or gedit's syntax highlighting configuration. See README file for details.
+ (Adeodato Simó)
+
+
0.18.0 2007-07-14
FEATURES
=== modified file 'README'
--- a/README 2007-07-03 22:19:26 +0000
+++ b/README 2007-07-05 19:50:44 +0000
@@ -87,6 +87,26 @@
lines 2 hours old may be orange. Highlighting can be turned off with --plain
if overwhelming.
+Usage - diff window
+-------------------
+
+If you have the gtksourceview python bindings installed, the diff window
+will have syntax highlighting. If the python GConf bindings are installed,
+the colors will be read from gedit's syntax highlighting configuration
+for the "Diff" language.
+
+Afterwards, colors from the ~/.colordiffrc file will be read, and will
+override gedit's. Since that file may be written for a dark background
+environment, the file ~/.colordiffrc.bzr-gtk can be used to override
+some values.
+
+Because gtksourceview is more configurable that colordiff, in addition
+to the 'oldtext', 'newtext', and 'diffstuff' keys, the following keys
+are also accepted: 'location', 'file', 'specialcase'.
+
+Colors can be specified with names (valid names are those in the
+/usr/share/X11/rgb.txt file), or with a #RRGGBB notation.
+
Install on Windows
------------------
=== modified file 'diff.py'
--- a/diff.py 2007-02-03 13:01:12 +0000
+++ b/diff.py 2007-07-16 10:27:35 +0000
@@ -14,6 +14,8 @@
import gtk
import pango
+import os
+import re
import sys
try:
@@ -21,11 +23,17 @@
have_gtksourceview = True
except ImportError:
have_gtksourceview = False
+try:
+ import gconf
+ have_gconf = True
+except ImportError:
+ have_gconf = False
import bzrlib
from bzrlib.diff import show_diff_trees
from bzrlib.errors import NoSuchFile
+from bzrlib.trace import warning
class DiffWindow(gtk.Window):
@@ -92,6 +100,9 @@
self.buffer = gtksourceview.SourceBuffer()
slm = gtksourceview.SourceLanguagesManager()
gsl = slm.get_language_from_mime_type("text/x-patch")
+ if have_gconf:
+ self.apply_gedit_colors(gsl)
+ self.apply_colordiff_colors(gsl)
self.buffer.set_language(gsl)
self.buffer.set_highlight(True)
@@ -167,3 +178,140 @@
s = StringIO()
show_diff_trees(self.parent_tree, self.rev_tree, s, specific_files)
self.buffer.set_text(s.getvalue().decode(sys.getdefaultencoding(), 'replace'))
+
+ @staticmethod
+ def apply_gedit_colors(lang):
+ """Set style for lang to that specified in gedit configuration.
+
+ This method needs the gconf module.
+
+ :param lang: a gtksourceview.SourceLanguage object.
+ """
+ GEDIT_SYNTAX_PATH = '/apps/gedit-2/preferences/syntax_highlighting'
+ GEDIT_LANG_PATH = GEDIT_SYNTAX_PATH + '/' + lang.get_id()
+
+ client = gconf.client_get_default()
+ client.add_dir(GEDIT_LANG_PATH, gconf.CLIENT_PRELOAD_NONE)
+
+ for tag in lang.get_tags():
+ tag_id = tag.get_id()
+ gconf_key = GEDIT_LANG_PATH + '/' + tag_id
+ style_string = client.get_string(gconf_key)
+
+ if style_string is None:
+ continue
+
+ # function to get a bool from a string that's either '0' or '1'
+ string_bool = lambda x: bool(int(x))
+
+ # style_string is a string like "2/#FFCCAA/#000000/0/1/0/0"
+ # values are: mask, fg, bg, italic, bold, underline, strike
+ # this packs them into (str_value, attr_name, conv_func) tuples
+ items = zip(style_string.split('/'), ['mask', 'foreground',
+ 'background', 'italic', 'bold', 'underline', 'strikethrough' ],
+ [ int, gtk.gdk.color_parse, gtk.gdk.color_parse, string_bool,
+ string_bool, string_bool, string_bool ]
+ )
+
+ style = gtksourceview.SourceTagStyle()
+
+ # XXX The mask attribute controls whether the present values of
+ # foreground and background color should in fact be used. Ideally
+ # (and that's what gedit does), one could set all three attributes,
+ # and let the TagStyle object figure out which colors to use.
+ # However, in the GtkSourceview python bindings, the mask attribute
+ # is read-only, and it's derived instead from the colors being
+ # set or not. This means that we have to sometimes refrain from
+ # setting fg or bg colors, depending on the value of the mask.
+ # This code could go away if mask were writable.
+ mask = int(items[0][0])
+ if not (mask & 1): # GTK_SOURCE_TAG_STYLE_USE_BACKGROUND
+ items[2:3] = []
+ if not (mask & 2): # GTK_SOURCE_TAG_STYLE_USE_FOREGROUND
+ items[1:2] = []
+ items[0:1] = [] # skip the mask unconditionally
+
+ for value, attr, func in items:
+ try:
+ value = func(value)
+ except ValueError:
+ warning('gconf key %s contains an invalid value: %s'
+ % gconf_key, value)
+ else:
+ setattr(style, attr, value)
+
+ lang.set_tag_style(tag_id, style)
+
+ @staticmethod
+ def apply_colordiff_colors(lang):
+ """Set style colors for lang using the colordiff configuration file.
+
+ Both ~/.colordiffrc and ~/.colordiffrc.bzr-gtk are read.
+
+ :param lang: a "Diff" gtksourceview.SourceLanguage object.
+ """
+ colors = {}
+
+ for f in ('~/.colordiffrc', '~/.colordiffrc.bzr-gtk'):
+ f = os.path.expanduser(f)
+ if os.path.exists(f):
+ try:
+ f = file(f)
+ except IOError, e:
+ warning('could not open file %s: %s' % (f, str(e)))
+ else:
+ colors.update(DiffWindow.parse_colordiffrc(f))
+ f.close()
+
+ if not colors:
+ # ~/.colordiffrc does not exist
+ return
+
+ mapping = {
+ # map GtkSourceView tags to colordiff names
+ # since GSV is richer, accept new names for extra bits,
+ # defaulting to old names if they're not present
+ 'Added at 32@line': ['newtext'],
+ 'Removed at 32@line': ['oldtext'],
+ 'Location': ['location', 'diffstuff'],
+ 'Diff at 32@file': ['file', 'diffstuff'],
+ 'Special at 32@case': ['specialcase', 'diffstuff'],
+ }
+
+ for tag in lang.get_tags():
+ tag_id = tag.get_id()
+ keys = mapping.get(tag_id, [])
+ color = None
+
+ for key in keys:
+ color = colors.get(key, None)
+ if color is not None:
+ break
+
+ if color is None:
+ continue
+
+ style = gtksourceview.SourceTagStyle()
+ try:
+ style.foreground = gtk.gdk.color_parse(color)
+ except ValueError:
+ warning('not a valid color: %s' % color)
+ else:
+ lang.set_tag_style(tag_id, style)
+
+ @staticmethod
+ def parse_colordiffrc(fileobj):
+ """Parse fileobj as a colordiff configuration file.
+
+ :return: A dict with the key -> value pairs.
+ """
+ colors = {}
+ for line in fileobj:
+ if re.match(r'^\s*#', line):
+ continue
+ if '=' not in line:
+ continue
+ key, val = line.split('=', 1)
+ colors[key.strip()] = val.strip()
+ return colors
+
=== modified file 'tests/__init__.py'
--- a/tests/__init__.py 2007-05-19 16:15:11 +0000
+++ b/tests/__init__.py 2007-07-16 10:27:35 +0000
@@ -25,6 +25,7 @@
loader = TestUtil.TestLoader()
testmod_names = [
+ 'test_diff',
'test_preferences',
'test_history',
'test_viz'
More information about the bazaar-commits
mailing list