all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* bitten by lexical-binding
@ 2015-11-21 22:28 Drew Adams
  2015-11-22 14:02 ` Johan Bockgård
                   ` (3 more replies)
  0 siblings, 4 replies; 8+ messages in thread
From: Drew Adams @ 2015-11-21 22:28 UTC (permalink / raw)
  To: emacs-devel

I should hardly complain without understanding completely
what is going on, but FWIW:

I redefine `mouse-drag-region', so that if you click in
the echo area when *Messages* is already displayed then:
(1) `M-x' is invoked and (2) the *Messages* window is
removed.  Otherwise, it behaves the same as the vanilla
version.

Not a big change, and this code has worked from Emacs 22
on.  And the part of the redefinition that differs from
the vanilla definition is not even in question here.

The vanilla definition of `mouse-drag-region' is this:

 (defun mouse-drag-region (start-event)
   (interactive "e")
   (run-hooks 'mouse-leave-buffer-hook)
   (mouse-drag-track start-event))

Prior to Emacs 24.4 it was the same, except the last line
had (mouse-drag-track start-event t).  My version of it too
had (mouse-drag-track start-event t).

Starting with Emacs 25, `mouse-drag-track' does not accept
the second arg.  But invoking it without that argument meant
that (my version of) `mouse-drag-region' no longer copied
the text to the kill ring, when `mouse-drag-copy-region'=t.
That was the problem.

I spent quite a while debugging this.  Using the debugger
or using calls to `message' to print out state was useless.

What changed in vanilla Emacs was `mouse-drag-track'.  It
now uses `set-transient-map' instead of handling a second
arg.  But finding just what change to make, to fix my code,
was really not easy.

It turned out (though I do not understand completely) that
the only thing I needed to do was to add a `lexical-binding'
declaration to my file.  (Luckily, the code in the file did
not depend on dynamic binding.)

My redefinition of `mouse-drag-region' does not make any
apparent use of visible lexical binding - no free vars,
no use of closures, etc.

`mouse-drag-track' does depend on lexical binding.  But
my code does not change `mouse-drag-track' in any way -
it just calls it, exactly the same way that vanilla Emacs
calls it.

Why is it that with dynamic binding my code did not work
(but it works with lexical binding)?

The same thing was true whether I byte-compiled my code or
not, and regardless of which Emacs version I byte-compiled
it in (even Emacs 20!).  And the same thing was true if I
loaded the vanilla source code (mouse.el) first, instead
of its byte-compiled version (mouse.elc).

An explanation of this would be great.  Meanwhile, this
seems like a gotcha.  Just because some function depends
on lexical binding, why should code that calls it also
need to use lexical binding?

----

Here is my code, FWIW.  The only part that differs from the
vanilla code is the handling of a click in the echo area.
And that part is not what misbehaved - it can be ignored here.

AFAIU, nothing in this code should change because of lexical
vs dynamic binding.  What am I missing?

(defun mouse-drag-region (start-event)
  (interactive "e")
  (let ((clickwin  (posn-window (event-start start-event))))
    (if (and (window-minibuffer-p clickwin)
	     (not (minibuffer-window-active-p clickwin)))
	(let* ((Messages-buf (get-buffer-create "*Messages*"))
	       (Messages-win (get-buffer-window Messages-buf
                                               'visible)))
	  (if Messages-win
	      (let ((M-x-cmd  (or (key-binding "\M-x" t)
				    'execute-extended-command)))
		(read-event)
		(if (eq Messages-win (selected-window))
		    (bury-buffer)
		  (delete-window Messages-win))
		(save-window-excursion
		  (call-interactively M-x-cmd nil [(meta ?x)])))
	    (save-excursion
	      (read-event)
	      (set-buffer Messages-buf)
	      (goto-char (point-max))
	      (display-buffer (current-buffer)))))
      (run-hooks 'mouse-leave-buffer-hook)
      (let ((emacs24.4+
	      (or (> emacs-major-version 24)
		  (and (= emacs-major-version 24)
		       (not (version< emacs-version "24.3.50"))))))
	(if emacs24.4+
	    (mouse-drag-track start-event) ; <=========
	  (mouse-drag-track start-event t))))))



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: bitten by lexical-binding
  2015-11-21 22:28 bitten by lexical-binding Drew Adams
@ 2015-11-22 14:02 ` Johan Bockgård
  2015-11-22 14:12 ` Artur Malabarba
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 8+ messages in thread
From: Johan Bockgård @ 2015-11-22 14:02 UTC (permalink / raw)
  To: Drew Adams; +Cc: emacs-devel


?? In Emacs 24 and 25, clicking in the echo area does not involve
`mouse-drag-region' at all, so I don't understand what you are talking
about.



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: bitten by lexical-binding
  2015-11-21 22:28 bitten by lexical-binding Drew Adams
  2015-11-22 14:02 ` Johan Bockgård
@ 2015-11-22 14:12 ` Artur Malabarba
  2015-11-22 14:23 ` Andreas Schwab
  2015-11-22 14:28 ` Michael Heerdegen
  3 siblings, 0 replies; 8+ messages in thread
From: Artur Malabarba @ 2015-11-22 14:12 UTC (permalink / raw)
  To: Drew Adams; +Cc: emacs-devel

> It turned out (though I do not understand completely) that
> the only thing I needed to do was to add a `lexical-binding'
> declaration to my file.  (Luckily, the code in the file did
> not depend on dynamic binding.)

From what I understand, lexical-binding definitely shouldn't have
affected this. Do you think you can come up with some self-contained
reproduction steps?



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: bitten by lexical-binding
  2015-11-21 22:28 bitten by lexical-binding Drew Adams
  2015-11-22 14:02 ` Johan Bockgård
  2015-11-22 14:12 ` Artur Malabarba
@ 2015-11-22 14:23 ` Andreas Schwab
  2015-11-22 14:29   ` David Kastrup
  2015-11-22 15:57   ` Drew Adams
  2015-11-22 14:28 ` Michael Heerdegen
  3 siblings, 2 replies; 8+ messages in thread
From: Andreas Schwab @ 2015-11-22 14:23 UTC (permalink / raw)
  To: Drew Adams; +Cc: emacs-devel

Drew Adams <drew.adams@oracle.com> writes:

>       (let ((emacs24.4+
> 	      (or (> emacs-major-version 24)
> 		  (and (= emacs-major-version 24)
> 		       (not (version< emacs-version "24.3.50"))))))
> 	(if emacs24.4+
> 	    (mouse-drag-track start-event) ; <=========

This is the wrong condition. In 24.5 mouse-drag-track still accepts the
optional argument.

Andreas.

-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: bitten by lexical-binding
  2015-11-21 22:28 bitten by lexical-binding Drew Adams
                   ` (2 preceding siblings ...)
  2015-11-22 14:23 ` Andreas Schwab
@ 2015-11-22 14:28 ` Michael Heerdegen
  2015-11-22 17:08   ` Drew Adams
  3 siblings, 1 reply; 8+ messages in thread
From: Michael Heerdegen @ 2015-11-22 14:28 UTC (permalink / raw)
  To: emacs-devel

Drew Adams <drew.adams@oracle.com> writes:

> Starting with Emacs 25, `mouse-drag-track' does not accept
> the second arg.  But invoking it without that argument meant
> that (my version of) `mouse-drag-region' no longer copied
> the text to the kill ring, when `mouse-drag-copy-region'=t.
> That was the problem.

Can't reproduce here, built from Nov 21 2015.

I copied your code into a file, one time with lexical binding enabled,
one time without.  In emacs -Q, I loaded that file and set
mouse-drag-copy-region -> t.

With both file versions, the region was copied to the kill ring after
dragging with the mouse.


Michael.




^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: bitten by lexical-binding
  2015-11-22 14:23 ` Andreas Schwab
@ 2015-11-22 14:29   ` David Kastrup
  2015-11-22 15:57   ` Drew Adams
  1 sibling, 0 replies; 8+ messages in thread
From: David Kastrup @ 2015-11-22 14:29 UTC (permalink / raw)
  To: Andreas Schwab; +Cc: Drew Adams, emacs-devel

Andreas Schwab <schwab@linux-m68k.org> writes:

> Drew Adams <drew.adams@oracle.com> writes:
>
>>       (let ((emacs24.4+
>> 	      (or (> emacs-major-version 24)
>> 		  (and (= emacs-major-version 24)
>> 		       (not (version< emacs-version "24.3.50"))))))
>> 	(if emacs24.4+
>> 	    (mouse-drag-track start-event) ; <=========
>
> This is the wrong condition. In 24.5 mouse-drag-track still accepts the
> optional argument.

And why would that make the condition wrong?

-- 
David Kastrup



^ permalink raw reply	[flat|nested] 8+ messages in thread

* RE: bitten by lexical-binding
  2015-11-22 14:23 ` Andreas Schwab
  2015-11-22 14:29   ` David Kastrup
@ 2015-11-22 15:57   ` Drew Adams
  1 sibling, 0 replies; 8+ messages in thread
From: Drew Adams @ 2015-11-22 15:57 UTC (permalink / raw)
  To: Andreas Schwab; +Cc: emacs-devel

> > 	(if emacs24.4+
> > 	    (mouse-drag-track start-event)
> 
> This is the wrong condition. In 24.5 mouse-drag-track still accepts the
> optional argument.

OK, thanks.  I'll revisit/retest that 24.4+ condition.

IIRC, I used that, rather that >24.5, because, although it
still accepts the 2nd arg, the behavior did not reflect it.
But I will check that condition.  Thx.



^ permalink raw reply	[flat|nested] 8+ messages in thread

* RE: bitten by lexical-binding
  2015-11-22 14:28 ` Michael Heerdegen
@ 2015-11-22 17:08   ` Drew Adams
  0 siblings, 0 replies; 8+ messages in thread
From: Drew Adams @ 2015-11-22 17:08 UTC (permalink / raw)
  To: Michael Heerdegen, emacs-devel

> > Starting with Emacs 25, `mouse-drag-track' does not accept
> > the second arg.  But invoking it without that argument meant
> > that (my version of) `mouse-drag-region' no longer copied
> > the text to the kill ring, when `mouse-drag-copy-region'=t.
> > That was the problem.
> 
> Can't reproduce here, built from Nov 21 2015.
> I copied your code into a file, one time with lexical binding
> enabled, one time without.  In emacs -Q, I loaded that file
> and set mouse-drag-copy-region -> t.
> With both file versions, the region was copied to the kill
> ring after dragging with the mouse.

Thanks for checking.

Testing some more, I found that the problem occurred only for
Emacs 24.[45], not for Emacs 25.  (Coulda sworn that I had
the problem for Emacs 25 also, but I sometimes use 24.5 to
avoid crashes I get with Emacs 25, and perhaps that's what
was involved here - faulty testing.)

I've removed the lex binding declaration and fixed the test
for passing two args to mouse-drag-track (which fixes the
problem for Emacs 24.[45]).

Sorry for the noise, and thanks to all for the feedback.

----

BTW, I neglected to say that the point of the code, which is
to let a mouse-1 click in the minibuffer invoke `M-x' and
remove *Messages*, if *Messages* is already shown, needs
these bindings, which are commented out as suggestions in
the file header:

;; ;; Do not use `view-echo-area-messages' for `mouse-1'.
;; ;; Use version of `mouse-drag-region' defined here
;; (when (> emacs-major-version 23)
;;   (define-key minibuffer-inactive-mode-map [down-mouse-1] nil)
;;   (define-key minibuffer-inactive-mode-map [mouse-1]      nil))

This is independent of the normal behavior and copying the
selection to the kill ring, which was the question here.
I mention this only in case someone is interested in this
click-in-echo-area behavior and wants to try it.



^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2015-11-22 17:08 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-11-21 22:28 bitten by lexical-binding Drew Adams
2015-11-22 14:02 ` Johan Bockgård
2015-11-22 14:12 ` Artur Malabarba
2015-11-22 14:23 ` Andreas Schwab
2015-11-22 14:29   ` David Kastrup
2015-11-22 15:57   ` Drew Adams
2015-11-22 14:28 ` Michael Heerdegen
2015-11-22 17:08   ` Drew Adams

Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.