From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Drew Adams Newsgroups: gmane.emacs.devel Subject: bitten by lexical-binding Date: Sat, 21 Nov 2015 14:28:11 -0800 (PST) Message-ID: <9b834ee9-4f63-42ca-98b4-c0f14986642e@default> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: quoted-printable X-Trace: ger.gmane.org 1448144930 17381 80.91.229.3 (21 Nov 2015 22:28:50 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Sat, 21 Nov 2015 22:28:50 +0000 (UTC) To: emacs-devel@gnu.org Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Sat Nov 21 23:28:35 2015 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1a0Ge3-00036t-5h for ged-emacs-devel@m.gmane.org; Sat, 21 Nov 2015 23:28:35 +0100 Original-Received: from localhost ([::1]:53878 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1a0Ge2-0007eZ-Bq for ged-emacs-devel@m.gmane.org; Sat, 21 Nov 2015 17:28:34 -0500 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:39663) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1a0Gdn-0007cy-Rz for emacs-devel@gnu.org; Sat, 21 Nov 2015 17:28:20 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1a0Gdi-0006wd-R0 for emacs-devel@gnu.org; Sat, 21 Nov 2015 17:28:19 -0500 Original-Received: from aserp1040.oracle.com ([141.146.126.69]:41308) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1a0Gdi-0006wZ-KZ for emacs-devel@gnu.org; Sat, 21 Nov 2015 17:28:14 -0500 Original-Received: from userv0021.oracle.com (userv0021.oracle.com [156.151.31.71]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id tALMSDFE021171 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Sat, 21 Nov 2015 22:28:14 GMT Original-Received: from userv0122.oracle.com (userv0122.oracle.com [156.151.31.75]) by userv0021.oracle.com (8.13.8/8.13.8) with ESMTP id tALMSD2P029039 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL) for ; Sat, 21 Nov 2015 22:28:13 GMT Original-Received: from abhmp0014.oracle.com (abhmp0014.oracle.com [141.146.116.20]) by userv0122.oracle.com (8.13.8/8.13.8) with ESMTP id tALMSCnL028864 for ; Sat, 21 Nov 2015 22:28:13 GMT X-Priority: 3 X-Mailer: Oracle Beehive Extensions for Outlook 2.0.1.9 (901082) [OL 12.0.6691.5000 (x86)] X-Source-IP: userv0021.oracle.com [156.151.31.71] X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.4.x-2.6.x [generic] X-Received-From: 141.146.126.69 X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.devel:194966 Archived-At: 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'=3Dt. 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) =09 (not (minibuffer-window-active-p clickwin))) =09(let* ((Messages-buf (get-buffer-create "*Messages*")) =09 (Messages-win (get-buffer-window Messages-buf 'visible))) =09 (if Messages-win =09 (let ((M-x-cmd (or (key-binding "\M-x" t) =09=09=09=09 'execute-extended-command))) =09=09(read-event) =09=09(if (eq Messages-win (selected-window)) =09=09 (bury-buffer) =09=09 (delete-window Messages-win)) =09=09(save-window-excursion =09=09 (call-interactively M-x-cmd nil [(meta ?x)]))) =09 (save-excursion =09 (read-event) =09 (set-buffer Messages-buf) =09 (goto-char (point-max)) =09 (display-buffer (current-buffer))))) (run-hooks 'mouse-leave-buffer-hook) (let ((emacs24.4+ =09 (or (> emacs-major-version 24) =09=09 (and (=3D emacs-major-version 24) =09=09 (not (version< emacs-version "24.3.50")))))) =09(if emacs24.4+ =09 (mouse-drag-track start-event) ; <=3D=3D=3D=3D=3D=3D=3D=3D=3D =09 (mouse-drag-track start-event t))))))