Subject: [PATCH] Support strings for electric-pairs.
From: Elijah Gabe Pérez <[email-masked]>
To: [email-masked]
Date: Thu, 24 Apr 2025 18:30:10 -0600
List-Id: <debbugs-submit.debbugs.gnu.org>

Tags: patch

As discussed in bug#77823, this feature bring support for
using strings as pairs in `electric-pair-mode', the advantage is that
this can be used for: Auto-close block comments, close conditional
constructs such as `case esac' from bash and whatever.

This is currently a working prototype (only inserts the pairs).
I would like to hear some comments or suggestions of this implementation.

Thanks.
From 8e237df3dded619b1f5a849e33b0bb5b9cf8bab7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?El=C3=ADas=20Gabriel=20P=C3=A9rez?= <[email-masked]>
Date: Thu, 24 Apr 2025 17:34:58 -0600
Subject: [PATCH] Support strings for electric-pairs.  (bug#)

This add support for string pairs in electric-pairs-mode.
For example, typing `/*' in c-mode and derived it auto insert ` */',
or in sh-mode `case ' inserts `esac'.

* lisp/elec-pair.el (electric-pair-pairs): Add string :type
in defcustom.
(electric-pair-syntax-info)
(electric-pair-post-self-insert-function): Add support for
strings.
* etc/NEWS: Announce changes.
---
 etc/NEWS          |  5 +++++
 lisp/elec-pair.el | 22 ++++++++++++++++++++--
 2 files changed, 25 insertions(+), 2 deletions(-)

diff --git a/etc/NEWS b/etc/NEWS
index ade5abc43fc..2d024f7a5e3 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -527,6 +527,11 @@ You can now insert or wrap text with multiple sets of parentheses and
 other matching delimiters at once with Electric Pair mode, by providing
 a prefix argument when inserting one of the delimiters.
 
+---
+** Electric pair mode now supports using strings as pairs.
+Now 'electric-pair-mode' can use strings as pairs,
+TODO: I don't know what to put here
+
 +++
 ** You can now use 'M-~' during 'C-x s' ('save-some-buffers').
 Typing 'M-~' while saving some buffers means not to save the buffer and
diff --git a/lisp/elec-pair.el b/lisp/elec-pair.el
index aa2577300fd..e48fbee6b4a 100644
--- a/lisp/elec-pair.el
+++ b/lisp/elec-pair.el
@@ -41,7 +41,9 @@ electric-pair-pairs
 See also the variable `electric-pair-text-pairs'."
   :version "24.1"
   :group 'electricity
-  :type '(repeat (cons character character)))
+  :type '(repeat
+          (choice (cons character character)
+                  (cons string string))))
 
 (defcustom electric-pair-text-pairs
   `((?\" . ?\")
@@ -258,7 +260,18 @@ electric-pair-syntax-info
      (direct (if (eq (car direct) (cdr direct))
                  (list ?\" command-event t string-or-comment)
                (list ?\( (cdr direct) t string-or-comment)))
-     (reverse (list ?\) (car reverse) t string-or-comment)))))
+     (reverse (list ?\) (car reverse) t string-or-comment))
+     ;; The if-let here is for avoid unnecessary looking-back computation
+     ((if-let* ((str-pair
+		 (cl-loop for pairs in fallback
+			  do
+			  (if (and
+			       (stringp (car pairs))
+			       (looking-back
+				(regexp-quote (car pairs))
+				(- (point) (length (car pairs)))))
+			      (cl-return (cdr pairs))))))
+	  (list 'str str-pair nil nil))))))
 
 (defun electric-pair--insert (char times)
   (let ((last-command-event char)
@@ -591,6 +604,11 @@ electric-pair-post-self-insert-function
                               pos))
          (forward-char num))
         ;; Insert matching pair.
+        ;; String pairs
+        ((and (eq syntax 'str) (not overwrite-mode))
+         (insert " ")
+         (save-excursion (insert " " pair)))
+        ;; Char pairs
         ((and (memq syntax '(?\( ?\" ?\$))
               (not overwrite-mode)
               (or unconditional
-- 
2.49.0

-- 
                                          - E.G via GNU Emacs and Org.