Subject: [PATCH] smerge-mode: add a function to resolve all conflicts in a file

From: Konstantin Kharlamov <[email-masked]>
Date: Sat, 17 Feb 2024 13:16:14 +0300

This implements a feature request from here¹ about having a function to
resolve all conflicts simultaneously. Although question author didn't
reply, but either way I think it's a useful functional. I needed it so
many times, but before stumbling upon this question I just didn't know
there are functions `smerge-keep-upper/base/lower`, and so ofc I never
though of writing a new one that would apply them to all conflicts.

It might be useful to make a function to do the same within a git-repo,
but for now let's have at least a function that does that within a
file.

1:
https://emacs.stackexchange.com/questions/80361/when-merging-conflicts-in-smerge-mode-how-to-select-mine-for-all-conflicts
From 1702d7c0f782a8e18b2539194a5b276707181353 Mon Sep 17 00:00:00 2001
From: Konstantin Kharlamov <[email-masked]>
Date: Sat, 17 Feb 2024 12:43:02 +0300
Subject: [PATCH] smerge-mode: add a function to resolve all conflicts in a
 file

* lisp/vc/smerge-mode.el (smerge-resolve-all-in-file-to): a new
interactive function to resolve all conflicts in a file.
---
 etc/NEWS               |  6 ++++++
 lisp/vc/smerge-mode.el | 21 +++++++++++++++++++++
 2 files changed, 27 insertions(+)

diff --git a/etc/NEWS b/etc/NEWS
index 9bdc3af5e71..b7a48412f4f 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -1170,6 +1170,12 @@ Similarly to buffer restoration by Desktop, 'recentf-mode' checking
 of the accessibility of remote files can now time out if
 'remote-file-name-access-timeout' is set to a positive number.
 
+** Smerge mode
+
+*** New interactive function 'smerge-resolve-all-in-file-to'.
+Allows to resolve all conflicts inside a file in preference of 'upper'
+or 'base' or 'lower'.
+
 ** Notifications
 
 +++
diff --git a/lisp/vc/smerge-mode.el b/lisp/vc/smerge-mode.el
index a16c7871ff9..c32410bcb15 100644
--- a/lisp/vc/smerge-mode.el
+++ b/lisp/vc/smerge-mode.el
@@ -714,6 +714,27 @@ smerge-keep-upper
   (smerge-keep-n 1)
   (smerge-auto-leave))
 
+(defun smerge-resolve-all-in-file-to (to-keep)
+  "Resolves all conflicts inside a file in preference of TO-KEEP.
+
+TO-KEEP decides which part to keep and is one of `upper', `base',
+`lower'".
+  (interactive
+   (list (completing-read "Keeping: " [upper base lower])))
+  (let ((resolve-func
+         (pcase to-keep
+           ("upper" 'smerge-keep-upper)
+           ("base"  'smerge-keep-base)
+           ("lower" 'smerge-keep-lower)
+           (_ (error "Unknown resolution argument!"))))
+        (num-chars-before (point-max)))
+    (save-excursion
+      (goto-char (point-min))
+      (while (ignore-errors (not (smerge-next)))
+        (funcall resolve-func)))
+    (when (= num-chars-before (point-max))
+      (message "No conflicts were found"))))
+
 (define-obsolete-function-alias 'smerge-keep-mine 'smerge-keep-upper "26.1")
 
 (defun smerge-get-current ()
-- 
2.43.0