An illustrated Emacs tutorial

MIT’s SIPB IAP activities page is a treasure trove of interesting stuff. Among the many classes programmed for 2007, there’s one that i’m sure will be interesting to many mew readers: Being Productive With Emacs. The good news is that you don’t need to travel to Boston to get this excellent illustrated introduction to Emacs, continued with a customization and an extension guide. Being the slides of three presentations (by Phil Sung), they’re sketchy at places, but make for a great introduction to Emacsland nonetheless, and there’s a trick or two for seasoned users as well. Recommended.

Elisp and the Lambda Calculus

This one is only for hardcore emacsers who are into programming languages theory: a lambda calculus interpreter written in Elisp by Michael Olson. Enjoy!

Gnus miscellanea

GnusI’ve spent part of the morning setting up Gnus on my OS X, to replace Mail.app and ease synchronization with my GNU/Linux boxes. I won’t enter in the details of basic Gnus setup (see, for instance, the Gnus tutorial), but offer some customization tips, and mention two of my favourite Gnus-enhancing packages (which are not OS X-specific, by the way).

First thing was to import my Mail.app mailboxes. Easy. Open the mailbox in Mail, select all messages and execute the menu command Save as... (under File); in the save dialog, be sure to select Raw Message Source. The saved file is in mbox format, a Gnus import friendly one. All you need to get those messages into Gnus is to press B f in the *Group* buffer, providing your mbox file when asked. A new group is created with all your messages. You can, for instance, mark all of them and B c to copy them in, say, a regular nnml group.

Setting Gnus to read and send messages via Gmail was also easy following the instructions here. A caveat: you’ll need also the file ssl.el from the Gnus CVS repository to make POP3 work (and of course gnutls, which i installed via the fink package gnutls14; be sure to tell Emacs about your fink path: (add-to-list 'exec-path "/sw/bin")).

With that, I had a functional Gnus running and could move on to more interesting stuff. I don’t know about you, but i absolutely need random mail signatures, selected from my growing collection. To that end, i’ve been using randomsig.el since i can remember. Just put the file in your load path (or, if you’re on Debian, install the gnus-bonus-el package), and add to your initialisation files something along the lines of:

(when (require 'randomsig nil t)
  (define-key message-mode-map (kbd "C-c s") 'randomsig-replace-sig)
  (define-key message-mode-map (kbd "C-c S") 'randomsig-select-sig)
  (require 'gnus-sum) ; probably required for `gnus-summary-save-map'
  (define-key gnus-summary-save-map "-" 'gnus/randomsig-summary-read-sig)
  (setq randomsig-dir "~/Library/Emacs/Gnus/")
  (setq randomsig-files '("signatures.txt"))
  ;; or (setq randomsig-files (randomsig-search-sigfiles))
  ;; or (setq randomsig-files 'randomsig-search-sigfiles)
  (setq message-signature 'randomsig-signature)
  (setq randomsig-delimiter-pattern "^--"))

As you can see, i put my signatures in a file called signatures.txt. Now, every time i start editing an email, a random signature taken from this file is inserted for me. If i don’t like it, i can request another one typing C-c s. And if i’m reading anything inside and Emacs buffer and find a new text to add to my signatures.txt, M-x randomsig-message-read-sig will add the region marked in the buffer to my collection. Perfect bliss.

Mail.app comes with a sophisticated search engine based on Spotlight. But i’ve noticed that i never use the 95% of its features, not to mention that it’s annoyingly slow. What i really need is a simple and quick keyword search, and i’ve had it for many years now with Gnus and nnir.el. This package provides an Emacs/Gnus front-end to several indexers, my preferred one being namazu. So, besides getting nnir.el, you’ll need to install it. In Debian, it’s as easy as installing the corresponding package (namazu2), but, theres no namazu package to be seen in fink. Fortunately, you can compile it from source just by following the instructions: they worked in my MacBook without a glitch. With namazu installed, you can index your extant email in a breeze: create a directory to hold the index files (i use ~/Library/Caches/namazu) and type:

cd ~/Library/Caches/namazu
mknmz --mailnews ~/Library/Emacs/Gnus/Mail

(using the appropriate directories, of course), and the index directory will get populated. Now, with nnir.el in your load path, tell Emacs how to find those index files:

(when (require 'nnir nil t)
  (setq nnir-search-engine 'namazu)
  (setq nnir-namazu-index-directory
        (expand-file-name "~/Library/Caches/namazu"))
  (setq nnir-namazu-remove-prefix
        (expand-file-name "~/Library/Emacs/Gnus/Mail/"))
  (setq nnir-mail-backend (nth 0 gnus-secondary-select-methods)))

(i put this code in my Gnus configuration file). We are all setup: go to the *Group* buffer and type G G to search your emails. A temporal group containing the messages that match your query will be created for you, for your browsing pleasure. Inside that group, G T will teletransport you to the original message, in case you need to recover its context. As you’ll notice, namazu searches are at least an order of magnitude faster than Spotlight.

The only bit left is to set an entry in your crontab running mknmz for you periodically (i’ve got it set up with a period of one hour). Indexing is incremental, i.e., fast. Yeah, it’s not that immediate indexing of Spotlight or Beagle, but, you know, it’s not like i get a mail every five seconds, or that i need engine to find a mail i read twenty minutes ago.

There are many other tricks to play with Gnus, but i’ll save them for future posts :-).

Simple window configuration management

Most of the time, I run Emacs in a single, maximized frame (and, sometimes, just inside a urxvt terminal). Inside that frame i create and destroy windows as needed to contain my buffers [0]. After a while working with Emacs one gets used to a fluid window setup, where windows come and go as need arises.

But I remember that in the early days I felt a bit confused: I started by creating a windows setup (split horizontally, then vertically, open files in each of the windows… that kind of thing) and was non-plussed when any operation (going to a Gnus buffer and reading messages, for instance) destroyed my carefully prepared layout. Over the years i’ve seen many a newbie feeling that way. My advice is usually to let go, and learn how to move around your windows, creating them as needed.

That said, i must admit that, sometimes, i want to recover a certain window configuration in a quick way. A particularly simple one is provided by winner-mode, a package which is part of Emacs. Winner keeps track of your window configurations, and provides functions to navigate your window configuration history.

As advertised, activating winner-mode (which is a global minor mode) is as easy as one can get: just type M-x winner-mode or put this line:

    (winner-mode 1)

in your .emacs. Use Emacs normally, and whenever one cherished window layout gets destroyed, press C-c <left> (where <left> refers to the left cursor key) to recover it–actually, this calls winner-undo, and you can invoke it as many times as you want to visit previous window configurations. As one would expect, C-c <right> (the default binding for winner-redo) navigates configurations in the opposite direction [1]. Simple and very useful, as it should be.

But maybe you want to be automatically tele-transported to a previous configuration without traversing the intermediate ones. No problem: Emacs provides functions to store and retrieve window configurations (which, in fact, are the ones winner-mode is using under the covers). You can store the current window configuration in register ‘a’ (registers are named using single letters or numbers) pressing C-x r w a, and restore it later by means of C-x r j a. Again, it’s that easy.

Although there exist several packages providing more sophisticated window management (named configs, save and restore, etc.), in my experience, the simple tricks described above are more than enough (and work out of the box in any Emacs). As always, YMMV.


[0] For those of you not familiar with Emacs lingo, an Emacs frame is what most window managers would call a window, while an Emacs window is any of the regions displaying a buffer inside a frame. Usual ways of creating windows in Emacs are C-x 2, C-x 3, C-x 4 f, and so on. See Windows and WindowsAndFrames for more.

[1] In Emacs 21, the default keybindings start with C-x instead of C-c.

Imenu, with a workaround

imenu is a very handy command i learnt not long ago. Just type M-x imenu in a source code buffer (an Elisp one, for instance) and start typing the name of a variable or function (or simply TAB for name completion). There you go: instant access to definitions in the buffer.

You can also get the list of completions in a menu item calling imenu-add-menubar-index. Or, if you want the menu to be automatically created for, say, all your C files, you can put something like

(add-hook 'c-mode-hook 'imenu-add-menubar-index)

in your initialisation files.

You can read more about imenu (which has obsoleted speedbar in my workflow) in the Emacs Wiki, including how to adapt it to your favorite language (if it’s not yet supported).

Oh, and the workaround: if you’re using Emacs 22 on Mac OS X, you may need to add this dummy definition to your .emacs to make imenu work:

(defun imenu-progress-message (a &optional c d))

(otherwise, you’ll get an error about imenu-progress-message being an invalid function).

Killing, yanking and copying lines

Kind reader William Annis noticed how clumsily i copied a line in the kill ring in my last screencast. I went to the beginning of the line (C-a), killed it (C-k) so i got it in my kill-ring, and yanked it back (C-y). Admittedly, a bit cumbersome, my only excuse being that i have this keystroke sequence hardwired in my nervous system from the dawn of my emacs times; approximately the same epoch when i put in my .emacs this setting to make kill-line eat also the final carry return:

(setq kill-whole-line t)

But, as William notices, there’re better ways of copying the current line. A quick one would be:

(defun jao-copy-line ()
  "Copy current line in the kill ring"
  (interactive)
  (kill-ring-save (line-beginning-position) 
                  (line-beginning-position 2))
  (message "Line copied"))

which can be easily extended to take as a prefix argument the number of lines to copy (with 1 as the default)

(defun jao-copy-line (arg)
  "Copy lines (as many as prefix argument) in the kill ring"
  (interactive "p")
  (kill-ring-save (line-beginning-position) 
                  (line-beginning-position (+ 1 arg)))
  (message "%d line%s copied" arg (if (= 1 arg) "" "s")))

Assign the new function to a handy shortcut, and you’re done. These functions have the additional benefit of leaving the point untouched.

Next thing you’ll do after using your new shiny shortcut will most probably be yanking those lines somewhere. And it may well happen that they’ll be mis-indented in their new location. A relatively quick way of realigning them is to take advantage of the fact that after a yank the region is set to the yanked text and use indent-region, which is bound to C-M-\. But i prefer to let Emacs do that for me, using this piece of advice in my .emacs:

(defadvice yank (after indent-region activate)
  (if (member major-mode '(emacs-lisp-mode scheme-mode lisp-mode
                           c-mode c++-mode objc-mode
                           LaTeX-mode TeX-mode))
      (indent-region (region-beginning) (region-end) nil)))

where, as you can see, i’m limiting the advice to some modes: just delete the major-mode check if you want it to work everywhere.

Type faster with Predictive

I had Predictive in my list of Emacs packages to try out and review, but Mathias Dahl has saved me the trouble by writing a nice tutorial on using Predictive, complete with screenshots and all. In a nutshell,

Predictive is a package for the GNU Emacs Editor that helps you write text faster. It does this by trying to predict what you are going to write by looking at the first few characters of each word you type, looking into a dictionary for matching words, and suggesting words from this dictionary.

Mathias goes on providing all the details you need to get stated with Predictive. Although i have not yet used it, looks pretty interesting.

predictive-02.png

Oh, as an aside, i recommend taking a look at Tony ‘Qubit’ Cubitt’s site for more Emacs (and non-Emacs) goodies, or just to enjoy a beautiful website.

Follow

Get every new post delivered to your Inbox.