XZise has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/210704

Change subject: [FEAT] Add context to diffs
......................................................................

[FEAT] Add context to diffs

This adds context to printed diffs which can be any number of lines
given.

Change-Id: I6d212fd5912281fb6f0225a7657a1edb56f4b8d9
---
M pywikibot/__init__.py
M pywikibot/diff.py
2 files changed, 59 insertions(+), 7 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/pywikibot/core 
refs/changes/04/210704/1

diff --git a/pywikibot/__init__.py b/pywikibot/__init__.py
index d6ea7ec..fdf2f57 100644
--- a/pywikibot/__init__.py
+++ b/pywikibot/__init__.py
@@ -646,14 +646,14 @@
     config.default_edit_summary = s
 
 
-def showDiff(oldtext, newtext):
+def showDiff(oldtext, newtext, context=0):
     """
     Output a string showing the differences between oldtext and newtext.
 
     The differences are highlighted (only on compatible systems) to show which
     changes were made.
     """
-    PatchManager(oldtext, newtext).print_hunks()
+    PatchManager(oldtext, newtext).print_hunks(context)
 
 
 # Throttle and thread handling
diff --git a/pywikibot/diff.py b/pywikibot/diff.py
index 015dcbd..359b90a 100644
--- a/pywikibot/diff.py
+++ b/pywikibot/diff.py
@@ -72,8 +72,13 @@
 
     def get_header(self):
         """Provide header of unified diff."""
-        a_rng = format_range_unified(*self.a_rng)
-        b_rng = format_range_unified(*self.b_rng)
+        return self.get_header_text(self.a_rng, self.b_rng)
+
+    @staticmethod
+    def get_header_text(a_rng, b_rng):
+        """Provide header for any ranges."""
+        a_rng = format_range_unified(*a_rng)
+        b_rng = format_range_unified(*b_rng)
         return '@@ -{0} +{1} @@\n'.format(a_rng, b_rng)
 
     def create_diff(self):
@@ -244,10 +249,57 @@
 
         return blocks
 
-    def print_hunks(self):
+    def print_hunks(self, context=3):
         """Print the headers and diff texts of all hunks to the output."""
-        for hunk in self.hunks:
-            pywikibot.output(hunk.header + hunk.diff_text)
+        def extend_context(start, end):
+            """Add context lines."""
+            output.extend('  {0}\n'.format(self.a[line_nr].rstrip())
+                          for line_nr in range(start, end))
+
+        if context < 0:
+            raise ValueError('The number of context line may not be negative.')
+
+        if context:
+            # Determine if two hunks are connected by context
+            super_hunk = []
+            super_hunks = [super_hunk]
+            for hunk in self.hunks:
+                # context * 2, because if context is 2 the hunks would be
+                # directly adjacent when 4 lines in between and for anything
+                # below 4 they share lines
+                if (not super_hunk or
+                        super_hunk[-1].a_rng[1] >= hunk.a_rng[0] - context * 
2):
+                    # previous hunk has shared/adjacent context lines
+                    super_hunk += [hunk]
+                else:
+                    super_hunk = [hunk]
+                    super_hunks += [super_hunk]
+        else:
+            super_hunks = [[hunk] for hunk in self.hunks]
+
+        # Verify that it applied all hunks
+        assert(sum(len(super_hunk) for super_hunk in super_hunks) == 
len(self.hunks))
+        output = []
+        for super_hunk in super_hunks:
+            pre_context_end = super_hunk[0].a_rng[0]
+            pre_context_start = max(0, pre_context_end - context)
+            post_context_start = super_hunk[-1].a_rng[1]
+            post_context_end = min(len(self.a), post_context_start + context)
+
+            output += [Hunk.get_header_text(
+                (pre_context_start, post_context_end),
+                (max(0, super_hunk[0].b_rng[0] - context),
+                 min(len(self.b), super_hunk[-1].b_rng[1] + context)))]
+            extend_context(pre_context_start, pre_context_end)
+            previous_hunk = None
+            for hunk in super_hunk:
+                if previous_hunk:
+                    extend_context(previous_hunk.a_rng[1], hunk.a_rng[0])
+                previous_hunk = hunk
+                output += [hunk.diff_text]
+            extend_context(post_context_start, post_context_end)
+            output += ['\n']
+        pywikibot.output(''.join(output)[:-1])
 
     def review_hunks(self):
         """Review hunks."""

-- 
To view, visit https://gerrit.wikimedia.org/r/210704
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I6d212fd5912281fb6f0225a7657a1edb56f4b8d9
Gerrit-PatchSet: 1
Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-Owner: XZise <commodorefabia...@gmx.de>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to