Subject: Re: bug#4854: 23.1.50; before-string overlay and show-paren-mode

From: [email-masked]
Date: Sun, 03 Jul 2016 11:36:01 -0400

Stephen Berman <[email-masked]> writes:

> On Fri, 01 Jul 2016 14:42:30 -0400 [email-masked] wrote:
>
> [...]
>> Stephen Berman <[email-masked]> writes:
>>> These two things seem very strange: (i) enabling show-paren-mode and
>>> getting the show-paren overlay somehow nullifies the unless test; (ii)
>>> this effect only happens when the command is invoked via a key
>>> sequence.
>>
>> It's because show-paren-mode uses a single (pair of) overlay(s) for all
>> buffers and moves it to right place during idle time.  When you invoke a
>> command with M-x the overlay pair gets moved to the minibuffer.  With a
>> direct keybinding the overlay pair stays in the current buffer.
>
> Thanks for the diagnosis, which is convincing.
>
>> So I think this is not a bug, it's just how show-paren-mode works.
>
> I guess you're right; yet this behavior seems to go against the spirit
> of the way Emacs is intended to work, as suggested by the Emacs manual,
> node `M-x': "Every Emacs command has a name that you can use to run it.
> For convenience, many commands also have key bindings.  You can run
> those commands by typing the keys, or run them by name.  Most Emacs
> commands have no key bindings, so the only way to run them is by
> name. [...]  Note that ‘forward-char’ is the same command that you
> invoke with the key ‘C-f’.  The existence of a key binding does not stop
> you from running the command by name."  Are there any other Emacs
> commands that produce different behavior depending on whether they are
> invoked with a key binding or by name?

self-insert-command ;)

You can fix your my-test command by changing the condition:

(defun my-test ()
  ...
  (unless (cl-some (lambda (o) (overlay-get o 'before-string))
                   (overlays-in (1- (point)) (1+ (point))))
    ...))

>                                         
>                                         Maybe it would be better to
> unify the behavior of show-paren-mode.  (I briefly tried conditioning
> the calls to move-overlay on whether the current buffer is a minibuffer,
> but my attempt (which I didn't give much thought to) didn't work.)

Well, it's possible to avoid moving overlays to minibuffer, but then
show-paren-mode stops working in the minibuffer, which I don't think is
so great.

diff --git i/lisp/paren.el w/lisp/paren.el
index 53eb500..1e4942f 100644
--- i/lisp/paren.el
+++ w/lisp/paren.el
@@ -236,9 +236,10 @@ show-paren--default
 ;; Find the place to show, if there is one,
 ;; and show it until input arrives.
 (defun show-paren-function ()
-  (let ((data (and show-paren-mode (funcall show-paren-data-function))))
+  (let ((data (and show-paren-mode (not (minibufferp))
+                   (funcall show-paren-data-function))))
     (if (not data)
-        (progn
+        (unless (minibufferp)
           ;; If show-paren-mode is nil in this buffer or if not at a paren that
           ;; has a match, turn off any previous paren highlighting.
           (delete-overlay show-paren--overlay)

With that patch, the original my-test keeps inserting more overlays
whether it's called by keybinding or M-x.

>
> I guess this bug can be closed, unless leaving it open might spur
> someone to try and "improve" show-paren-mode.

Not sure if there's anything to do.