Speaking of Emacs...

by Erica Sadun

They didn't put the Mac in Emacs for nothing. (Dear Usual Pedants: I am aware that Emacs predates the Mac. This is an attempt at wit. A bad one, I'll give you.) Did you know that you could use Emacs navigation keys in TextEdit? And Terminal? And many other Cocoa apps? They all work the way you'd expect. Well, at least mostly. In TextEdit, ^N and ^P go to the beginning and end of word-wrapped paragraphs, not just lines.



  • ^B: Move cursor back one character

  • ^F: Move cursor forward one character

  • ^P: Move cursor up one line to previous line

  • ^N: Move cursor down one line to next line

  • ^A: Move cursor to start of line/paragraph

  • ^E: Move cursor to end of line/paragraph


  • ^D: Kill character to the right of the cursor

  • ^H: Kill character to the left of the cursor

  • ^T: Transpose the characters to the left and right of the cursor

  • ^K: Kill all text to the end of the paragraph

  • ^Y: Yank back all text from the kill buffer


  • ^V: Scroll down one page

  • ^O: Insert a line break without moving the cursor


(There's also ^L to center your selection, but I haven't seen it used in many Cocoa apps.)



Your keybindings are defined in /System/Library/Frameworks/AppKit.framework/Resources/StandardKeyBinding.dict. This Apple document shows how to expand the emacs key-bindings further.



In Terminal, use the Emacs key-bindings to scroll back and forth through your command history (^P, ^N) and to edit the contents of the current command line (^B, ^F, ^H, ^D, ^A, ^E, ^T, etc). Add ^U to the mix to clear the command-line completely.



Don't overlook the elegant double-escape completion feature that works so well with the other editing commands. For example, type % cd ~/De and then type ESC-ESC to automatically complete "Desktop".



While I'm speaking about Terminal, don't forget that you can always drop a file icon onto the command line to see its path. That includes the little icon found in the title bar of most documents, such as the ones in TextEdit. Save your text file and then move the cursor over the little icon in the title bar. Press the (left) mouse button, Wait for the icon to turn dark and then drag it out of the title bar and drop it onto the command line or into any other program for that matter. (Again, this won't work unless the document has been saved. The "saved" title bar icon is dark. The "modified" icon is slightly lighter in hue.)



Finally, for extra Terminal-fu, you may want to bone up on the "bang" commands that work in nearly all the shells provided in OS X (/bin/*sh*). !! means repeat the previous command. !-2 means repeat the command just before the previous one (aka "go back 2 items in the history list"), and !5 means do command 5 in the history list. A bang followed by a few letters searches for the previous command that started with those letters, e.g. !cc reruns the last cc command issued.



I think I'll stop now.


11 Comments

Jacob Rus
2006-05-15 12:10:50
I wrote a better explanation of how to customize the text system here: http://hcs.harvard.edu/~jrus/site/cocoa-text.html


A shortened version, with some cool stuff like setting an emacs universal argument key (NSRepeatCountBinding), etc. is at macosxhints:
http://www.macosxhints.com/article.php?story=20060317045211408


And a list of all the default bindings, including ^a, ^v, etc. is here:
http://hcs.harvard.edu/~jrus/site/system-bindings.html


There's some really remarkably powerful stuff there, and changing your bindings will work across all Cocoa apps.

Erica Sadun
2006-05-15 12:18:47
Excellent links! Thanks for sharing them.


I was a little confused by the "no backspace on mac keyboards" thing in the hsc.harvard link. Isn't the "delete" key a "backspace" key and the "del" key a delete key? (And of course for old fogies, ^H is the ultimate, true and eternal backspace key).

David Bishop
2006-05-15 13:17:40
If you like saving keystrokes, and just a little bit of 'reach', use a single TAB instead of ESC-ESC. OSX defaults to bash now, remember? :-)
Erica Sadun
2006-05-15 13:21:35
Nice! I never knew the "tab" alternative.
Joshua Emmons
2006-05-15 14:52:45
I wrote a better explanation of how to customize the text system


Don't forget the official Apple version! For the "short and to the point" crowd.

David
2006-05-15 17:25:10
> In Terminal, use the Emacs key-bindings to scroll back and forth


What you're describing isn't a feature of Terminal, but the shell you're using. Newer Macs use the BASH shell as their default shell, and the default settings on BASH set the keys to EMACS mode. You can also use the editor keys not just to edit the current command line, but to search your command history and bring up previous commands, edit them, and re-execute them.


If you prefer "vi" to "emacs", you can do a "set -o vi". Mac comes with the VI-Improved editor (better known as vim). I prefer vi to emacs because the commands are shorter, more mnemonic, and can be combined in a very logical manner to produce even more commands. Vim does syntax highlighting (which makes it very easy to find where you left off a quotation mark is shell and Perl scripts), automatic line wrapping (which unlike vi's wrapmargin, won't put a NL when it wraps the margin) smart comments, and a lot of other programming innovations.


Jacob Rus
2006-05-15 17:59:59
Erica: there's a "backspace" key code that isn't ever issued by any keyboard I've ever seen, but is still defined in the default bindings, which is why I included it in the chart, but at the bottom. The regular "backspace" key on a PC keyboard will send the "delete" key code, while the "del" key sends a "del" key code.


Joshua: the "official Apple version" was linked in the original article. Unfortunately, it's kind of ambiguous, and is both difficult for non-power-users to figure out, and doesn't cover the full power of changing key bindings. For instance, no where is it mentioned how to use the "insertText:" selector, which allows for the creation of complicated macros. For instance, I have a macro which can create an opening and closing html tag from a word, leaving the insertion point between them, tied to "⌃<". This is available in all Cocoa text fields. The bindings are flexible enough to allow some quite sophisticated macros (of course these pale in comparison to the customizability of TextMate, but they are available in all text fields, such as this one). Quite easily, I created bindings on "⌃g, a", "⌃g, b", etc. which allow the insertion of Greek letters, like so: αβγδε... It's possible to create macros for inserting commonly used symbols, like ⌘⇧⌥, or for commonly used bits of text like my address or telephone number. They can be used to remap commonly used symbols to more accessible locations, for instance, I have "⌥j" and "⌥k" insert "(" and ")", respectively, which I find much more convenient than "⇧9" and "⇧0", etc.

Erica Sadun
2006-05-15 18:12:35
Nifty! Didn't know that about the backspace.
Jeremy
2006-05-16 21:34:49
On the assumption you meant "^A and ^E go to the beginning and end of word-wrapped paragraphs, not just lines", you can make it use lines instead with:


"^a" = "moveToBeginningOfLine:";
"^e" = "moveToEndOfLine:";

Rua Haszard Morris
2006-05-21 20:19:51
I have been looking for a way to fiddle with these keybindings for a long time - thanks for posting the info.


Dang it all though they seem to work for everything except Terminal (which is where I want them!).


Anybody know why?


I want to be able to jump word-left word-right (i.e. cmd-arrow, or ctrl-arrow on windows) in Terminal. Can anybody tell me how to set this up? I'm using bash by the way (was the default with my install).

sjk
2006-05-28 02:13:42
Rua,


Word Movement in Terminal might help answer your question. And the bash man page describes how to assign keys to cursor movement functions in the ~/.inputrc file that bash uses.