Emacs Find of the Day: Repeating Commands

One thing that I love about Emacs is that even after 20 years, I’m finding new (old, in actuality) functionality that makes my life better.

Today’s example is repeat-complex-command, which is normally bound to ctrl-x ESC ESC, as noted on the emacs wiki. The problem in my world is that I’m also using CUA mode, from the ergoemacs library, which redefines ctrl-x to do cuts (as in cut, copy, paste).

Normally that doesn’t cause an issue, since if you don’t have a region marked, then ctrl-x is apparently ignored by ergoemacs and is delegated to the default behavior, in which case ctrl-x ESC ESC brings up the previous command in the echo area, ready to be edited.

However, what has arisen as a nuisance in my experience is when I’ve done a search and replace in one region, then want to do a similar but not identical search and replace in a different region, such as renaming variables in two methods.

Normally I’d mark the first method, run search and replace (query-replace or query-replace-regexp), then go to the second method and mark it. At that point I’d like to bring up the previous search-and-replace and modify the command, but when I hit ctrl-x, the currently-marked region (the second method in this example) is cut, per behavior from ergoemacs.

The fix is to map a different key, in my case alt-j alt-j (the mnemonic being that the keys repeat) mapped to repeat-complex-command, per this snippet from my .emacs file(s):

(define-key global-map (kbd "M-j") jep:keymap)
(define-key global-map (kbd "C-j") jep:keymap)

;; CUA settings muck up ctrl-x, so use an alternative, alt-j alt-j:
(define-key jep:keymap (kbd "M-j") 'repeat-complex-command)

Yes, I map both alt-j and ctrl-j as equivalent keys that define my keymap, making it simpler when I have shortcuts that are prefixed with alt- and ctrl-. So alt-j alt-j flows better, as does ctrl-j ctrl-l (which inserts logging statements, if you’re wondering).

All of this is available at my github repository.

But wait — there’s more: the second nugget of the day is that after running repeat-complex-command, the echo area will display the previous command, of course. But then running alt-p will bring up the command prior to that, and alt-p the command prior to that one, etc. On the other hand, and in the opposite direction, alt-n moves forward through the list of commands.

I hope this helps, and I plan to post more about Emacs and what I find therein.

Ergonomic Emacs Keybindings

I just spent three days trying out Xah Lee’s ErgoEmacs – ergonomic Emacs keybindings – and I’ve been impressed. Easier in terms of typing, given that the most frequent commands are defined as Alt-. (where “.” is a single key) instead of as Ctrl- (or worse, Ctrl-C Ctrl-.). Thus “Emacs pinkie” is less likely, since the thumbs are more heavily used on the the Alt keys instead of the pinkies working the Ctrl keys.

Setup is trivial. Just grab the zip file, unzip it into ~/.emacs.d, and add the following to your ~/.emacs file:

(setenv "ERGOEMACS_KEYBOARD_LAYOUT" "us") ; US

;; load ErgoEmacs keybinding
(load "~/.emacs.d/ergoemacs-keybindings-5.3.9/ergoemacs-mode")

;; turn on minor mode ergoemacs-mode
(ergoemacs-mode 1)

Among the first things to do is, at least if you’re running with the default Gnome keyboard shortcuts, is to disable alt-space from raising the menu within terminals (at least, this is the case for gnome-terminal). To do this, change or disable the shortcut via Preferences > Keyboard Shortcuts > Desktop > Show the panel’s main menu. Select that, hit backspace, and it should now read “Disabled”.

ErgoEmacs is actually two modules in one: it first is, as its name says, a more ergonomically friendly version of Emacs, where commonly-used commands have easy-to-type shortcuts, that is, with the use of Alt instead of Ctrl, and by favoring the keys in the center of the keyboard, as opposed to [, ], \, ~, etc.

The second module is that it uses the now-standard (for lack of a better word) editor shortcuts for operations such as opening files, copy, cut, and paste, which is much more intuitive and consistent with other editors.

I like much of it, but have some issues. I agree that the default Emacs keybindings and behavior are difficult, overwhelming and inconsistent with other editors, and should be updated. However, as with the Qwerty keyboard, we’re essentially stuck, by “we” I mean Unix-based programmers using Emacs, especially the most experienced ones. ErgoEmacs seems designed best for people experienced with mainstream editors such as Notepad and TextMate.

Emacs is so second-nature to me that I don’t consciously know some (most?) of the key shortcuts. If you’re like that, chances are that ErgoEmacs will force you to think about the shortcuts, causing cognitive friction that will interrupt your flow. If you have RSI issues, then you’re more likely to benefit, although as a programmer, I’m typing the oddball keys ([], {}, ()) so much that it is not significant to me to have the less frequently used commands a bit easier to type. (I’d never thought of that before, but it’s another reason to like Ruby: fewer special characters, since for example blocks are delimited with “begin” and “end” instead of “{” and “}”.)

The tipping point for me against ErgoEmacs is that my shell, Z shell, does not have the equivalent shortcuts, so I would essentially have to remember two separate (and conflicting) sets of commands.

That brings me to my final point: I dislike that ErgoEmacs provides no bridge or transition period for going from standard Emacs to ErgoEmacs. I’ve read that one can provide hints (in the same way that vanilla Emacs suggests shortcuts after you’ve executed a command via the traditional (M-x whatever). Having this with out-of-the-box ErgoEmacs would have been nice.

That said, I like the principle behind ErgoEmacs, and I’ll certainly be taking some ideas from it. On that note, I’ve finally posted my Emacs environment, 16 years of cruft and all, on GitHub here. I’ll be actively refining it over the next few weeks, and intend to have it up to date and stable by the end of January.