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: have cake will eat, eat cake will have - krazy key koncept kontroversy Date: Wed, 26 Aug 2009 18:36:22 -0700 Message-ID: <732931969EE046E8A44CE77C4FD88C64@us.oracle.com> NNTP-Posting-Host: lo.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit X-Trace: ger.gmane.org 1251337013 9252 80.91.229.12 (27 Aug 2009 01:36:53 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Thu, 27 Aug 2009 01:36:53 +0000 (UTC) To: "'Emacs-Devel devel'" Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Thu Aug 27 03:36:46 2009 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([199.232.76.165]) by lo.gmane.org with esmtp (Exim 4.50) id 1MgTus-0002zh-IZ for ged-emacs-devel@m.gmane.org; Thu, 27 Aug 2009 03:36:43 +0200 Original-Received: from localhost ([127.0.0.1]:48105 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1MgTur-0005uN-Ng for ged-emacs-devel@m.gmane.org; Wed, 26 Aug 2009 21:36:41 -0400 Original-Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1MgTuj-0005tI-UZ for emacs-devel@gnu.org; Wed, 26 Aug 2009 21:36:33 -0400 Original-Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1MgTue-0005mH-7s for emacs-devel@gnu.org; Wed, 26 Aug 2009 21:36:32 -0400 Original-Received: from [199.232.76.173] (port=47230 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1MgTue-0005m3-3g for emacs-devel@gnu.org; Wed, 26 Aug 2009 21:36:28 -0400 Original-Received: from acsinet12.oracle.com ([141.146.126.234]:40215) by monty-python.gnu.org with esmtps (TLS-1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.60) (envelope-from ) id 1MgTud-0004Ip-9o for emacs-devel@gnu.org; Wed, 26 Aug 2009 21:36:27 -0400 Original-Received: from acsinet15.oracle.com (acsinet15.oracle.com [141.146.126.227]) by acsinet12.oracle.com (Switch-3.3.1/Switch-3.3.1) with ESMTP id n7R1ZnEC024256 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Thu, 27 Aug 2009 01:35:51 GMT Original-Received: from abhmt010.oracle.com (abhmt010.oracle.com [141.146.116.19]) by acsinet15.oracle.com (Switch-3.3.1/Switch-3.3.1) with ESMTP id n7R1aPQK022594 for ; Thu, 27 Aug 2009 01:36:26 GMT Original-Received: from dradamslap1 (/141.144.224.223) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Wed, 26 Aug 2009 18:36:22 -0700 X-Mailer: Microsoft Office Outlook 11 Thread-Index: Acomtshdu4N6ZSR3QBqqc5DpzCzXCw== X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.5579 X-Source-IP: abhmt010.oracle.com [141.146.116.19] X-Auth-Type: Internal IP X-CT-RefId: str=0001.0A090206.4A95E317.00B8:SCFSTAT5015188,ss=1,fgs=0 X-detected-operating-system: by monty-python.gnu.org: GNU/Linux 2.6 (newer, 1) X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.devel:114651 Archived-At: (At Swim-Two-Birds...) This will probably be another controversial suggestion... Or ignored. Or both. ;-) 1. Key sequences that are single keys or chords can be repeated by simply holding the key or chord pressed. This is very handy for certain commands; for other commands it is not so important (not needed). The set of easy-to-use single keys and chords is limited, so we should try to save such key sequences for commands that we might want to easily repeat. IOW, we don't want to waste such keys. (Yes, you can always use `C-x z z z z z...' after any key sequence, to repeat a command. But that's not quite as handy as simply holding a key pressed to repeat it.) 2. Putting commands on a prefix key makes them *not* easily repeatable. So we should do that only for commands whose easy repetition is not so important. 3. Grouping related commands on a prefix key is one way to conserve non-prefix key bindings (that is, conserve keys that are easily repeatable). (Such grouping can also help with remembering, doc, etc.) For example, we put all of the bookmark commands on prefix `C-x r'. We could have bound each of them to a non-prefix key instead, but that would have wasted the (easily repeatable) non-prefix keys. These particular commands do not need to be repeated often, so grouping them on a prefix is a good choice. 4. Emacs has some non-prefix keys that are not bound to commands that require easy repetition. I haven't thought about a list of such commands, but there are some. You can easily think of a few (`C-a', for instance). Judging only by the criterion in #1, this is a waste of precious easily-repeatable keys. (But that's not the only criterion.) 5. The reasons for #4 might be different for different keys. They include: 5a. Often-used commands deserve an easy-to-press key or chord. Regardless of whether they are often repeated or even repeatable. 5b. Maybe just legacy - the key was assigned soon after the Emacs Big Bang, and old habits die hard. When Emacs was young, there were more easy keys to go 'round. 6. Emacs has other non-prefix keys, such as `C-b', that are bound to commands that do require the possibility of easy repetition. Like the easily repeatable non-prefix keys that do not require repetition (#4), these keys are, well, non-prefix. They cannot also be used as a prefix, to introduce a group of related keys. ("Huh? Duh!", I hear you say.) 7. A prefix key defines key sequences that cannot easily be repeated (i.e., simply by holding pressed), and the prefix key itself does nothing. That is, it has no action other than serving as a way station to the suffix keys it prefixes. This means that each prefix key (single key or chord) that itself is easy to type wastes an easily repeatable key, depriving it of being used on its own for an action. For example, since `C-x' is a prefix key, `C-x' cannot be used to perform some action - so we cannot then just hold `C-x' pressed to repeat that action. (Note that using the prefix key itself as one of its suffixes is not the same as repeatedly repeating it. E.g. `C-x C-x' can be defined as some action, but `C-x' itelf cannot perform a repeatable action, and `C-x C-x C-x' is not a repetition of anything. 8. #6 and #7 together simply say that you cannot have your cake and eat it too. If a key serves as a prefix, then it cannot also perform an action. If a key performs an action, then it cannot also be a prefix key. After all, a prefix key is bound to a keymap, not to a command. Duh, again. OK, here comes the crazy, controversial part... 9. What about somehow working around this limitation? That is, find a way to let a key such as `C-x' serve both (a) as a prefix key (a way station to suffix keys) and (b) as its own binding, to invoke a repeatable action. 10. If we did that, then we could potentially revisit some of the wasters mentioned in #4, #6, and #7. We could define the same easily repeatable key (`C-a' or whatever) as a prefix key. Being able to do that doesn't mean that we would have to do it, but the discussion could be opened wrt particular keys, case by case. 11. WDOT? Is this a good idea in general or not? If so, do you have a good idea for an implementation of #9? 12. Here is one possible implementation in Lisp. I don't claim it's the best one, but it seems to work OK. (defun repeat-command (command) "Repeat COMMAND. (more explanation needed)" (interactive) (let ((repeat-previous-repeated-command command) (last-repeatable-command 'repeat)) (repeat nil))) Here is how you could then define `C-x', which is already a prefix key, as also a repeatable key for an action command, in this case, `backward-char': (defun backward-char-repeat () "Like `backward-char'. (more explanation needed)" (interactive) (repeat-command 'backward-char)) (define-key ctl-x-map "\C-x" 'backward-char-repeat) Now just holding down `C-x' invokes `backward-char' repeatedly - once you've gotten past the first `C-x' (the prefix). But `C-x C-f' still calls `find-file', `C-x b' still calls `switch-to-buffer', etc. IOW, `C-x' is, in effect, both a prefix key and an action key ("in effect", meaning it _seems_ to act that way). The idea is to just define the prefix key as its own suffix (just as we do for `exchange-point-and-mark'), but by binding that key sequence to a repeat action. (Obviously, this example is just an illustration. I'm not proposing to do away with `C-x C-x' for `exchange-point-and-mark' or to change the binding of `backward-char'.) 13. Yes, you must repeat the key at least once for it to do anything. That is, `C-x' does nothing until you hit it again. But each `C-x' after the first one invokes the action. Because of this startup hiccup (stutter?), we would not want to do this for any command (such as `C-b', in fact) that we would often use _without_ repeating. This would be good for actions, such as frame movement, text scaling, or window resizing, that are typically used with repetition and not as one-offs. 14. In the implementation, we could perhaps play with using a prefix arg too. But without changing the definitions at all, notice that you can already use a prefix arg to increase the scale of each action (or do whatever the command does with a prefix arg, each time it is invoked in a set of repetitions). For example, with the above definitions, `C-u C-x C-x C-x C-x' performs three (4 - 1 = 3) `backward-char' operations, giving each one the prefix arg (numeric value 4). For `backward-char', the effect is that the scale of movement is multiplied by 4. Each repetition is scaled: 3 * 4 = 12. 15. Obviously, the interest of this would be to be able to do both of these at the same time (have our cake and eat it too): 15a. HAVE CAKE: Treat an existing non-prefix key as a prefix key (e.g. `C-a'). 15b. EAT CAKE: Add an action binding to an existing prefix key (e.g. `M-s'). 16. Downsides? Less transparency, not so obvious. `C-h k C-x C-x' for the above example shows its doc string, but we would need to introduce the concept of such a key for users, to make it clear once and for all what's involved. And there is no doc for just `C-h k C-x'. That is, this kind of repeatable key/action is nevertheless on a prefix key - nothing happens until you hit it a second time. IOW, the "trick" would need to be explained, to set expectations. Not the implementation, but the idea that `C-x C-x' (or whatever) is a key sequence whose last part (only) is repeatable. You need not repeat the pair `C-x C-x'; you can just repeat `C-x' (at least once). Some doc or naming convention should probably be adopted to identify and refer to such commands and their key bindings. Another (minor, IMO) downside is the inability to use, say, `C-x C-f' immediately after repeating `C-x C-x...'. You must do something else first, to break the chain of repetition. 17. If we were to decide to adopt this approach semi-systematically, the question would arise as to how to proceed. Emacs itself could no doubt take advantage of the possibility of additional easily-repeatable bindings. But users would also appreciate that possibility for their own bindings. I personally would not like to see Emacs take advantage of things to the point of not giving some of the new freedom to users for their own bindings. 18. An alternative approach might be to do nothing except explain this possibility to users, as a trick they might want to use to rationalize their key bindings. IOW, document it, but don't use it to change any bindings in Emacs-out-of-the box. (Or do nothing at all - I'll just mention it on the wiki.) 19. If we decided for #17 (not #18), a good place to start would be to identify the cases of #15a that might be good candidates for redefinition. IOW, would it make sense to bind `C-b' to a command such as `backward-char-repeat'? Let's suppose the answer for `C-b' is "yes" (even though it's not). That means defining `C-b' as a prefix key, but it doesn't necessarily mean defining any other suffix than `C-b' right away. Emacs could hold off, leaving the rest of that prefix key open for use by users, at least for now. On the other hand, some might argue that it would be silly to do that, given that the current use of a single `C-b' would be lost (you would need to use `C-b C-b' to get any action at all). They might say that we should wait until we actually use `C-b' as a prefix for some group of operations - that way, at least the loss of a single active `C-b' would be compensated by some gain. Obviously, `C-b' is, again, just an illustration. I'm not proposing that we lose the single-key `C-b' action just to be able to squeeze suffixes onto `C-b'. Real candidates for this would need to be picked case by case. 20. Anyway, you get the idea: 20a. The main question of the utility of such a manip. 20b. The question of what implementation would be good. 20c. The question of how to proceed (which keys/commands to look at).