Subject: Re: bug#77876: 31.0.50; elec-pair --- `electric-pair-inhibit-predicate' ignored for `electric-pair-pairs'

From: João Távora <[email-masked]>
Date: Sat, 26 Apr 2025 15:30:35 +0100

On Sat, Apr 26, 2025 at 1:28 PM Eli Zaretskii <[email-masked]> wrote:
>
> > From: Fernando de Morais <[email-masked]>
> > Date: Thu, 17 Apr 2025 17:14:46 -0300
> >
> > *Notice:* I don't believe this is a bug, but I would like to bring up a
> > discussion about the issue.
> >
> > To illustrate the matter, using `emacs -Q', please evaluate the
> > following snippet:
> >
> > #+begin_src emacs-lisp
> >   (progn
> >     (elisp-enable-lexical-binding 'interactive)
> >
> >     (defun org-electric-pair-inhibit (char)
> >       (let ((pairs '(?* ?/ ?_ ?= ?~ ?+)))
> >         (or (when (member char pairs)
> >           (not (region-active-p)))
> >         (electric-pair-default-inhibit char))))
> >
> >     (autoload #'setq-mode-local "mode-local")
> >     (setopt electric-pair-mode t)
> >     (setq-mode-local org-mode
> >                  electric-pair-pairs (append
> >                                       electric-pair-pairs
> >                                       '((?* . ?*) (?/ . ?/)
> >                                         (?_ . ?_) (?= . ?=)
> >                                         (?~ . ?~) (?+ . ?+)))
> >                  electric-pair-inhibit-predicate #'org-electric-pair-inhibit)
> >     (find-file "temp.org"))
> > #+end_src
> >
> > Results in:
> >
> > - The `org-electric-pair-inhibit' function is ignored, and the
> >   characters that should only be inserted in pairs when the region is
> >   active are inserted in pairs regardless.
> >
> > After a bit of investigation, I found that characters listed in
> > `electric-pair-pairs' are always inserted in pairs unconditionally.  The
> > function defined in `electric-pair-inhibit-predicate' is called only for
> > the pairs defined in the syntax table of the corresponding major mode.
> >
> > Although I believe this was a design decision, in my view, the
> > `electric-pair-inhibit-predicate' function should also apply to
> > characters in the `electric-pair-pairs' list.
> >
> > I'm not sure about the implications for other use cases, but a little
> > change made to the `electric-pair-post-self-insert-function' solves the
> > issue (diff attached).
> >
> > Do you think a change like this could be considered?  Thanks in advance.
> >
> > --
> > Regards,
> > Fernando de Morais.
> >
> > diff --git a/lisp/elec-pair.el b/lisp/elec-pair.el
> > index aa2577300fd..97aeca3f3b3 100644
> > --- a/lisp/elec-pair.el
> > +++ b/lisp/elec-pair.el
> > @@ -593,11 +593,10 @@ electric-pair-post-self-insert-function
> >          ;; Insert matching pair.
> >          ((and (memq syntax '(?\( ?\" ?\$))
> >                (not overwrite-mode)
> > -              (or unconditional
> > -                  (not (electric-pair--save-literal-point-excursion
> > -                         (goto-char pos)
> > -                         (funcall electric-pair-inhibit-predicate
> > -                                  last-command-event)))))
> > +              (not (electric-pair--save-literal-point-excursion
> > +                    (goto-char pos)
> > +                    (funcall electric-pair-inhibit-predicate
> > +                             last-command-event))))
> >           (save-excursion (electric-pair--insert pair num))))))))
> >
> >  (defun electric-pair-open-newline-between-pairs-psif ()
>
> João, any comments or suggestions?

I don't know, much of this is out of my mental cache.  But I would
start by checking
if it passes the unit tests for elec-pair.el (hoping that they haven't
been disabled
as as has happened in the past).  The tests have a pretty important say on
what the library is supposed to do, as they were carefully crafted from a good
number of edge cases and bug reports.

João