unofficial mirror of emacs-devel@gnu.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

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 public inbox

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

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).