From mboxrd@z Thu Jan 1 00:00:00 1970 Path: main.gmane.org!not-for-mail From: "Stefan Monnier" Newsgroups: gmane.emacs.devel Subject: Re: Suggestion: Simple way to make conditional key bindings. Date: Mon, 26 Aug 2002 11:47:50 -0400 Sender: emacs-devel-admin@gnu.org Message-ID: <200208261547.g7QFlpA24835@rum.cs.yale.edu> References: <3D49FF140074EFAE@mel-rta7.wanadoo.fr> <5xadnd3eck.fsf@kfs2.cua.dk> <200208231722.g7NHM0M02096@rum.cs.yale.edu> <5xptw6wm2v.fsf@kfs2.cua.dk> NNTP-Posting-Host: localhost.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: main.gmane.org 1030379660 19400 127.0.0.1 (26 Aug 2002 16:34:20 GMT) X-Complaints-To: usenet@main.gmane.org NNTP-Posting-Date: Mon, 26 Aug 2002 16:34:20 +0000 (UTC) Cc: "Stefan Monnier" , "David PONCE" , emacs-devel@gnu.org Return-path: Original-Received: from quimby.gnus.org ([80.91.224.244]) by main.gmane.org with esmtp (Exim 3.35 #1 (Debian)) id 17jMoj-00052g-00 for ; Mon, 26 Aug 2002 18:34:17 +0200 Original-Received: from monty-python.gnu.org ([199.232.76.173]) by quimby.gnus.org with esmtp (Exim 3.12 #1 (Debian)) id 17jNJd-0008Db-00 for ; Mon, 26 Aug 2002 19:06:13 +0200 Original-Received: from localhost ([127.0.0.1] helo=monty-python.gnu.org) by monty-python.gnu.org with esmtp (Exim 4.10) id 17jMq0-0007Y6-00; Mon, 26 Aug 2002 12:35:37 -0400 Original-Received: from list by monty-python.gnu.org with tmda-scanned (Exim 4.10) id 17jM6Y-0002bj-00 for emacs-devel@gnu.org; Mon, 26 Aug 2002 11:48:38 -0400 Original-Received: from mail by monty-python.gnu.org with spam-scanned (Exim 4.10) id 17jM5v-0002Pl-00 for emacs-devel@gnu.org; Mon, 26 Aug 2002 11:48:16 -0400 Original-Received: from rum.cs.yale.edu ([128.36.229.169]) by monty-python.gnu.org with esmtp (Exim 4.10) id 17jM5q-0002NP-00 for emacs-devel@gnu.org; Mon, 26 Aug 2002 11:47:54 -0400 Original-Received: (from monnier@localhost) by rum.cs.yale.edu (8.11.6/8.11.6) id g7QFlpA24835; Mon, 26 Aug 2002 11:47:51 -0400 X-Mailer: exmh version 2.4 06/23/2000 with nmh-1.0.4 Original-To: storm@cua.dk (Kim F. Storm) Errors-To: emacs-devel-admin@gnu.org X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.0.11 Precedence: bulk List-Help: List-Post: List-Subscribe: , List-Id: Emacs development discussions. List-Unsubscribe: , List-Archive: Xref: main.gmane.org gmane.emacs.devel:6921 X-Report-Spam: http://spam.gmane.org/gmane.emacs.devel:6921 > > You want to have a code. That's what functions are for. I think `eval' > > should generally be avoided, and `funcall' used instead. > > This is especially true if we care about lexical scoping. > > I don't quite follow, but I take your word for it :-) When you construct a function, the Elisp interpreter/compiler knows that it's a piece of code and can do all kinds of things with it (byte-compile it, analyze it and put out warnings, build a closure to remember the current lexical bindings, ...). OTOH, when you build a piece of code to be eval'd, the Elisp interpreter/compiler usually has no idea that this is code rather than just some kind of list of elements, so it can't do anything clever with it. > > One problem with your change is "what binding do we use when we don't want > > to run code?". The `menu-item' syntax provides a binding (in the example > > above it's "my-filter" which is not very useful indeed) for the case > > where code should not be evalled (for example in `where-is'). > > Who said we don't want to run code :-) The current code says so. > > > It will then be quite trivial to enhance `define-key' to handle > > > conditional bindings: > > > > But is it desirable ? > > Don't really know... It seems like a simple approach to allow > packages to hook into "standard bindings". How about a set of examples where the current code does not provide sufficient flexibility ? I can come up with plenty of examples where we could use your code, but for most/all of them we could just as well put the bindings in minor/major-mode-maps or text-property keymaps. > > > (define-key global-map "\C-y" 'yank) ; this sets the default > > > > > > (define-key global-map "\C-y" 'yank-with-properties > > > '(and kill-ring (table-recognize-table (car kill-ring)))) > > > > > > The second call would automatically changes the non-cond binding into > > > a cond binding with the previous binding as default. > > > > Why not > > > > (define-key global-map "\C-y" 'yank-careful) > > (defun yank-careful (...) > > "Reinsert the last stretch of killed text, like `yank'. > > Contrary to `yank' this function is careful to preserve some important > > text properties when yanking tables." > > ...) > > The point is that you can install a package - like table.el - which is > then able to install its own conditional binding on C-y *without* > interferring with (or even knowning) the standard binding. I don't think that's right. I don't believe that table wants to override C-y sometimes: instead it wants to override `yank' sometimes. So what you want to do is to create `yank-careful' and then use either the `remap' thingy or substitute-key-definition or something like that. > Suppose we have a conditional binding like this > > (define-key global-map "\C-y" 'yank-rectangle > '(rectangle-p (car kill-ring))) > > to be able to insert rectangles from the kill-ring using C-y. The behavior would be really odd if the user had rebound C-y to `comment-dwim'. > Then table.el would still be able to install its own conditional > binding on C-y. Now that's a more interesting example. But maybe that calls for replacing `yank-careful' with a (defadvice yank ...) or something like that. I admit that I don't think either of yank-careful or defadvice are quite satisfactory for this case. But maybe, using `remap', we could check for an existing `remap' binding before adding our own, so that table.el would not defer to `yank' but to `yank-careful'. > > The advantage is that C-h k C-y doesn't just give you one of the two > > bindings but a docstring that describes both. Of course we could also > > improve C-h k to recognize your `cond' construct, etc... but is it > > really worth the trouble ? > > I didn't think about that, but it would be a nice way to report such > "multiple" bindings on a key... > > But you may also consider this as a different approach than using a > minor-mode-keymap, and in that case, I think C-h k doesn't report all > possible bindings for a key -- only the "currently active" binding, so > why does `cond' have to behave differently? It depends on whether the conditional that determines if the binding is active changes frequently or not (or implicitly or not). By the way, you can also get a behavior similar to the one you suggest using minor-mode maps (or major-mode maps or text-property maps) where the menu-item's filter returns nil in some cases (thus deferring to lower-precedence keymaps). Stefan