Mailing List Archive


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

[tlug] Efficient editor keystrokes [was: How to use FF's shortcuts]



Curt Sampson writes:

 > On Wed, 8 Aug 2007, Stephen J. Turnbull wrote:
 > 
 > > More [efficient], quite possible (although the viper emulation mode
 > > is pretty good, which might wipe out that advantage entirely ;-)
 > 
 > It has one serious failure which drove me up the wall: it puts the
 > cursor on characters that don't exist. Specifically, the non-existent
 > character after the last character of the line.

Emacs edits anything including the Linux kernel and tarfiles (although
I'll grant I would not want to run the bzip2 algorithm if coded in
LISP ;-).  There is a character there, the NEW LINE FUNCTION (NLF),
and it simplifies the conceptual model to treat it as one.

I'm not sure how hard it would be to treat lines as physical records,
and ignore the NLF.  Depends on your usage, and it might be very
inefficient without changes to the low-level C code.  For example,
counting characters in Mule is in principle O(n) so we cache
positions, but even so it needs to be done in C.  If you change the
algorithm, that could be very costly if done in LISP.

 > that Emacs' LISP-like thing, bastardized as it is,

Emacs LISP is a true LISP, invented before Common LISP implementations
were freely available.  It is neither Common LISP nor Scheme, and much
the worse for that.  But it is true LISP.

In XEmacs, most Common LISP constructs are available by default; in
GNU Emacs, you can get them with by require'ing 'cl.  The main missing
feature in both cases is lexical scoping (although there is a
lexical-let hack, which nobody uses so might as well not be there),
which is a biggy, I admit.

 > > Of course 8 of them are chords, which is hard on the tendons.
 > 
 > Chords, to me, and many others, count as as many keystrokes are in the
 > chord. Let me justify it this way, and see if you agree:

I disagree.  Chords are chords, and in public should be counted as
such (rather than assigning a specific number of keystrokes), as you
can expect any two typists to hold three opinions on how to count them.

 > First, I think it's not a true chord, as in one you'd play on a piano,
 > since the order in which you press the keys is important.

True.  This never matters to me unless I *try* to press the main
character fractionally before the modifier.  [Pointed noted, but I
gather that abbreviating "ordered chord" to "chord" is acceptable, so
I'm not going to differentiate since true availability of true chords
is determined by the hardware.]

The same thing is true of uppercase and other shifted keystrokes, of
course.  Do you have a keyboard layout that makes the most commonly
used uppercase letters available as single keystrokes?  If not, would
you consider using it now that I mention it?

 > Second, a chord seems to me harder in that I now have to
 > co-ordinate the lifting off a finger from the key,

You have to do the lift, but as far as I can tell order doesn't matter.

 > > In Emacs, that's
 > >
 > > C-s foo C-s C-s M-b C-b C-SPC M-} C-w .
 > >  1   4   5   6   7   8     9  10  11 12
 > 
 > Or, if you count chords the way I (and many others!) do, ignoring having
 > to time the lift, and just looking at keypresses: [...] 19 keystrokes.

Maybe that's unfair.  I don't think the repeated control characters
should count Control as keystrokes twice.

 > In vi, where the last E is an escape:
 > 
 >      3/foo/-1c}.E
 > 
 > or 13 keystrokes (remember the shift for the '}').

So accepting your accounting, Emacs costs about 50% more than vi.
"Premature optimization is the root of all error."  (That's a joke,
you're welcome to optimize whatever you want.)  As a data point, is
this kind of operation often in your inner loop?

One thing that your example elides is the need to count "foos".  You
save about n - log n keystrokes (counting a repetition of the same
control character as one keystroke as I did above, which is reasonable
for C-s and C-r).  However, if the problem is "find nth foo and
replace, where n happens to be 3", you get 

/fooR/R/R-1c}.E

which is 16 keystrokes.  This is not a moot point; IIRC at one time
(ca. 1979) C-s was bound to a fixed search (not incremental), but the
incremental search was found to be more efficient so it was changed.
If C-s were a fixed search, then the Emacs user could save a couple
keystrokes by using ESC 3 C-s foo RET, and for large n the saving
(relative to the Emacs pattern above) would be proportional to n.
(ESC 3 C-s would not give three repetitions, rather it gives an
incremental regexp search, which is pretty cool.)

 > Of course, you also need to consider what kind of reach you need for the
 > keystrokes, and the right-left balance,

Not according to RMS. :-(  He's paid for his error, though.

 > In general, watching what appear to me to be good Emacs users, I find
 > them banging on or holding down arrow keys and the like quite a lot more
 > than I do.

I do that for selecting lines with Shift Arrow.  Otherwise, a *good*
Emacs user will not usually be using the arrow keys.  What you will
find me banging on repeatedly are C-s and C-r (the search keystrokes),
and C-u C-SPC, which moves to the top mark and pops it off the mark
stack.

In general, you should *not* use position-based navigation in Emacs.
It's much more efficient to use content-based navigation and
mark-based navigation to get "close" to where you want to be.  This
can be further optimized by use of syntax-based navigation for fine
positioning.  Emacs has commands for motion (and therefore marking,
and often deletion and transposition) by words, sentences, paragraphs,
and sexps, at least.  Some modes (like PSGML) add more.  Granted, most
people, even those who generally are pretty efficient users, never
make paragraphs and sexps part of their daily repertoire (except that
movement by sexp is an essential part of debugging mismatched parens
in LISP, so everybody learns to use it for that).

The other key sequence that you will see me repeat a lot is C-x e,
which is "execute macro".

 > Then again, for most users, the whole point may be moot. My friend Perry
 > Metzger once claimed to me that you will never become a good Emacs user
 > if you didn't learn it before you were fifteen, and I can believe the
 > same of vi.

You'll probably never become a Leonard Bernstein or even a George
Winston, true.  But you can become a good user if you kaizen your
usage, in the same way that you kaizen your coding process.

 > It's not likely to happen because what expert Emacs user is likely
 > to want to stand around behind me for several weeks answering
 > questions such as, "how do I move to the space before third
 > instance of the word 'foo' ahead of the cursor and replace the rest
 > of the the paragraph with a period?"

Well, in most cases it's obvious, and Emacs bindings are pretty
orthogonal, though the "mnemonic" part is often unintuitive.  If
C-CHAR operates by characters, then M-CHAR operates by words and
C-M-CHAR operates by sexps.  A similar relationship holds for lines,
sentences, and defuns.  (IIRC this is not an advantage over vi, which
is even more orthogonal, except that there are abbreviations for the
most common operations on the most common objects.)

If you can guess the name of a command (normally not hard, something
like "forward-paragraph" is easy to guess, no?), then M-x
forward-paragraph RET will do what you want, and will also inform you
that it's bound to "M-}, M-down, M-kp-down".  So it is fairly easy to
optimize your Emacs usage compared to vi, I think, because of the many
ways available to introspect Emacs's UI.

Where things get hard is when something like that becomes part of the
inner loop, and you need to do it in a macro-friendly way.  That is
something of an art, and I think that's a reason why most Emacs users
don't learn to use them effectively.  (Another issue is that they are
pretty ephemeral, although you can name them it's not as transparent
as I would like, and having more than one available at a time requires
manual management with little help from Emacs.)



Home | Main Index | Thread Index

Home Page Mailing List Linux and Japan TLUG Members Links