[meld] Move BufferLines shim for line-based buffer access to meldbuffer



commit 122d40e3f89def2f1973c19bff23195f18b5e67e
Author: Kai Willadsen <kai willadsen gmail com>
Date:   Sun Aug 14 07:22:16 2011 +1000

    Move BufferLines shim for line-based buffer access to meldbuffer

 meld/filediff.py   |   87 ++-------------------------------------------------
 meld/meldbuffer.py |   77 +++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 80 insertions(+), 84 deletions(-)
---
diff --git a/meld/filediff.py b/meld/filediff.py
index 81d684e..a6c910d 100644
--- a/meld/filediff.py
+++ b/meld/filediff.py
@@ -77,89 +77,10 @@ class CachedSequenceMatcher(object):
             del self.cache[item[0]]
 
 
-class BufferLines(object):
-    """gtk.TextBuffer shim with line-based access and optional filtering
-
-    This class allows a gtk.TextBuffer to be treated as a list of lines of
-    possibly-filtered text. If no filter is given, the raw output from the
-    gtk.TextBuffer is used.
-
-    The logic here (and in places in FileDiff) requires that Python's
-    unicode splitlines() implementation and gtk.TextBuffer agree on where
-    linebreaks occur. Happily, this is usually the case.
-    """
-
-    def __init__(self, buf, textfilter=None):
-        self.buf = buf
-        if textfilter is not None:
-            self.textfilter = textfilter
-        else:
-            self.textfilter = lambda x: x
-
-    def __getslice__(self, lo, hi):
-        # FIXME: If we ask for arbitrary slices past the end of the buffer,
-        # this will return the last line.
-        start = self.buf.get_iter_at_line_or_eof(lo)
-        end = self.buf.get_iter_at_line_or_eof(hi)
-        txt = unicode(self.buf.get_text(start, end, False), 'utf8')
-
-        filter_txt = self.textfilter(txt)
-        lines = filter_txt.splitlines()
-        ends = filter_txt.splitlines(True)
-
-        # The last line in a gtk.TextBuffer is guaranteed never to end in a
-        # newline. As splitlines() discards an empty line at the end, we need
-        # to artificially add a line if the requested slice is past the end of
-        # the buffer, and the last line in the slice ended in a newline.
-        if hi >= self.buf.get_line_count() and \
-           lo < self.buf.get_line_count() and \
-           (len(lines) == 0 or len(lines[-1]) != len(ends[-1])):
-            lines.append(u"")
-            ends.append(u"")
-
-        hi = self.buf.get_line_count() if hi == sys.maxint else hi
-        if hi - lo != len(lines):
-            # These codepoints are considered line breaks by Python, but not
-            # by GtkTextStore.
-            additional_breaks = set((u'\x0c', u'\x85'))
-            i = 0
-            while i < len(ends):
-                line, end = lines[i], ends[i]
-                # It's possible that the last line in a file would end in a
-                # line break character, which requires no joining.
-                if end and end[-1] in additional_breaks and \
-                   (not line or line[-1] not in additional_breaks):
-                    assert len(ends) >= i + 1
-                    lines[i:i + 2] = [line + end[-1] + lines[i + 1]]
-                    ends[i:i + 2] = [end + ends[i + 1]]
-                i += 1
-
-        return lines
-
-    def __getitem__(self, i):
-        if i >= len(self):
-            raise IndexError
-        line_start = self.buf.get_iter_at_line_or_eof(i)
-        line_end = line_start.copy()
-        if not line_end.ends_line():
-            line_end.forward_to_line_end()
-        txt = self.buf.get_text(line_start, line_end, False)
-        return unicode(self.textfilter(txt), 'utf8')
-
-    def __len__(self):
-        return self.buf.get_line_count()
-
-
-################################################################################
-#
-# FileDiff
-#
-################################################################################
-
 MASK_SHIFT, MASK_CTRL = 1, 2
-
 MODE_REPLACE, MODE_DELETE, MODE_INSERT = 0, 1, 2
 
+
 class CursorDetails(object):
     __slots__ = ("pane", "pos", "line", "offset", "chunk", "prev", "next",
                  "prev_conflict", "next_conflict")
@@ -236,12 +157,12 @@ class FileDiff(melddoc.MeldDoc, gnomeglade.Component):
         self.textview_focussed = None
         self.textview_overwrite_handlers = [ t.connect("toggle-overwrite", self.on_textview_toggle_overwrite) for t in self.textview ]
         self.textbuffer = [v.get_buffer() for v in self.textview]
-        self.buffer_texts = [BufferLines(b) for b in self.textbuffer]
+        self.buffer_texts = [meldbuffer.BufferLines(b) for b in self.textbuffer]
         self.text_filters = []
         self.create_text_filters()
         app.connect("text-filters-changed", self.on_text_filters_changed)
-        self.buffer_filtered = [BufferLines(b, self._filter_text) for
-                                b in self.textbuffer]
+        self.buffer_filtered = [meldbuffer.BufferLines(b, self._filter_text)
+                                for b in self.textbuffer]
         for (i, w) in enumerate(self.scrolledwindow):
             w.get_vadjustment().connect("value-changed", self._sync_vscroll, i)
             w.get_hadjustment().connect("value-changed", self._sync_hscroll)
diff --git a/meld/meldbuffer.py b/meld/meldbuffer.py
index 66ecb79..fb1a35d 100644
--- a/meld/meldbuffer.py
+++ b/meld/meldbuffer.py
@@ -1,5 +1,5 @@
 ### Copyright (C) 2002-2006 Stephen Kennedy <stevek gnome org>
-### Copyright (C) 2009-2010 Kai Willadsen <kai willadsen gmail com>
+### Copyright (C) 2009-2011 Kai Willadsen <kai willadsen gmail com>
 
 ### 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
@@ -15,6 +15,8 @@
 ### along with this program; if not, write to the Free Software
 ### Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
+import sys
+
 import meld.util.sourceviewer
 
 
@@ -63,3 +65,76 @@ class MeldBufferData(object):
         self.encoding = None
         self.newlines = None
 
+
+class BufferLines(object):
+    """gtk.TextBuffer shim with line-based access and optional filtering
+
+    This class allows a gtk.TextBuffer to be treated as a list of lines of
+    possibly-filtered text. If no filter is given, the raw output from the
+    gtk.TextBuffer is used.
+
+    The logic here (and in places in FileDiff) requires that Python's
+    unicode splitlines() implementation and gtk.TextBuffer agree on where
+    linebreaks occur. Happily, this is usually the case.
+    """
+
+    def __init__(self, buf, textfilter=None):
+        self.buf = buf
+        if textfilter is not None:
+            self.textfilter = textfilter
+        else:
+            self.textfilter = lambda x: x
+
+    def __getslice__(self, lo, hi):
+        # FIXME: If we ask for arbitrary slices past the end of the buffer,
+        # this will return the last line.
+        start = self.buf.get_iter_at_line_or_eof(lo)
+        end = self.buf.get_iter_at_line_or_eof(hi)
+        txt = unicode(self.buf.get_text(start, end, False), 'utf8')
+
+        filter_txt = self.textfilter(txt)
+        lines = filter_txt.splitlines()
+        ends = filter_txt.splitlines(True)
+
+        # The last line in a gtk.TextBuffer is guaranteed never to end in a
+        # newline. As splitlines() discards an empty line at the end, we need
+        # to artificially add a line if the requested slice is past the end of
+        # the buffer, and the last line in the slice ended in a newline.
+        if hi >= self.buf.get_line_count() and \
+           lo < self.buf.get_line_count() and \
+           (len(lines) == 0 or len(lines[-1]) != len(ends[-1])):
+            lines.append(u"")
+            ends.append(u"")
+
+        hi = self.buf.get_line_count() if hi == sys.maxint else hi
+        if hi - lo != len(lines):
+            # These codepoints are considered line breaks by Python, but not
+            # by GtkTextStore.
+            additional_breaks = set((u'\x0c', u'\x85'))
+            i = 0
+            while i < len(ends):
+                line, end = lines[i], ends[i]
+                # It's possible that the last line in a file would end in a
+                # line break character, which requires no joining.
+                if end and end[-1] in additional_breaks and \
+                   (not line or line[-1] not in additional_breaks):
+                    assert len(ends) >= i + 1
+                    lines[i:i + 2] = [line + end[-1] + lines[i + 1]]
+                    ends[i:i + 2] = [end + ends[i + 1]]
+                i += 1
+
+        return lines
+
+    def __getitem__(self, i):
+        if i >= len(self):
+            raise IndexError
+        line_start = self.buf.get_iter_at_line_or_eof(i)
+        line_end = line_start.copy()
+        if not line_end.ends_line():
+            line_end.forward_to_line_end()
+        txt = self.buf.get_text(line_start, line_end, False)
+        return unicode(self.textfilter(txt), 'utf8')
+
+    def __len__(self):
+        return self.buf.get_line_count()
+



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