[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

have cake will eat, eat cake will have - krazy key koncept kontroversy

From: Drew Adams
Subject: have cake will eat, eat cake will have - krazy key koncept kontroversy
Date: Wed, 26 Aug 2009 18:36:22 -0700

(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

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,

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

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)"
 (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,

(defun backward-char-repeat ()
  "Like `backward-char'.  (more explanation needed)"
  (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

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).

reply via email to

[Prev in Thread] Current Thread [Next in Thread]