From 71edb33c3d3a43ee7ad37f34d5ec7097d44881c6 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Fri, 18 Aug 2023 14:45:01 +1000 Subject: [PATCH] merge-view: allow 9:A-m to both cut and paste. If there is an active merge 9:A-m cuts it. If there isn't but is a selection, 9:A-m will paste it. Now if there is an active merge and a selection, 9:A-m will cut and paste. Signed-off-by: NeilBrown --- DOC/TODO.md | 2 +- python/lib-mergeview.py | 67 +++++++++++++++++++++++++---------------- 2 files changed, 42 insertions(+), 27 deletions(-) diff --git a/DOC/TODO.md b/DOC/TODO.md index 83deb315..df9b5a36 100644 --- a/DOC/TODO.md +++ b/DOC/TODO.md @@ -19,7 +19,7 @@ the file. find, favourite directories, favourite make or shell commands. Maybe that are found by moving "down" in history? Maybe alt-* flags them? -- [ ] merge command 9-A-m could work as one command. If there is an +- [X] merge command 9-A-m could work as one command. If there is an active selection, the patch is moved to that selection. - [X] merge command 9 must ensure selection is full lines. - [ ] if cursor position causes pane size to change, this doesn't diff --git a/python/lib-mergeview.py b/python/lib-mergeview.py index d66fb35f..5de79fd5 100644 --- a/python/lib-mergeview.py +++ b/python/lib-mergeview.py @@ -89,6 +89,35 @@ class MergePane(edlib.Pane): self.marks = None focus.call("view:changed", self.done_marks[0], self.done_marks[1]) + def apply_copied_merge(self, focus): + # If we have a selection and last copy was a patch, insert it + pt = focus.call("doc:point", ret='mark') + if pt and pt['selection:active'] == "1": + mk = focus.call("doc:point", ret='mark2') + else: + mk = None + if mk: + diff = focus.call("copy:get", ret='str') + if not diff or not diff.startswith("|||||||"): + diff = None + if diff: + # selection must be full lines + focus.call("doc:EOL", -1, pt) + focus.call("doc:EOL", -1, mk) + strt,end = pt.dup(),mk.dup() + if strt > end: + strt,end = end,strt + focus.call("select:commit") + + # move strt before region + strt.step(0) + focus.call("doc:replace", strt, strt, "<<<<<<< found\n") + # move end after region + end.step(1) + focus.call("doc:replace", end, end, diff, 0, 1) + return strt + return None + def handle_alt_m(self, key, focus, num, mark, **a): "handle:K:A-m" @@ -150,35 +179,21 @@ class MergePane(edlib.Pane): focus.call("copy:save", diff) focus.call("doc:replace", 0, 1, self.marks[1], m) self.marks = None - - return 1 + # we have an active selection, insert the merge there. + mark = self.apply_copied_merge(focus) + if not mark: + return 1 + num = 1 + else: + return 1 if num == 9: # paste from copy-buf if it is a diff - pt = focus.call("doc:point", ret='mark') - if pt and pt['selection:active'] == "1": - mk = focus.call("doc:point", ret='mark2') - else: - mk = None - if mk: - # selection must be full lines - focus.call("doc:EOL", -1, pt) - focus.call("doc:EOL", -1, mk) - strt,end = pt.dup(),mk.dup() - if strt > end: - strt,end = end,strt - focus.call("select:commit") - diff = focus.call("copy:get", ret='str') - if diff and diff.startswith("|||||||"): - # move strt before region - strt.step(0) - focus.call("doc:replace", strt, strt, "<<<<<<< found\n") - # move end after region - end.step(1) - focus.call("doc:replace", end, end, diff, 0, 1) - # Leave pt,mk - use 'strt' to find merge - mark = strt - # fall through to "Find" the merge + m = self.apply_copied_merge(focus) + if not m: + return 1 + mark = m + # fall through to "Find" the merge if self.marks: focus.call("doc:set-attr", "render:merge-same", -- 2.39.5