bug#50236: 27.2; electric-pair-mode is inconvenient in comint

João Távora <[email protected]> Thu, 06 Aug 2026 11:35:17 +0100
Newsgroups gmane.emacs.bugs
Message-ID <[email protected]>
Andrew Hyatt <[email protected]> writes:

>  If so, it'll be much easier to review and to understand by future maintainers. 
>
> Yes, I can create a macro that does the restriction, which may help readability. I've done so in a new patch which is now
> attached.

Hmmm, not quite.  The point was to make the diff smaller, not larger
:-).  Attached a patch after my sig that illustrates this.

Anyway, I've briefly tested your idea with M-x eshell and it works quite
elegantly!  Just the patch needs to be simplified:

- The docstring for electric-pair-max-field-size is too verbose and
  confusing (at least for dumb old me).
  
- This doesn't need a mention in the manual, at least not that
  prominently, it's just going to confuse newcomers about a super niche
  edge case.

- You could, however, call this out in NEWS, because that will alert
  some existing e-p-m users that it now more useful in these modes,
  where they probably are turning it off.  In fact, I think this change
  should go to emacs-31, it is a bug fix after all.

- There are basically no changes to
  electric-pair-post-self-insert-function's meat&bones, which is very
  good.  The diff should reflect that.  See below how.

- The variable doesn't really need to be defvar-local (in fact, a
  hardcoded 500 or sth wouldn't be silly either, seems unlikely someone
  will want to change this).  If modes want to make it local, they can
  just do so.  Also the defvar sits better near the usage locus IMO.

- The public-facing docstring of electric-pair-post-self-insert-function
  doesn't need a mention of the new implementation detail.  At least
  that's a very LLMish thing to do :-) it annoys me personally.  Better
  to call out this bug in a comment.

- The long variable names for the save-restriction logic made it harder
  to read, but again that's just me.

- The value of 1000 could be suitable, but you have to be aware this
  will amount to two new buffer field searches for _every_ insertion in
  the buffer, not just parenthesis.  This is probably "peanuts",
  i.e. not relevant, but you should find some way to measure.  Like how
  many spaces can you type in one minute if you hold down the spacebar
  in an emacs -Q -f electric-pair-mode before&after your change?

- The new tests are nice, but they're a bit hard to read.  Either make
  them about parenthesis-skipping (those are slightly easier to read) or
  add a comment explaining what the tests assert..

João

diff --git a/lisp/elec-pair.el b/lisp/elec-pair.el
index 54fbc960b0f..70a5e6853a4 100644
--- a/lisp/elec-pair.el
+++ b/lisp/elec-pair.el
@@ -596,10 +596,28 @@ electric-pair-default-inhibit
       (electric-pair-inhibit-if-helps-balance char)
     (electric-pair-conservative-inhibit char)))
 
+(defvar electric-pair-max-field-size 1000
+  "How far to look for field to restrict pairing to.
+If a field can't be found, use accessible buffer.")
+
 (defun electric-pair-post-self-insert-function ()
   "Do main work for `electric-pair-mode'.
 This function is added to `post-self-insert-hook' when
-`electric-pair-mode' is enabled.
+`electric-pair-mode' is enabled."
+  ;; Restrict operation to nearby field, if any (bug#50236)
+  (if (use-region-p)
+      (electric-pair-post-self-insert-function-1)
+    (with-restriction
+        (let* ((lim (- (point) electric-pair-max-field-size))
+               (beg (field-beginning nil nil (max (point-min) lim))))
+          (if (= lim beg) (point-min) beg))
+        (let* ((lim (+ (point) electric-pair-max-field-size))
+               (end (field-end nil nil (min (point-max) lim))))
+          (if (= end lim) (point-max) end))
+      (electric-pair-post-self-insert-function-1))))
+
+(defun electric-pair-post-self-insert-function-1 ()
+  "Do main work for `electric-pair-post-self-insert-function'.
 
 If the newly inserted character C has delimiter syntax, this
 function may decide to insert additional paired delimiters, or