[meld] filediff, diffutil: Scroll all chunks on screen at once (bgo#767981)



commit e9701c5c454233cc8132d3f94692c944684dbc84
Author: Kai Willadsen <kai willadsen gmail com>
Date:   Sun Jun 26 08:25:07 2016 +1000

    filediff, diffutil: Scroll all chunks on screen at once (bgo#767981)
    
    When we're navigating by chunk, our previous code found the correct
    chunk in the focused pane, placed the cursor on the first line and
    scrolled to the cursor. This works in most cases, because our scroll
    alignment handling takes care of the rest. However, for chunks at the
    start or end of the file (especially for very unequal file lengths)
    this means you can end up not actually scrolling the real change on
    screen, for example if you're on the empty side of an insertion chunk.
    
    This change does a slightly inefficient thing and actually gets the
    offsets for all panes of an aligned chunk and scrolls the first line of
    each pane's chunk on screen. We then re-scroll to the cursor, just in
    case our scroll alignment handling has changed the scroll too much; it
    shouldn't, but if it does it would be *really* irritating.

 meld/diffutil.py |    9 +++++++++
 meld/filediff.py |   13 +++++++++++++
 2 files changed, 22 insertions(+), 0 deletions(-)
---
diff --git a/meld/diffutil.py b/meld/diffutil.py
index 2475cf2..193531c 100644
--- a/meld/diffutil.py
+++ b/meld/diffutil.py
@@ -255,6 +255,15 @@ class Differ(GObject.GObject):
                 chunk = self._merge_cache[index][1]
             return chunk
 
+    def get_chunk_starts(self, index):
+        chunks = self._merge_cache[index]
+        chunk_starts = [
+            chunks[0].start_b if chunks[0] else None,
+            chunks[0].start_a if chunks[0] else None,
+            chunks[1].start_b if chunks[1] else None,
+        ]
+        return chunk_starts
+
     def locate_chunk(self, pane, line):
         """Find the index of the chunk which contains line."""
         try:
diff --git a/meld/filediff.py b/meld/filediff.py
index b1e3c59..3d7175d 100644
--- a/meld/filediff.py
+++ b/meld/filediff.py
@@ -473,6 +473,16 @@ class FileDiff(melddoc.MeldDoc, gnomeglade.Component):
         self.actiongroup.get_action("PrevConflict").set_sensitive(have_prev)
         self.actiongroup.get_action("NextConflict").set_sensitive(have_next)
 
+    def scroll_to_chunk_index(self, chunk_index, tolerance):
+        """Scrolls chunks with the given index on screen in all panes"""
+        starts = self.linediffer.get_chunk_starts(chunk_index)
+        for pane, start in enumerate(starts):
+            if start is None:
+                continue
+            buf = self.textbuffer[pane]
+            it = buf.get_iter_at_line(start)
+            self.textview[pane].scroll_to_iter(it, tolerance, True, 0.5, 0.5)
+
     def go_to_chunk(self, target, pane=None, centered=False):
         if target is None:
             return
@@ -491,7 +501,10 @@ class FileDiff(melddoc.MeldDoc, gnomeglade.Component):
         if self.cursor.line != chunk[1]:
             buf.place_cursor(buf.get_iter_at_line(chunk[1]))
 
+        # Scroll all panes to the given chunk, and then ensure that the newly
+        # placed cursor is definitely on-screen.
         tolerance = 0.0 if centered else 0.2
+        self.scroll_to_chunk_index(target, tolerance)
         self.textview[pane].scroll_to_mark(
             buf.get_insert(), tolerance, True, 0.5, 0.5)
 


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