[meld] New text-filter mechanism to prevent interference of multiple filters



commit eee58a571b1dc75f0d85d266aecec48a52df38c3
Author: David Rabel <David Rabel NoreSoft com>
Date:   Sun Nov 29 14:15:13 2015 +0100

    New text-filter mechanism to prevent interference of multiple filters
    
    By now, each text filter cuts out the out-filtered parts, so all following
    filters operate on the already modified text. This leads to mistakes.
    
    The new mechanism first stores, which parts have to be cut out for
    each filter, merges these ranges and in the end actualy cuts the text.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=758478

 meld/filediff.py |   47 ++++++++++++++++++-----------------------------
 1 files changed, 18 insertions(+), 29 deletions(-)
---
diff --git a/meld/filediff.py b/meld/filediff.py
index c2117a8..dafa69b 100644
--- a/meld/filediff.py
+++ b/meld/filediff.py
@@ -762,41 +762,29 @@ class FileDiff(melddoc.MeldDoc, gnomeglade.Component):
                                                 None, True)
             self.queue_draw()
 
-    def _filter_text(self, txt, buf, start_iter, end_iter):
+    def _filter_text(self, txt, buf, txt_start_iter, txt_end_iter):
         dimmed_tag = buf.get_tag_table().lookup("dimmed")
-        buf.remove_tag(dimmed_tag, start_iter, end_iter)
+        buf.remove_tag(dimmed_tag, txt_start_iter, txt_end_iter)
 
-        def killit(m):
-
-            def get_match_iters(match, match_index=0):
-                start = start_iter.copy()
-                end = start_iter.copy()
-                start.forward_chars(match.start(match_index))
-                end.forward_chars(match.end(match_index))
-                return start, end
-
-            assert m.group().count("\n") == 0
-            if len(m.groups()):
-                s = m.group()
-                for i in reversed(range(1, len(m.groups())+1)):
-                    g = m.group(i)
-                    if g:
-                        start, end = get_match_iters(m, i)
-                        buf.apply_tag(dimmed_tag, start, end)
+        try:
+            filter_ranges = []
 
-                        s = s[:m.start(i)-m.start()]+s[m.end(i)-m.start():]
+            for filt in self.text_filters:
+                if filt.active:
+                    for match in filt.filter.finditer(txt):
+                        filter_ranges.append(match.span())
 
-                return s
-            else:
-                start, end = get_match_iters(m)
-                buf.apply_tag(dimmed_tag, start, end)
+            filter_ranges = misc.merge_intervals(filter_ranges)
 
-                return ""
+            for (start, end) in reversed(filter_ranges):
+                assert txt[start:end].count("\n") == 0
+                txt = txt[:start] + txt[end:]
+                start_iter = txt_start_iter.copy()
+                start_iter.forward_chars(start)
+                end_iter = txt_start_iter.copy()
+                end_iter.forward_chars(end)
+                buf.apply_tag(dimmed_tag, start_iter, end_iter)
 
-        try:
-            for filt in self.text_filters:
-                if filt.active:
-                    txt = filt.filter.sub(killit, txt)
         except AssertionError:
             if not self.warned_bad_comparison:
                 misc.error_dialog(
@@ -807,6 +795,7 @@ class FileDiff(melddoc.MeldDoc, gnomeglade.Component):
                         u"not be accurate.") % filt.label,
                 )
                 self.warned_bad_comparison = True
+
         return txt
 
     def after_text_insert_text(self, buf, it, newtext, textlen):


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]