From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Michael Heerdegen Newsgroups: gmane.emacs.help Subject: Re: Eval keymapp in a macros Date: Wed, 04 Aug 2021 02:18:09 +0200 Message-ID: <87r1faf4fy.fsf@web.de> References: <87bl6fy4cf.fsf@web.de> Mime-Version: 1.0 Content-Type: text/plain Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="33113"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/28.0.50 (gnu/linux) To: help-gnu-emacs@gnu.org Cancel-Lock: sha1:J7/v9F8UnzQbTTwip3USH0y28rA= Original-X-From: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane-mx.org@gnu.org Wed Aug 04 02:18:47 2021 Return-path: Envelope-to: geh-help-gnu-emacs@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1mB4cR-0008PC-2X for geh-help-gnu-emacs@m.gmane-mx.org; Wed, 04 Aug 2021 02:18:47 +0200 Original-Received: from localhost ([::1]:33978 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mB4cQ-0000ZK-3L for geh-help-gnu-emacs@m.gmane-mx.org; Tue, 03 Aug 2021 20:18:46 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:49784) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mB4c1-0000V1-UN for help-gnu-emacs@gnu.org; Tue, 03 Aug 2021 20:18:21 -0400 Original-Received: from ciao.gmane.io ([116.202.254.214]:46178) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mB4c0-0005wE-Bm for help-gnu-emacs@gnu.org; Tue, 03 Aug 2021 20:18:21 -0400 Original-Received: from list by ciao.gmane.io with local (Exim 4.92) (envelope-from ) id 1mB4bx-0007oi-LQ for help-gnu-emacs@gnu.org; Wed, 04 Aug 2021 02:18:17 +0200 X-Injected-Via-Gmane: http://gmane.org/ Received-SPF: pass client-ip=116.202.254.214; envelope-from=geh-help-gnu-emacs@m.gmane-mx.org; helo=ciao.gmane.io X-Spam_score_int: -23 X-Spam_score: -2.4 X-Spam_bar: -- X-Spam_report: (-2.4 / 5.0 requ) BAYES_00=-1.9, FREEMAIL_FORGED_FROMDOMAIN=0.249, FREEMAIL_FROM=0.001, HEADER_FROM_DIFFERENT_DOMAINS=0.248, NICE_REPLY_C=-1, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: help-gnu-emacs@gnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Users list for the GNU Emacs text editor List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane-mx.org@gnu.org Original-Sender: "help-gnu-emacs" Xref: news.gmane.io gmane.emacs.help:132351 Archived-At: Arthur Miller writes: > So I ended with the one I posted which works, but I wonder why, and I > don't really like it. I think you are correct about the reason. That is > what I think also, so that is why I used eval, because I need the keymap > object itself to pass to define-key, at least so I think. Maybe I am > wrong there? You are right. What you get in the expansion is similar to what happens here: (let ((entry '([f11] . emacs-lisp-mode-map))) (define-key global-map (car entry) (cdr entry))) which will also not "work". You never evaluate the bindings - else you would need to quote your command names. With other words: you currently specify command names and keymaps in the same way (as a symbol) - but the expansion needs to treat them differently, obviously, since `define-key' always interprets a symbol as a command name. That can't work. Your `keymapp' fix is an emergency solution but it's not perfect: that test happens at compile time. If the keymap is not defined at compile time your compiled code will be inappropriate. The only solution for this is to rewrite your macro so that keymap and command names are specified differently _in the call_. > (insert (pp (macroexpand-1 > '(defmacro with-key-map (mapname &rest body) > `(dolist (def '(,@body)) > (define-key ,mapname > (if (vectorp (car def)) (car def) > (read-kbd-macro (car def))) > (if (keymapp (cdr def)) > (eval (cdr def)) > (cdr def))))) > ))) I suggested to expand calls of the macro, not its definition ;-) Unless you wanted to search for bugs in the implementation of `defmacro'... but let's assume for now that your issue is caused by the implementation of `with-key-map', and not by `defmacro' ;-) > > Note that nothing in BODY is ever evaluated (it's behind a quote). > > Stuff in dolist gets evaluated, because dolist itself is a macro. > The real body of function which is all in do list gets expanded by > dolist (or the real interested part by 'while' which seems to be a > special form) and then evaled by dolist. So dolist will actually call > define-key for me, and that is what seem to happend, because stuff gets > defined after I call the macro. I hope I understand correctly what is > going on there. Yes, see my example above: the (quoted) list gets evaluated, but not its members, so you pass a symbol to `define-key' (what works for command names but not for keymap names). > As a side note, this isn't really a macro that writes a function or > another macro and returns it. I have it partly to save myself typing, > and partly to skip overhead of macroexpansion when Emacs start. Byte > compiler will expand it when init file is byte compiled. Actually I > wrote a program to write my init file which does expansion when it > outputs code to init file but it is just another regression. Compiling is a good idea. It would warn you if you misspelled a command name (your version doesn't support that btw). That concrete idea is cool but not really suitable for daily use, as you already have found out: macro expansions can take damage after printing and re-reading. Why do you think you need that? Why is normal code + normal compiling not sufficient? Michael.