From mboxrd@z Thu Jan 1 00:00:00 1970 Path: main.gmane.org!not-for-mail From: storm@cua.dk (Kim F. Storm) Newsgroups: gmane.emacs.devel Subject: Re: Enhancements to "minor-mode-map-alist" functionality. Date: 12 Apr 2002 15:20:17 +0200 Sender: emacs-devel-admin@gnu.org Message-ID: <5x4rih12b2.fsf@kfs2.cua.dk> References: <5xbscpg7zl.fsf@kfs2.cua.dk> <200204112243.g3BMhmI01190@rum.cs.yale.edu> <5xd6x5i7ps.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 1018614088 18592 127.0.0.1 (12 Apr 2002 12:21:28 GMT) X-Complaints-To: usenet@main.gmane.org NNTP-Posting-Date: Fri, 12 Apr 2002 12:21:28 +0000 (UTC) Cc: emacs-devel@gnu.org Return-path: Original-Received: from quimby.gnus.org ([80.91.224.244]) by main.gmane.org with esmtp (Exim 3.33 #1 (Debian)) id 16w03U-0004pl-00 for ; Fri, 12 Apr 2002 14:21:28 +0200 Original-Received: from fencepost.gnu.org ([199.232.76.164]) by quimby.gnus.org with esmtp (Exim 3.12 #1 (Debian)) id 16w0Jj-0006lh-00 for ; Fri, 12 Apr 2002 14:38:16 +0200 Original-Received: from localhost ([127.0.0.1] helo=fencepost.gnu.org) by fencepost.gnu.org with esmtp (Exim 3.34 #1 (Debian)) id 16w03A-0003qC-00; Fri, 12 Apr 2002 08:21:08 -0400 Original-Received: from mail.filanet.dk ([195.215.206.179]) by fencepost.gnu.org with smtp (Exim 3.34 #1 (Debian)) id 16w01X-0003lQ-00 for ; Fri, 12 Apr 2002 08:19:28 -0400 Original-Received: from kfs2.cua.dk.cua.dk (kfs2.local.filanet.dk [192.168.1.182]) by mail.filanet.dk (Postfix) with SMTP id 460427C047; Fri, 12 Apr 2002 12:19:26 +0000 (GMT) Original-To: "Stefan Monnier" In-Reply-To: <5xd6x5i7ps.fsf@kfs2.cua.dk> Original-Lines: 98 User-Agent: Gnus/5.09 (Gnus v5.9.0) Emacs/21.2.50 Errors-To: emacs-devel-admin@gnu.org X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.0.9 Precedence: bulk List-Help: List-Post: List-Subscribe: , List-Id: Emacs development discussions. List-Unsubscribe: , List-Archive: Xref: main.gmane.org gmane.emacs.devel:2574 X-Report-Spam: http://spam.gmane.org/gmane.emacs.devel:2574 I have been thinking more about this and I've now got a more generic solution (I think) which has a lot of potential: Nested, Conditioned Keymaps. The idea is as follows: 1) A keymap may be conditioned with (keymap :filter FORM ...) We already discussed that, and although some precautions are needed to handle this, it should be fairly trivial to implement. 2) A keymap may be nested with (keymap ... (keymap ...) ... (keymap ...) ...) The idea is that when we scan through a keymap (searching for a binding), if we encounter a nested keymap, we will [recursively] scan that keymap before continuing through the original keymap. Now, if we combine those two ideas, I can write a "single" cua-mode master keymap which contains all of the conditioned sub-keymaps I need, i.e. something like this [I know this isn't the proper way to create a keymap, but it illustrates the point I'm making]: (setq cua-mode-map (keymap :filter cua-mode (keymap :filter (and mark-active cua-enable-cua-keys (or (eq cua-enable-cua-keys t) (not cua--explicit-region-start)) (not executing-kbd-macro) (not cua--prefix-override-timer)) ,cua--prefix-override-keymap) (keymap :filter (and mark-active (timerp cua--prefix-override-timer)) ,cua--prefix-repeat-keymap) (keymap :filter (or (eq cua-enable-cua-keys t) cua--last-region-shifted) ,cua--cua-keys-keymap) (keymap :filter (and cua--global-mark-active (not (window-minibuffer-p))) ,cua--global-mark-keymap) (keymap :filter cua--rectangle ,cua--rectangle-keymap) (keymap :filter mark-active ,cua--region-keymap) ,cua-global-keymap)) (add-to-list 'minor-mode-map-alist `(cua-mode . ,cua-mode-map)) So doing this would remove the need for the emulation-mode-map-alists (which you dislike :-) as well I can easily ensure that cua-mode-map stays at the beginning of minor-mode-map-alist [will be simple in a post-command hook, or maybe by adding it to minor-mode-overriding-map-alist :-) ] Some functions may be needed to manage this, e.g. (add-keymap keymap nested &optional after) -> inserts NESTED at the beginning of KEYMAP, or after optional AFTER keymap (or last if AFTER is t) Returns NESTED. (remove-keymap keymap nested) -> removes NESTED from the KEYMAP. (set-keymap-filter keymap filter &optional new) -> sets the :filter property on KEYMAP to FILTER, removes the :filter property if FILTER is nil. If NEW is non-nil, create a new keymap and use KEYMAP as a nested of that keymap, and apply the FILTER on the new keymap. This means that we can apply a filter to an existing keymap without adding a filter to that keymap. -> returns KEYMAP if NEW is nil, or the new keymap if NEW is non-nil. (get-keymap-filter keymap) -> returns the :filter property on KEYMAP This can also be used instead of minor-mode-overriding-map-alist: >>From diff-mode.el: ;; Neat trick from Dave Love to add more bindings in read-only mode: (add-to-list (make-local-variable 'minor-mode-overriding-map-alist) (cons 'buffer-read-only diff-mode-shared-map)) could be replaced by: ;; Neat trick from Kim Storm to add more bindings in read-only mode: (add-keymap 'diff-mode-map (set-keymap-filter diff-mode-shared-map 'buffer-read-only t)) -- Kim F. Storm http://www.cua.dk