help-gnu-emacs
[Top][All Lists]
Advanced

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

repeatable keys, prefix keys [was: Emacs keybindings according to fi


From: Drew Adams
Subject: repeatable keys, prefix keys [was: Emacs keybindings according to file type]
Date: Wed, 23 Sep 2020 10:04:03 -0700 (PDT)

> For instance one can make it to continue pressing
> C-t l f f f to continue moving line downward.
> 
> Any sample code to try out?

Sure:

(defun repeat-command (command)
  "Repeat COMMAND."
  (require 'repeat) ; Define its vars before we let-bind them.
  (let ((repeat-previous-repeated-command  command)
        (repeat-message-function           #'ignore)
        (last-repeatable-command           'repeat))
    (repeat nil)))

You can use it with nearly any COMMAND.  E.g., to make
a repeatable version of command `other-window':
 
(defun other-window-repeat ()
  "Same as `other-window', but repeatable even on a prefix key.
E.g., if bound to `C-x o' then you can use `C-x o o o...' to repeat."
  (interactive)
  (repeat-command 'other-window))

(global-set-key [remap other-window] 'other-window-repeat)
____

I do this all over the place, where it makes sense.

Keyboard keys are scarce.  When Emacs decides to bind
a key by default - a key that wasn't bound by default
before, I often raise these two points:

1. Save naturally repeatable keys for, well, commands
   that can be repeated, i.e., commands for which it
   makes sense to be able to just hold down a key to
   repeat them.

2. Save some keys for prefix keys, as opposed to just
   sacrificing them for a single command.  A prefix
   key essentially gives you a whole keyboard of
   possibilities for a single key.  Think of all the
   mileage we get out of the prefix key `C-x'!  Of
   course, adding a prefix key makes a key sequence
   longer, more complex.  Tradeoff.

I tend to define lots of keys for features I write,
and put them, by groups, on their own keymaps, and
then put those keymaps on prefix keys.  Even if such a
prefix key appears complicated or slow, the fact of
using a separate keymap means that a user can easily
put it on a different, shorter keymap, or remap it to
a more global keymap.

E.g., in Bookmark+ there are all of these keymaps on
prefix keys by default:

bookmark-map                C-x x
bmkp-annotate-map           C-x x a
bmkp-set-map                C-x x c    ("create")
bmkp-tags-map               C-x x t
bmkp-jump-map               C-x j
bmkp-jump-other-window-map  C-x 4 j

And it goes on from there.  `C-x j t' is a prefix key
for jumping to bookmarks with particular tags.

`C-x j t *' and `C-x j t +' are prefix keys for
jumping to bookmarks with all (*), or some (+), of a
given set of tags.

`C-x j t % *' and `C-x j t % +' are prefix keys for
jumping to bookmarks with tags, all, or some, of which
match a given regexp.  `%' for regexp, `*' for all
(Boolean multiplication), `+' for some (Boolean
addition).

And so on.  These bindings are mnemonic, but more
importantly, they're grouped so you can easily move a
group to a different prefix key or a global keymap
instead.

Without using prefix keys, there's no way I could
provide key bindings for so many commands, let alone
do so in an organized way (discoverable, mnemonic).
____

Now imagine that keys aren't reserved by Emacs this
way - repeatable keys for repeatable commands, and
some keys available to be used as prefix keys.

Imagine if Emacs just predefined `C-x' for a single
command (e.g. `cut').  Zillions of keys bound to
keymaps under `C-x' would be sacrificed.

At the very least, when a new key is decided to be
sacrificed by default (vanilla Emacs), it had better
be bound to a repeatable command, not one (such as
`cut') that it makes no sense to repeat.  And even a
repeatable key is a sacrifice - consider if `C-x' were
bound to, say, `forward-word'.  Repeatable, yes, but
think of all the bindings now under `C-x' that would
be sacrificed.

Keyboard keys are precious - scarce.  Too many have
already been sacrificed to default bindings, I think.
Sure, any user or library can redefine any keys.  But
once blessed as a default vanilla-Emacs key binding, a
key is, for practical purposes, kinda off limits for a
library.

For example, for years I had `bookmark-map' on prefix
`C-x p'.  I had to change that recently to `C-x x'
because Emacs decided to co-opt `C-x p' (& `C-x 4 p')
for keys for library `project.el'.  (Luckily `C-x x'
was still available.)

And for years I've had `Do Re Mi' commands on prefix
key `C-x t'.  I'll now have to change that to some
other prefix key, as Emacs has decided to co-opt that
prefix for `tab-bar-mode' keys.

That's fine.  At least Emacs is doing the right thing
by using prefix keys (and not top-level keys, which
are typically repeatable, but keys under `C-x').

The point is that (1) it's easy to move a keymap from
one prefix key to another, and (2) there need to be
some prefix keys available to move maps to.

Eventually, I imagine that some simple, repeatable
keys that have been assigned default Emacs bindings
for commands that aren't repeatable, or that aren't
super useful, or that don't really need a single-key
binding, will be recycled and put to better use: for
repeatable commands, as prefix keys, or just unbound
by default and left available for libraries.

No, I don't have particular suggestions, and no, it's
not urgent.

But consider `M-!', for example.  Sure, `!' is
mnemonic for shell.  But `M-!' is repeatable (just
hold it down), and it makes no sense to repeat
`shell-command'.  There are other default key bindings
like this - essentially wasted.

Some commands bound to repeatable keys should be
replaced by repeatable versions.  I do that for `C-a'
and `C-e', for example, so they're similar to `C-n'
and `C-p' (repeatable).  That kind of change is
minimal - it's the least we can do to make things a
little saner.  And `repeat-command' lets you do this
kind of thing easily.

Take a look at `C-h b', and see which repeatable keys
are bound to non-repeatable commands.  Not too many,
but there are some.

Even `C-w' is "wasted" on a non-repeatable command.
Am I suggesting `C-w' should not be bound by default
to `kill-region'?  Not really.  That's not urgent, at
least.  But hey, keys are limited - the keyboard's a
small planet. ;-)

And `beginning-of-buffer'.  That non-repeatable
command's bound by default to two repeatable keys,
`M-<' and `C-home'.  Both mnemonic (good).  But...



reply via email to

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