emacs-devel
[Top][All Lists]
Advanced

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

Re: Key bindings proposal


From: Stephen J. Turnbull
Subject: Re: Key bindings proposal
Date: Thu, 29 Jul 2010 14:47:55 +0900

Uday S Reddy writes:
 > Stephen J. Turnbull writes:

 > > IME, users just don't do this, or want to do it; I really don't
 > > understand what you're talking about.  Please be more specific
 > > about the use cases.
 > 
 > I refer you to Teemu Likonen's post on the July 17, especially his
 > comment that "there's not enough abstraction on that front [the key
 > bindings of modes".

That's not a use case.  A use case is a specific usage or programming
problem, typically with data, which can be addressed by providing code.

As much as I respect Teemu, as a matter of free software development
practice, theoretical claims of lack of abstraction are much more
likely to be lack of understanding on the claimant's part than of
actual language design deficiencies.  The only way to demonstrate it
is to give a concrete use case showing how the abstraction could be
used to do something that cannot be done concisely in the stock
language.  It's not your job to prove it can't be done, it's our job
to show how the use case can be addressed in idiomatic, stock elisp.
But conversely, it's your job, not ours, to provide the use case.

 > In fact, a good part of the discussion in the "Emacs learning
 > curve" was about the difficulty of changing key bindings, why the
 > CUA mode can't be made the default etc.

Sure, but this is not a user use case either.  It has nothing to do
with users specifying keymaps, it's about a lack of choice of keymap.
That is because developers don't provide keymaps.

I have seen zero evidence that "redesigning the key mapping system" is
anything but a hobgoblin of lazy folks who want work done but are
unwilling to bear the burden themselves.  It's true that laziness is
the Mother of Hackerly Invention, but this is the wrong kind of
laziness.  The Keymap Problem is a *combinatorial explosion* problem,
not a *data structures + algorithms* problem.

The only way to solve the Keymap Problem is to start enumerating the
combinations.

 > At least one use case that seems to be implemented in Gnu Emacs is to
 > bind [remap undo] in modes that need it.  So, if a user binds C-z to
 > undo, he/she gets the appropriate undo in all modes (as long as they
 > use remap for the key).

Right, so users don't need to know about [remap] (in the sense above,
it is NOT a user use case), and Emacs already has the necessary
structures.  The problem is identifying more of these use cases, and
changing modes to respect them.  (N.B. Stefan has been doing this for
years; I imagine he'd appreciate help.)

 > I don't know if remap helps for rebinding C-c and C-x.  That seems
 > like too hard a problem for remap.

Again, I have no clue what you're talking about.  Is this the CUA
bogeyman again?  Several people have pointed out that rebinding C-c
and C-x are actually (conceptually) easy because they're bound to
keymap variables (not even keymaps).  The pragmatic problem is that
many modes, especially minor modes, don't use those keymaps
(especially the C-c map) properly.  A SMOP.

It might be possible to change `define-key' so that it starts in the
indicated keymap, but instead of simply installing a mapping for a key
sequence in the indicated keymap, it recurses into subkeymaps bound to
prefixes of the sequence and changes only the ultimate binding.  This
is a bit delicate because of key sequences common across modes; you'd
need to be sure you're binding the in the mode-specific keymap.

 > The current practice is not necessarily indicative of what the
 > users want to do.  Many of us expected the key bindings of Emacs to
 > be customizable, tried it, found it to be too hard and gave up.

I'm not talking about current practice, I'm talking about what
questions users post.  What did you try to customize and find to be
too hard?  Maybe the particular task *is* hard (whacking the mole aka
enumerating all combinatorial possibilities).  Maybe it's just tedious
and you lost patience, but it could easy if you asked somebody like
Stefan or Miles to cook up a helper function (eg, to swap keys is a
nearly trivial example).  But if you don't ask *here*, why would you
expect these helper functions to exist?

And I don't understand what could be so hard about keymapping.
Keymaps are a little bit complex because of inheritance.  But you
asked for inheritance and object-orientation, so I assume you
understand them.  Is it that you don't understand keymaps as objects?
Is it that whacking the mole gets tedious?

 > Some people persist because it is really important to them.  It is
 > their exasperation that keeps this debate alive.

Let them stew in their exasperation if they refuse to learn or ask to
be taught.

 > It might have been Barbara Liskov that said that the inheritance of
 > implementation is not all that interesting, but the inheritance of
 > interface is the interesting one.  A have heard the comment from a lot
 > of other people too.  So, let us take inheritance of implementation
 > for granted.  There is nothing in particular to be said about it.

The keymap, not the individual keybinding, *is* the interface, and it
*does* provide inheritance of interface, in several ways, including
via [remap].

"The" Emacs keymap is a highly compressed and dynamic specification of
how to accomplish pretty much all personal information processing
tasks without ever resorting to a named command or menu.  Note
"compressed".  Just as there really is no good way to locally edit a
zipped file -- you need to decompress, edit, and recompress it --
there is not going to be a good *universal* way to "locally edit" the
keymap.  Not *-set-key, not define-key, and not [remap].

The keymap *does* have more structure than a zipfile, of course.  For
very minor (one new keystroke) additions, there is the reserved
personal bindings C-c <letter>.  Keymaps are recursive; ie, a
keystroke may be bound to a keymap.  If you respect this structure,
you *can* do local editing of the keymap; this is precisely how minor
modes work.

But making random changes and hoping the rest of the keymap will
pure-f'cking-magically rearrange itself, sorry, All Hope Abandon Ye.

 > But I am proposing that "actions" should also be usable with the M-x
 > prefix (or some similar prefix, since people will complain if the
 > semantics of M-x is changed).  So, one should also be able to do `M-x
 > undo' in a dired buffer and get `dired-undo', and get `vm-undo' in a
 > VM buffer and so on.  This doesn't seem too hard to implement, but it
 > requires us to separate the idea of actions/interfaces from
 > keymaps.

It does not.  It is *already* implemented, cf. fill-paragraph,
comment-region, etc. etc.  I showed how to implement this in
boilerplate for "quick actions", and even pointed out that this method
probably leads to internal simplification of modes like VM and Gnus,
as well as cross-mode code sharing between them!  You've got egg in
your beer right there, what do you want, a birthday cake too?

It already dramatically sucks that other commands with substantial
commonality across modes do not share code.  The proposal to define
actions would institutionalize a worst practice, don't you see?  It
would encourage modes to write completely independent implementations
(so much for quoting Liskov; inheriting implementation is *not*
trivial; it needs to be encouraged by interface!)

 > [Why allow this?

That's not the question.  It's already allowed and encouraged, it's
just that mode writers are too lazy to do it well.

 > It would be preferable to have simpler, general action names.

You already have them, via remap.  It's just a simple matter of going
through all the keymaps and identifying the generic actions, and
replacing mode-specific bindings with remaps.  This would have to be
done with a separate action feature, too.

 > Thirdly, I am proposing that interface inheritance need not only be
 > from the global-keymap, but it could also be from generic
 > local-keymaps.

Yes, [remap] gives you that, too.

 > You asked what "quick" actions are.  They are the things that one
 > would normally bind to plain keys.

Yeah, I kinda thought you'd say something like that.  The problem is
this:

 > Actions are *not* symbols denoting functions.  They are symbols that
 > sit on their own.  They are bits of interfaces.

Well, yes, symbols sit on their own, and are interfaces.  However,
there *must* be a common functional semantics for each symbol, or
there is no point in having a common interface.

 > It is possible, as you note, to make interfaces just be ordinary
 > functions with dummy implementations.  Smalltalk did that, but I think
 > they found that the take-up was sporadic.  Most developers just did
 > implementation-inheritance and didn't bother with interface
 > inheritance.  On the other hand, when Java added interfaces as a first
 > class concept, it had better success with the take-up.

Ah, I see.  Your true goal here is to make programming in Emacs LISP
at least as painful as programming in Java.  Good luck getting takeup
on that! :-)

The point is that unless you make actions *mandatory*, as Java does
(and as C++ does), you still won't get any takeup, because it's a
*rule*, and if there's one thing Emacs hackers have trouble doing,
it's following rules.

BTW, I'm not so sure about the success of Java interfaces.  From
comments on various VCS lists (!), I gather that arsing around with
interfaces is one of the most enthusiasm-draining tasks in Java.

 > I am not too fussed about the "quick" keyword.  It was just the first
 > thing that came to mind.  Perhaps "modal" to mean that it depends on
 > the mode.

I'm not fussed about the word, either (but "modal" is a terrible word,
since the point of having common actions is the commonality across
modes, not the differences).  I'm fussed about the ambiguity and the
lack of a list.  Don't you see, the whole problem is constructing the
list?  The rest is a SMOP.  And in this case the MOP truly is S.  It's
also VT (for very tedious).

 > I am hoping that we all don't have to agree on the keys.

For remap, there needs to be a default binding, or it won't work.

In the case of a separate set of actions, you don't need to agree on
keys, that's true.  The tradeoff is that the most likely outcome will
be that 3rd party modes will define their own actions rather than look
up the generic ones.  Cf. /usr/include/X11/*key*.h.  So you'll need to
do substantial work defining them, and educating mode hackers to use
them.  Cf. "Emacs hackers and rules" above.  I don't envy you that
task. ;-)

Note that you also have to define the interface to each action.  Users
will not be pleased to discover that C-u C-z means something quite
different (eg, redo vs. undo 4 times) when in VM than when in Gnus.
One advantage of the remap approach is that generally there will be
existing default implementations that can be overridden.

 > The whole idea is to empower the user to allow for his/her favorite
 > key bindings.

That idea is dead in the water, and sinking fast.  By your own
testimony, you weren't able to do that.  In general, the best that
users will be able to do is select from a menu of pre-designed
keymaps.  A few users will do things like swap bindings they use
frequently with more convenient keys whose bindings they don't use
much, but that's probably as far as it will go.

What *can* happen here is to make the task of designing keymaps a
little more attractive to developers, since setting up a new keymap
based on an existing group of generic commands or actions will work
for all modes using that group of generic commands.  Specifically, it
might make sense for somebody to design a quick-action-map as you
suggest, and then graft that on to VM, Gnus, dired, PCL-CVS, etc.

I suspect you will find that process a lot more painful than you
expect, though.

 > But the actions, we would have to agree on, as far as the common
 > actions go.  That seems nontrivial, but not insurmountable.

Agreed.




reply via email to

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