Subject: Re: bug#35177: 27.0.50; Binding deactivate-mark to nil unexpectedly deactivates the mark

From: Noam Postavsky <[email-masked]>
Date: Mon, 08 Apr 2019 20:04:01 -0400

Markus Triska <[email-masked]> writes:

> (let (deactivate-mark)
>   (switch-to-buffer (get-buffer-create "t"))
>   (insert "hello")
>   (set-mark-command nil)
>   (move-beginning-of-line nil))
>
> It seems to play a role whether its buffer is modified or not, hence
> this receipe starting from a fresh file and an unmodified buffer.

I think the key detail is whether deactivate-mark has a buffer-local
value or not (modifying the buffer gives it one).  If it does have a
buffer-local value, then the let-binding affects just the buffer-local
one, otherwise, it binds the global value.  So C-x C-e on the following
always gives an active mark:

(progn
  (make-local-variable 'deactivate-mark)
  ;; (kill-local-variable 'deactivate-mark)
  (let (deactivate-mark)
    (switch-to-buffer (get-buffer-create "t"))
    (insert "hello")
    (set-mark-command nil)
    (move-beginning-of-line nil)))

And if you uncomment the kill-local-variable statement, then C-x C-e
will never give an active mark.

C-M-x and M-x eval-region still do give an active mark for all variants.
I'm not entirely sure why, but I'm guessing it's because they juggle
buffers in a slightly different way, such that the command loop ends up
consulting the value of deactivate-mark from somewhere else.