[meld: 5/5] Merge branch 'hellyguo/meld-master'




commit c941727d01c0e5c5da78f06a8ade2ad107d688de
Merge: edfcce91 6137c625
Author: Kai Willadsen <kai willadsen gmail com>
Date:   Sun Apr 10 09:15:35 2022 +1000

    Merge branch 'hellyguo/meld-master'
    
    [feat]add a new feature: switch the panes
    
    See merge request !81

 meld/accelerators.py               | 2 ++
 meld/dirdiff.py                    | 6 ++++++
 meld/filediff.py                   | 7 +++++++
 meld/resources/gtk/help-overlay.ui | 7 +++++++
 meld/resources/gtk/menus.ui        | 7 +++++++
 5 files changed, 29 insertions(+)
---
diff --cc meld/filediff.py
index 4b5376cb,651d8c0a..b167449c
--- a/meld/filediff.py
+++ b/meld/filediff.py
@@@ -2539,137 -2471,10 +2541,142 @@@ class FileDiff(Gtk.VBox, MeldDoc)
                  mgr.clear()
          self.refresh_comparison()
  
+     def action_swap(self, *args):
+         buffer0 = self.textbuffer[0]
+         buffer1 = self.textbuffer[1]
+         self.set_files([buffer1.data.gfile, buffer0.data.gfile])
+ 
  
  FileDiff.set_css_name('meld-file-diff')
 +
 +
 +class SyncpointAction(Enum):
 +    # A dangling syncpoint can be moved to the line
 +    MOVE = "move"
 +    # A dangling syncpoint sits can be remove from this line
 +    DELETE = "delete"
 +    # A syncpoint can be added to this line to match existing ones
 +    # in other panes
 +    MATCH = "match"
 +    # A new, dangling syncpoint can be added to this line
 +    ADD = "add"
 +    # No syncpoint-related action can be taken on this line
 +    DISABLED = "disabled"
 +
 +
 +class Syncpoints:
 +    def __init__(self, num_panes: int, comparator):
 +        self._num_panes = num_panes
 +        self._points = [[] for _i in range(0, num_panes)]
 +        self._comparator = comparator
 +
 +    def add(self, pane_idx: int, point):
 +        pane_state = self._pane_state(pane_idx)
 +
 +        if pane_state == self.PaneState.DANGLING:
 +            self._points[pane_idx].pop()
 +
 +        self._points[pane_idx].append(point)
 +
 +        lengths = set(len(p) for p in self._points)
 +
 +        if len(lengths) == 1:
 +            for (i, p) in enumerate(self._points):
 +                p.sort(key=lambda point: self._comparator(i, point))
 +
 +    def remove(self, pane_idx: int, cursor_point):
 +        cursor_key = self._comparator(pane_idx, cursor_point)
 +
 +        index = -1
 +
 +        for (i, point) in enumerate(self._points[pane_idx]):
 +            if self._comparator(pane_idx, point) == cursor_key:
 +                index = i
 +                break
 +
 +        assert index is not None
 +
 +        pane_state = self._pane_state(pane_idx)
 +
 +        assert pane_state != self.PaneState.SHORT
 +
 +        if pane_state == self.PaneState.MATCHED:
 +            for pane in self._points:
 +                pane.pop(index)
 +        elif pane_state == self.PaneState.DANGLING:
 +            self._points[pane_idx].pop()
 +
 +    def clear(self):
 +        self._points = [[] for _i in range(0, self._num_panes)]
 +
 +    def points(self, pane_idx: int):
 +        return self._points[pane_idx].copy()
 +
 +    def valid_points(self):
 +        num_matched = min(len(p) for p in self._points)
 +
 +        if not num_matched:
 +            return []
 +
 +        matched = [p[:num_matched] for p in self._points]
 +
 +        return [
 +            tuple(matched_point[i] for matched_point in matched)
 +            for i in range(0, num_matched)
 +        ]
 +
 +    def _pane_state(self, pane_idx: int):
 +        lengths = set(len(points) for points in self._points)
 +
 +        if len(lengths) == 1:
 +            return self.PaneState.MATCHED
 +
 +        if len(self._points[pane_idx]) == min(lengths):
 +            return self.PaneState.SHORT
 +        else:
 +            return self.PaneState.DANGLING
 +
 +    def action(self, pane_idx: int, get_mark):
 +        state = self._pane_state(pane_idx)
 +
 +        if state == self.PaneState.SHORT:
 +            return SyncpointAction.MATCH
 +
 +        target = self._comparator(pane_idx, get_mark())
 +
 +        points = self._points[pane_idx]
 +
 +        if state == self.PaneState.MATCHED:
 +            is_syncpoint = any(
 +                self._comparator(pane_idx, point) == target
 +                for point in points
 +            )
 +
 +            if is_syncpoint:
 +                return SyncpointAction.DELETE
 +            else:
 +                return SyncpointAction.ADD
 +
 +        # state == DANGLING
 +        if target == self._comparator(pane_idx, points[-1]):
 +            return SyncpointAction.DELETE
 +
 +        is_syncpoint = any(
 +            self._comparator(pane_idx, point) == target
 +            for point in points
 +        )
 +
 +        if is_syncpoint:
 +            return SyncpointAction.DISABLED
 +        else:
 +            return SyncpointAction.MOVE
 +
 +    class PaneState(Enum):
 +        # The state of a pane with all its syncpoints matched
 +        MATCHED = "matched"
 +        # The state of a pane waiting to be matched to existing syncpoints
 +        # in other panes
 +        SHORT = "short"
 +        # The state of a pane with a dangling syncpoint, not yet matched
 +        # across all panes
 +        DANGLING = "DANGLING"


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