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: 19 Apr 2002 01:07:39 +0200 Sender: emacs-devel-admin@gnu.org Message-ID: <5xk7r4mwqs.fsf@kfs2.cua.dk> References: <5xbscpg7zl.fsf@kfs2.cua.dk> <200204112243.g3BMhmI01190@rum.cs.yale.edu> <5xd6x5i7ps.fsf@kfs2.cua.dk> <5x4rih12b2.fsf@kfs2.cua.dk> <200204121846.g3CIkZY16909@rum.cs.yale.edu> <5xofgoobzr.fsf@kfs2.cua.dk> <200204122021.g3CKLh217680@rum.cs.yale.edu> <5xu1qd29od.fsf@kfs2.cua.dk> <200204162018.g3GKI3S24358@aztec.santafe.edu> <5x662rxog2.fsf@kfs2.cua.dk> <200204181846.g3IIk2K00596@aztec.santafe.edu> NNTP-Posting-Host: localhost.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: main.gmane.org 1019168932 19361 127.0.0.1 (18 Apr 2002 22:28:52 GMT) X-Complaints-To: usenet@main.gmane.org NNTP-Posting-Date: Thu, 18 Apr 2002 22:28:52 +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 16yKOa-00052A-00 for ; Fri, 19 Apr 2002 00:28:52 +0200 Original-Received: from fencepost.gnu.org ([199.232.76.164]) by quimby.gnus.org with esmtp (Exim 3.12 #1 (Debian)) id 16yKhx-000572-00 for ; Fri, 19 Apr 2002 00:48:53 +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 16yK5Z-0003e4-00; Thu, 18 Apr 2002 18:09:13 -0400 Original-Received: from mail.filanet.dk ([195.215.206.179]) by fencepost.gnu.org with smtp (Exim 3.34 #1 (Debian)) id 16yK3P-0003Of-00; Thu, 18 Apr 2002 18:07:00 -0400 Original-Received: from kfs2.cua.dk.cua.dk (unknown [10.1.82.3]) by mail.filanet.dk (Postfix) with SMTP id 7759A7C04C; Thu, 18 Apr 2002 22:06:50 +0000 (GMT) Original-To: rms@gnu.org In-Reply-To: <200204181846.g3IIk2K00596@aztec.santafe.edu> Original-Lines: 213 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:2756 X-Report-Spam: http://spam.gmane.org/gmane.emacs.devel:2756 Richard Stallman writes: > Consider a keymap K which has a binding for [C-x 1], > a keymap P which has a binding for [C-x 2], and > a keymap S which has a binding for [C-x 3]. > > Keymap S has a filter which means that it is only active > if mark-active is non-nil. > > Now, we want keymap P to be a parent map for K, and > we want S to be a submap of K. > > Why do we want that? What job are you trying to do? I've described that several times by now -- I'm trying to find the right approach to address the issues with complex modes which uses a lot of keymaps (like cua and viper) and base the selection between those keymaps on combining various state information, i.e. to provide a more versatile keymap functionality than what is currently available. I think I have ironed this out for cua by now via a (tedious) post-command-hook to do this through minor-mode-map-alist, but where I could just condition a keymap with `mark-active' if the decision is made when a key is actually processed, I need an expression like (and mark-active (not deactivate-mark)) in the post-command-hook -- and hope that nothing else changes the mark state under my feet.... Here is the current cua code where the cua--fix-keymaps function is run by the post-command-hook after every command: now> (defvar cua-global-keymap (make-sparse-keymap)) now> (defvar cua--cua-keys-keymap (make-sparse-keymap)) now> (defvar cua--prefix-override-keymap (make-sparse-keymap)) now> (defvar cua--prefix-repeat-keymap (make-sparse-keymap)) now> (defvar cua--global-mark-keymap (make-sparse-keymap)) now> (defvar cua--rectangle-keymap (make-sparse-keymap)) now> (defvar cua--region-keymap (make-sparse-keymap)) now> now> (defvar cua--ena-cua-keys-keymap nil) now> (defvar cua--ena-prefix-override-keymap nil) now> (defvar cua--ena-prefix-repeat-keymap nil) now> (defvar cua--ena-region-keymap nil) now> (defvar cua--ena-global-mark-keymap nil) now> now> (defvar cua--mmap-prefix-override-keymap (cons 'cua--ena-prefix-override-keymap cua--prefix-override-keymap)) now> (defvar cua--mmap-prefix-repeat-keymap (cons 'cua--ena-prefix-repeat-keymap cua--prefix-repeat-keymap)) now> (defvar cua--mmap-cua-keys-keymap (cons 'cua--ena-cua-keys-keymap cua--cua-keys-keymap)) now> (defvar cua--mmap-global-mark-keymap (cons 'cua--ena-global-mark-keymap cua--global-mark-keymap)) now> (defvar cua--mmap-rectangle-keymap (cons 'cua--rectangle cua--rectangle-keymap)) now> (defvar cua--mmap-region-keymap (cons 'cua--ena-region-keymap cua--region-keymap)) now> (defvar cua--mmap-global-keymap (cons 'cua-mode cua-global-keymap)) now> now> (defvar cua--mmap-list now> (list cua--mmap-prefix-override-keymap now> cua--mmap-prefix-repeat-keymap now> cua--mmap-cua-keys-keymap now> cua--mmap-global-mark-keymap now> cua--mmap-rectangle-keymap now> cua--mmap-region-keymap now> cua--mmap-global-keymap)) now> now> (defun cua--fix-keymaps (disable) now> ;; Ensure that cua's keymaps are in minor-mode-map-alist and now> ;; in the correct order, and set control variables. now> (let (fix now> (mmap minor-mode-map-alist) now> (ml cua--mmap-list)) now> (while (and (not fix) mmap ml) now> (if (not (eq (car mmap) (car ml))) now> (setq fix t) now> (setq mmap (cdr mmap) now> ml (cdr ml)))) now> (if ml now> (setq fix t)) now> (when (or fix disable) now> (setq ml cua--mmap-list) now> (while ml now> (setq minor-mode-map-alist (delq (car ml) minor-mode-map-alist)) now> (setq ml (cdr ml)))) now> (when (and fix (not disable)) now> (setq minor-mode-map-alist now> (append (copy-sequence cua--mmap-list) minor-mode-map-alist)))) now> (setq cua--ena-region-keymap now> (and mark-active (not deactivate-mark))) now> (setq cua--ena-prefix-override-keymap now> (and cua--ena-region-keymap now> cua-enable-cua-keys now> (or (eq cua-enable-cua-keys t) now> (not cua--explicit-region-start)) now> (not executing-kbd-macro) now> (not cua--prefix-override-timer))) now> (setq cua--ena-prefix-repeat-keymap now> (and cua--ena-region-keymap now> (timerp cua--prefix-override-timer))) now> (setq cua--ena-cua-keys-keymap now> (and cua-enable-cua-keys now> (or (eq cua-enable-cua-keys t) now> cua--last-region-shifted))) now> (setq cua--ena-global-mark-keymap now> (and cua--global-mark-active now> (not (window-minibuffer-p))))) to the code as it would look like with a dynamic setup via the proposed emulation-mode-map-alists (andn nothing is needed in the post-command-hook): emma> (defvar cua-global-keymap (make-sparse-keymap)) emma> (defvar cua--cua-keys-keymap (make-sparse-keymap)) emma> (defvar cua--prefix-override-keymap (make-sparse-keymap)) emma> (defvar cua--prefix-repeat-keymap (make-sparse-keymap)) emma> (defvar cua--global-mark-keymap (make-sparse-keymap)) ; Initalized when cua-gmrk.el is loaded emma> (defvar cua--rectangle-keymap (make-sparse-keymap)) ; Initalized when cua-rect.el is loaded emma> (defvar cua--region-keymap (make-sparse-keymap)) emma> emma> (setq emulation-mode-map-alists emma> (cons emma> `((lambda . (and mark-active emma> cua-enable-cua-keys emma> (or (eq cua-enable-cua-keys t) emma> (not cua--explicit-region-start)) emma> (not executing-kbd-macro) emma> (not cua--prefix-override-timer) emma> '(cua--prefix-override . ,cua--prefix-override-keymap))) emma> (lambda . (and mark-active emma> (timerp cua--prefix-override-timer) emma> '(cua--prefix-override . ,cua--prefix-repeat-keymap))) emma> (lambda . (and cua-enable-cua-keys emma> (or (eq cua-enable-cua-keys t) emma> cua--last-region-shifted) emma> '(cua-enable-cua-keys . ,cua--cua-keys-keymap))) emma> (lambda . (and cua--global-mark-active emma> (not (window-minibuffer-p)) emma> '(cua--global-mark-active . ,cua--global-mark-keymap))) emma> (cua--rectangle . ,cua--rectangle-keymap) emma> (mark-active . ,cua--region-keymap) emma> (cua-mode . ,cua-global-keymap)) emma> emulation-mode-map-alists)) > > With my proposal, C-x 1, C-x 2, and (if mark-active) C-x 3 will all > work seemlessly > > What does it mean for them to "work"? Once again, what job > are you trying to do? It is not useful to address this backwards. > I have N keymaps which all make bindings starting with C-x -- and I want all of those bindings to "work". I tried the `simple' approach by putting these keymaps into the proposed `emulation-mode-map-alists', but that idea was turned down. If it wasn't for the problem evalling code in the current_minor_maps function [I believe there are ways to solve that], would that solution be acceptable? > We must not introduce more complex features merely because they look > appealing in the abstract. We have to look at the job first, then > determine how much complexity is really *necessary*. > > > What problem is it meant to solve? > > Multiple keymap inheritance as well as conditional keymaps. > > Multiple inheritance is a mess. We should avoid it if we can. But the `parent keymap' inheritance is already pretty messy. A clean way to add multiple inheritance would fix that! Stefan told me he was working on a way to support things like this, but it had a number of problems (such as unnecessary consing), so I made another proposal (which doesn't do consing), but has other implications... > > > There is no way to implement such a restriction, > > and users don't generally know which functions do consing. > > This is not intended to be a user feature, it is for package > writers. > > I know which users this feature is for. The users of Emacs Lisp > don't generally know which functions do consing. That can change. > > I didn't think we should `implement' the restriction -- simply > document it. > > No way. Ok. > > This proposal includes many aspects each of which is very undesirable. > The entire approach is wrong. We need to start by looking at the actual > problem that we actually need to solve. Ok, that's what I've tried to do all along! I've already described it several times now, so what aspects of the problem are still unclear? So, please look at the problem! You (and others) don't approve of the proposals I've made to solve this. That's ok, but then I ask you to come up with a better proposal which deals with the problem at hand. Thank you! -- Kim F. Storm http://www.cua.dk