]> git.neil.brown.name Git - edlib.git/commitdiff
mergeview: handle mode-swap-mark
authorNeilBrown <neil@brown.name>
Tue, 13 Jun 2023 22:08:20 +0000 (08:08 +1000)
committerNeilBrown <neil@brown.name>
Wed, 28 Jun 2023 07:51:41 +0000 (17:51 +1000)
Intercept the swap-mark command and instead cycle among corresponding
places in the three branches.

Signed-off-by: NeilBrown <neil@brown.name>
DOC/TODO.md
python/lib-mergeview.py

index e2baed32a7c3407e47bb9d032d877795c4a57428..0a33c44bbbedf1c4f0929e475f075a8917e54f0f 100644 (file)
@@ -241,7 +241,7 @@ Module features
 - [X] Capture '-<' and '->' on the marker lines to move the orig section
       w.r.t surrounding text, or to prune the before and after sections.
 - [ ] Consider what else can be done with < and > on other markers.
-- [ ] Capture :CX:C-x command to cycle through matching places in the
+- [X] Capture :CX:C-x command to cycle through matching places in the
       three branches.
 - [ ] merge-mode automatic detect, enable, goto-first
        I'm not sure I want this, but probably try it and see
index 96cfa9ce21e79c16752c48f89ad634fa8ae66c35..3e2cffa2518bc99295ca99c69446d0c32a291130 100644 (file)
@@ -21,7 +21,10 @@ class MergePane(edlib.Pane):
         self.wig = None
         self.conflicts = 0
         self.space_conflicts = 0
+        self.merge_num = None
+        self.merge_char = None
         self.call("doc:request:doc:replaced")
+        self.call("doc:request:mark:moving")
 
     def fore(self, m, end, ptn):
         if not m:
@@ -294,6 +297,78 @@ class MergePane(edlib.Pane):
             return 1;
         return edlib.Efallthrough
 
+    def handle_swap(self, key, focus, mark, **a):
+        "handle:mode-swap-mark"
+        # redefine mode-swap-mark while in merge to cycle among the branches.
+        if not self.marks:
+            return edlib.Efallthrough
+        m = mark.dup()
+        focus.call("doc:EOL", m, -1)
+        if m <= self.marks[0]:
+            mark.to_mark(self.marks[1])
+            return 1
+        if m == self.marks[1]:
+            mark.to_mark(self.marks[2])
+            return 1
+        if m == self.marks[2]:
+            mark.to_mark(self.marks[3])
+            return 1
+        if m >= self.marks[3]:
+            mark.to_mark(self.marks[0])
+            return 1
+
+        # Must be in the merge - find the location and cycle
+        if m < self.marks[1]:
+            which = 0
+        elif m < self.marks[2]:
+            which = 1
+        else:
+            which = 2
+        if self.merge_num is None:
+            m.to_mark(mark)
+            a = focus.call("doc:get-attr", m, "render:merge-same", ret='str')
+            c = 0
+            while (not a or a[0] != 'M') and m > self.marks[which]:
+                focus.prev(m)
+                c += 1
+                a = focus.call("doc:get-attr", m, "render:merge-same", ret='str')
+            if not a:
+                return 1
+            self.merge_num = int(a.split()[3])
+            self.merge_char = c
+        which = (which + 1) % 3
+        m.to_mark(self.marks[which])
+        focus.call("doc:EOL", m, 1, 1)
+        a = focus.call("doc:get-attr", m, "render:merge-same", ret='str')
+        while (m < self.marks[which+1] and
+               (not a or a[0] != 'M' or int(a.split()[3]) < self.merge_num)):
+            focus.next(m)
+            a = focus.call("doc:get-attr", m, "render:merge-same", ret='str')
+        if not a:
+            return 1
+        if int(a.split()[3]) == self.merge_num:
+            # target merge exists - find the char
+            c = 0
+            a = None
+            while (m < self.marks[which+1] and
+                   c < self.merge_char and
+                   (not a or a[0] != 'M')):
+                focus.next(m)
+                c += 1
+                a = focus.call("doc:get-attr", m, "render:merge-same", ret='str')
+        # when we move, merge_num will be cleared!
+        mn = self.merge_num
+        focus.call("Move-to", m)
+        self.merge_num = mn
+        return 1
+
+    def handle_mark_moving(self, key, focus, mark, **a):
+        "handle:mark:moving"
+        pt = self.call("doc:point", ret='mark')
+        if pt == mark:
+            self.merge_num = None
+        return 1
+
     def remark(self, key, **a):
         if self.marks:
             m = self.marks[3].dup()