[meld] filediff: Move auto-merge functionality to main FileDiff class



commit d926caa0562acaafb2afffa5f0cad149017fec82
Author: Kai Willadsen <kai willadsen gmail com>
Date:   Fri Nov 1 07:28:25 2019 +1000

    filediff: Move auto-merge functionality to main FileDiff class
    
    This isn't ideal logic-wise, but it's the only sane workaround I can
    think of to deal with the GtkTemplate support not supporting subclasses
    of templated widgets (https://github.com/yousseb/meld/issues/97).
    
    The actual logic separating the two cases isn't much, so even though I
    don't like adding the concept of a "mode" to `FileDiff`, this should be
    basically fine.

 meld/const.py      |  5 +++++
 meld/filediff.py   | 46 +++++++++++++++++++++++++++++++++++++++++-----
 meld/filemerge.py  | 46 ----------------------------------------------
 meld/meldwindow.py | 10 +++++++---
 meld/meson.build   |  1 -
 po/POTFILES.in     |  1 -
 6 files changed, 53 insertions(+), 56 deletions(-)
---
diff --git a/meld/const.py b/meld/const.py
index c5ec9afd..2b5ee28c 100644
--- a/meld/const.py
+++ b/meld/const.py
@@ -21,6 +21,11 @@ class ChunkAction(enum.Enum):
     copy_up = 'copy_up'
 
 
+class FileComparisonMode(enum.Enum):
+    AutoMerge = 'AutoMerge'
+    Compare = 'Compare'
+
+
 NEWLINES = {
     GtkSource.NewlineType.LF: ('\n', _("UNIX (LF)")),
     GtkSource.NewlineType.CR_LF: ('\r\n', _("DOS/Windows (CR-LF)")),
diff --git a/meld/filediff.py b/meld/filediff.py
index 717c0a14..90de6381 100644
--- a/meld/filediff.py
+++ b/meld/filediff.py
@@ -18,6 +18,7 @@ import copy
 import functools
 import logging
 import math
+from typing import Type
 
 from gi.repository import Gdk, Gio, GLib, GObject, Gtk, GtkSource
 
@@ -29,12 +30,13 @@ from meld.const import (
     TEXT_FILTER_ACTION_FORMAT,
     ActionMode,
     ChunkAction,
+    FileComparisonMode,
 )
 from meld.gutterrendererchunk import GutterRendererChunkLines
 from meld.iohelpers import prompt_save_filename
 from meld.matchers.diffutil import Differ, merged_chunk_order
 from meld.matchers.helpers import CachedSequenceMatcher
-from meld.matchers.merge import Merger
+from meld.matchers.merge import AutoMergeDiffer, Merger
 from meld.meldbuffer import (
     BufferDeletionAction,
     BufferInsertionAction,
@@ -188,7 +190,8 @@ class FileDiff(Gtk.VBox, MeldDoc):
     vbox1 = Gtk.Template.Child()
     vbox2 = Gtk.Template.Child()
 
-    differ = Differ
+    differ: Type[Differ]
+    comparison_mode: FileComparisonMode
 
     keylookup = {
         Gdk.KEY_Shift_L: MASK_SHIFT,
@@ -220,7 +223,12 @@ class FileDiff(Gtk.VBox, MeldDoc):
         default=False,
     )
 
-    def __init__(self, num_panes):
+    def __init__(
+        self,
+        num_panes,
+        *,
+        comparison_mode: FileComparisonMode = FileComparisonMode.Compare,
+    ):
         super().__init__()
         # FIXME:
         # This unimaginable hack exists because GObject (or GTK+?)
@@ -244,6 +252,12 @@ class FileDiff(Gtk.VBox, MeldDoc):
         ]
         map_widgets_into_lists(self, widget_lists)
 
+        self.comparison_mode = comparison_mode
+        if comparison_mode == FileComparisonMode.AutoMerge:
+            self.differ = AutoMergeDiffer
+        else:
+            self.differ = Differ
+
         self.warned_bad_comparison = False
         self._keymask = 0
         self.meta = {}
@@ -563,6 +577,10 @@ class FileDiff(Gtk.VBox, MeldDoc):
                 "notify::cursor-position", self.on_cursor_position_changed)
             buf.handlers = id0, id1, id2, id3, id4
 
+        if self.comparison_mode == FileComparisonMode.AutoMerge:
+            self.textview[0].set_editable(0)
+            self.textview[2].set_editable(0)
+
     def bind_adapt_cursor_position(self, binding, from_value):
         buf = binding.get_source()
         textview = self.textview[self.textbuffer.index(buf)]
@@ -1429,7 +1447,13 @@ class FileDiff(Gtk.VBox, MeldDoc):
 
     def get_comparison(self):
         uris = [b.data.gfile for b in self.textbuffer[:self.num_panes]]
-        return RecentType.File, uris
+
+        if self.comparison_mode == FileComparisonMode.AutoMerge:
+            comparison_type = RecentType.Merge
+        else:
+            comparison_type = RecentType.File
+
+        return comparison_type, uris
 
     def file_loaded(self, loader, result, user_data):
 
@@ -1488,7 +1512,19 @@ class FileDiff(Gtk.VBox, MeldDoc):
             self.scheduler.add_task(self._compare_files_internal())
 
     def _merge_files(self):
-        yield 1
+        if self.comparison_mode == FileComparisonMode.AutoMerge:
+            yield _("[%s] Merging files") % self.label_text
+            merger = Merger()
+            step = merger.initialize(self.buffer_filtered, self.buffer_texts)
+            while next(step) is None:
+                yield 1
+            for merged_text in merger.merge_3_files():
+                yield 1
+            self.linediffer.unresolved = merger.unresolved
+            self.textbuffer[1].set_text(merged_text)
+            self.recompute_label()
+        else:
+            yield 1
 
     def _diff_files(self, refresh=False):
         yield _("[%s] Computing differences") % self.label_text
diff --git a/meld/meldwindow.py b/meld/meldwindow.py
index 00c4adf9..e3b46974 100644
--- a/meld/meldwindow.py
+++ b/meld/meldwindow.py
@@ -23,10 +23,13 @@ from gi.repository import Gdk, Gio, GLib, Gtk
 import meld.ui.gladesupport  # noqa: F401
 import meld.ui.util
 from meld.conf import _
-from meld.const import FILE_FILTER_ACTION_FORMAT, TEXT_FILTER_ACTION_FORMAT
+from meld.const import (
+    FILE_FILTER_ACTION_FORMAT,
+    TEXT_FILTER_ACTION_FORMAT,
+    FileComparisonMode,
+)
 from meld.dirdiff import DirDiff
 from meld.filediff import FileDiff
-from meld.filemerge import FileMerge
 from meld.melddoc import ComparisonState, MeldDoc
 from meld.menuhelpers import replace_menu_section
 from meld.newdifftab import NewDiffTab
@@ -372,7 +375,8 @@ class MeldWindow(Gtk.ApplicationWindow):
             raise ValueError(
                 _("Need three files to auto-merge, got: %r") %
                 [f.get_parse_name() for f in gfiles])
-        doc = FileMerge(len(gfiles))
+        doc = FileDiff(
+            len(gfiles), comparison_mode=FileComparisonMode.AutoMerge)
         self._append_page(doc)
         doc.set_files(gfiles)
         if merge_output is not None:
diff --git a/meld/meson.build b/meld/meson.build
index a6aa6e12..ae3c2ee6 100644
--- a/meld/meson.build
+++ b/meld/meson.build
@@ -14,7 +14,6 @@ folders = {
         'diffgrid.py',
         'dirdiff.py',
         'filediff.py',
-        'filemerge.py',
         'filters.py',
         'gutterrendererchunk.py',
         'iohelpers.py',
diff --git a/po/POTFILES.in b/po/POTFILES.in
index fb03d7f2..952e92b2 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -36,7 +36,6 @@ meld/actiongutter.py
 meld/const.py
 meld/dirdiff.py
 meld/filediff.py
-meld/filemerge.py
 meld/gutterrendererchunk.py
 meld/iohelpers.py
 meld/meldapp.py


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