Medium 9781565922617

Writing GNU Emacs Extensions: Editor Customizations and Creations with LISP

Views: 945
Ratings: (0)

Yes, it is possible to be all things to all people, if you're talking about the Emacs editor. As a user, you can make any kind of customization you want, from choosing the keystrokes that invoke your favorite commands to creating a whole new work environment that looks like nothing ever developed before. It's all in Emacs Lisp -- and in this short but fast-paced book.GNU Emacs is more than an editor; it's a programming environment, a communications package, and many other things. To provide such a broad range of functions, it offers a full version of the Lisp programming language -- something much more powerful than the little macro languages provided in other editors (including older versions of Emacs). GNU Emacs is a framework in which you can create whole new kinds of editors or just alter aspects of the many functions it already provides.In this book, Bob Glickstein delves deep into the features that permit far-reaching Emacs customizations. He teaches you the Lisp language and discusses Emacs topics (such as syntax tables and macro templates) in easy-to-digest portions. Examples progress in complexity from simple customizations to extensive major modes.You will learn how to write interactive commands, use hooks and advice, perform error recovery, manipulate windows, buffers, and keymaps, exploit and alter Emacs's main loop, and more. Each topic is explored through realistic examples and a series of successive refinements that illustrate not only the Emacs Lisp language, but the development process as well, making learning pleasant and natural.

List price: $25.99

Your Price: $20.79

You Save: 20%


15 Slices

Format Buy Remix

1. Customizing Emacs


In this chapter:

Backspace and Delete


Keys and Strings

To What Is C-h Bound?

To What Should C-h Be Bound?

Evaluating Lisp Expressions


This chapter introduces basic Emacs customizations, and teaches some Emacs Lisp along the way. One of the simplest and most common customizations is to move commands from one key to another. Perhaps you don't like Emacs's two-key sequence for saving files (C-x C-s) because you've been using some other editor where save is simply C-s. Or perhaps you sometimes accidentally type C-x C-c, which exits Emacs, when you mean to press only C-x, and you'd like accidental presses of C-x C-c to have a less drastic effect. Or perhaps, as in the example that follows, you need to work around an unusual expectation that Emacs has about your keyboard.

Imagine you're typing the word "Lisp" and you accidentally type "List." To correct your typo, do you press the BACKSPACE key or the DELETE key?

The answer depends on your keyboard, but it's not merely a question of how the key is labeled. Sometimes the key is labeled "Backspace," sometimes it's labeled "Delete," sometimes "Erase," and sometimes it's not labeled with a word but has a left-pointing arrow or some other graphic. To Emacs, what matters isn't the label but the numeric character code that the key generates when pressed. Regardless of the label on the key, the "move left and erase the previous character" key may generate an ASCII "backspace" code (decimal 8, usually denoted BS) or an ASCII "delete" code (decimal 127, usually denoted DEL).


2. Simple New Commands


In this chapter:

Traversing Windows

Line-at-a-Time Scrolling

Other Cursor and Text Motion Commands

Clobbering Symbolic Links

Advised Buffer Switching

Addendum: Raw Prefix Argument

In this chapter we'll develop several very small Lisp functions and commands, introducing a wealth of concepts that will serve us when we tackle larger tasks in the chapters to follow.

When I started using Emacs, I was dissatisfied with the keybinding C-x o, other-window. It moves the cursor from one Emacs window into the next. If I wanted to move the cursor to the previous window instead, I had to invoke other-window with -1 as an argument by typing C-u - 1 C-x o, which is cumbersome. Just as cumbersome was pressing C-x o repeatedly until I cycled through all the windows and came back around to what had been the "previous" one.

What I really wanted was one keybinding meaning "next window" and a different keybinding meaning "previous window." I knew I could do this by writing some new Emacs Lisp code and binding my new functions to new keybindings. First I had to choose those keybindings. "Next" and "previous" naturally suggested C-n and C-p, but those keys are bound to next-line and previous-line and I didn't want to change them. The next best option was to use some prefix key, followed by C-n and C-p. Emacs already uses C-x as a prefix for many two-keystroke commands (such as C-x o itself), so I chose C-x C-n for "next window" and C-x C-p for "previous window."


3. Cooperating Commands


In this chapter:

The Symptom

A Cure

Generalizing the Solution

This chapter shows how to get different commands to work together by saving information in one command and retrieving it in another. The simplest way to share information is to create a variable and store a value in it. We'll certainly do that in this chapter. For instance, we'll store the current buffer position and reuse it in a later command. But we'll also learn some more sophisticated ways to preserve state, notably markers and symbol properties. We'll combine these techniques with information about buffers and windows to write a set of functions that allow you to "undo" scrolling.

You're deep into editing some complicated Lisp code. You're concentrating, juggling the tenuous connections between the conceptual structures in your brain and the glyphs that represent them on the screen. You're in a particularly tricky part when you notice a typo a few characters to the left. You mean to press C-b C-b C-b to back up and correct it, but insteadhorrors!you press C-v C-v C-v, paging the Emacs window three times, ending up light years away from the code you were editing. Your mental context is ruined as you try to figure out where the cursor was before your mistake, and why, and what you were doing there. As you scroll, or search, or cycle through the mark-ring or the undo-list trying to get back to where you were, you forget about that original typo you were trying to correct, and much later it turns into a bug in your code that takes hours to find.


4. Searching and Modifying Buffers


In this chapter:

Inserting the Current Time



There will be lots of times when you want to search through a buffer for a string, perhaps replacing it with something else. In this chapter we'll show a lot of powerful ways to do this. We'll cover the functions that perform searches and also show you how to form regular expressions, which add great flexibility to the kinds of searches you can do.

It is sometimes useful to insert the current date or time into a file as you edit it. For instance, right now, as I'm writing this, it's 10:30pm on Friday, 18 August, 1996. A few days ago, I was editing a file of Emacs Lisp code and I changed a comment that read


I placed a timestamp in the comment because it could be useful when editing that code in the future to look back and see when this change was made.

A command that merely inserts the current time is simple, once you know that the function current-time-string yields today's date and time as a string.[18]

The section More Asterisk Magic later in this chapter explains the meaning of (interactive "*") and insert.


5. Lisp Files


In this chapter:

Creating a Lisp File

Loading the File

Compiling the File


Local Variables Lists

Addendum: Security Consideration

Up to now, most of the Emacs Lisp we've written has been suitable for inclusion in your .emacs file. The alternative is to put Emacs Lisp code into files separated by functionality. This requires a little more effort to set up, but has some benefits over putting everything into .emacs:

Code in .emacs is always executed when Emacs starts up, even if it is never needed in a given session. This makes startup time longer and consumes memory. By contrast, a separate file of Lisp code can be loaded only when and if needed.

Code in .emacs typically isn't byte-compiled. Byte-compiling is the process of turning Emacs Lisp into a more efficient form that loads faster, runs faster, and uses less memory (but which, like compiled programs in other languages, contains unreadable codes that are not meant for human eyes). Byte-compiled Lisp files usually have names ending in .elc ("Emacs Lisp, compiled"), while their non-compiled counterparts usually have names ending in .el ("Emacs Lisp").


6. Lists


In this chapter:

The Simple View of Lists

List Details

Recursive List Functions

Iterative List Functions

Other Useful List Functions

Destructive List Operations

Circular Lists?!

So far, we've seen lists in a few contexts, but we haven't really explored how they work and why they're useful. Since lists are central to Lisp, this chapter provides a thorough look at this data structure.

As we've already seen, a list in Lisp is a sequence of zero or more Lisp expressions enclosed in parentheses. Lists may be nested; that is, the enclosed subexpressions may include one or more lists. Here are a few examples:

The empty list () is synonymous with the symbol nil.

The functions car and cdr [23] are used to access parts of a list: car yields the first element in a list, and cdr yields the remainder of the list (everything but the first element).

(Recall that quoting an expressioneven a complete listmeans to use that expression literally. So '(a b c) means the list containing a, b, and c, not the result of calling function a on arguments b and c.)


7. Minor Mode


In this chapter:

Paragraph Filling


Defining a Minor Mode

Mode Meat

In this chapter we'll ratchet our Emacs programming dexterity up a notch by considering times when we don't want extensions to apply to all buffers, but just to a particular type of buffer. For instance, when you're in Lisp mode it's nice to press C-M-a and have Emacs jump backwards to the beginning of the nearest function definition, but you don't want or need that ability when you're editing a textual document. The Emacs "mode" mechanism arranges things so that C-M-a does its magic only when you're in Lisp mode.

The subject of modes in Emacs is a complex one. We'll ease into it by first studying so-called minor modes. A minor mode coexists with a major mode in a buffer, adding a typically small amount of new editing behavior. Every Emacs user is familiar with major modes like Lisp and C and Text, but they may not be aware of little strings that appear on the "mode line" saying things like Fill when you're also in Auto Fill minor mode.


8. Evaluation and Error Recovery


In this chapter:



Macro Functions

Backquote and Unquote

Return Value

Failing Gracefully

Point Marker

In the previous chapter, we noted that save-excursion is a moderately expensive function, and we tried to reduce the number of times it is called in refill (which, since it's invoked on every buffer change, needs to be as fast as possible). Nevertheless, the code for refill contains five calls to save-excursion.

We could try to coalesce the uses of save-excursionfor example, by surrounding the entire body of refill with a call to save-excursion, discarding all the save-excursions within, and rewriting everything else to make sure the cursor is properly positioned at all times. But this would harm the clear layout of the code. Of course, clarity does sometimes have to be sacrificed in the name of optimization, but before we consider coalescing the calls to save-excursion, let's see if we can do without them. It turns out we can replace them with a different function with less overhead.


9. A Major Mode


In this chapter:

My Quips File

Major Mode Skeleton

Changing the Definition of a Paragraph

Quip Commands



Derived Modes

Writing a simple major mode is very much like writing a minor mode, which we covered in Chapter7. We'll just touch on the basic ideas of major modes in this chapter, preparing us for the creation of a substantial major modeindeed, a whole new applicationin the next chapter.

For several years I have been collecting witty quotations from various sources on the Internet, storing them in a file called Quips whose format is the same one used by the old UNIX fortune program. Each quotation is introduced by a line containing the string %%. Here's an example:


I like a man who grins when he fights.

- Winston Churchill


The human race has one really effective weapon, and that is laughter.

- Mark Twain

Apart from the %% lines, the file is completely free-form.

After my Quips file had been growing for a while, I found that I edited it a bit differently from the way I edit ordinary text files. For one thing, I frequently needed to confine my editing to a single quip in order to avoid accidentally straying into a neighboring quip. For another, whenever I needed to fill a paragraph at the beginning of a quip, I first had to separate it from the leading %% with a blank line. Otherwise, the %% would become filled as if it were part of the paragraph:


10. A Comprehensive Example


In this chapter:

New York Times Rules

Data Representation

User Interface

Setting Up the Mode

Tracking Unauthorized Changes

Parsing the Buffer

Word Finder

This chapter is the culmination of our programming examples. It is a substantial major mode implementing a crossword puzzle editorclearly a use which the designers of Emacs didn't foresee, but implementable nonetheless. The straightforwardness of designing and implementing Crossword mode demonstrates Emacs's true potential as an application-building toolkit.

After devising a data model for a crossword puzzle editing application, we'll construct a user interface for it, creating functions for displaying a representation of our data model and restricting input to the set of operations we allow on it. We'll write commands that go on the Emacs menu and commands that communicate with external processes. In doing so, we'll exploit the Lisp techniques we've learned for performing complex logic and string manipulation.

I'm a big fan of crossword puzzles. I used to do the New York Times crossword puzzle daily. I frequently found myself amazed at the skill that must go into constructing a crossword puzzle, and wanted to try my hand at it. My initial attempts were on graph paper, but I quickly found that crossword puzzle creation involves so much trial and error (at least for me) that by the time I was halfway through, my eraser would be tearing holes in the paper! I hit on the idea of writing a computer program to help me create crossword puzzles.


A. Conclusion


You are now ready to embark on your Emacs Lisp programming career. The discussion of techniques and tools in this book should accomplish for you what it took me years of experimentation to learn.

As I wrote in the Preface, this book isn't exhaustive in its coverage of the language. There are many interesting areas of Emacs Lisp we haven't covered. We haven't made use of Emacs's "selective display" facility, for example. Selective display allows you to hide and reveal individual lines or portions thereof. We haven't used "text properties" either. Text properties allow you to associate things like colors and fonts and even Lisp actions with the text in a buffer. We haven't tried to customize a mode line. We barely touched on the minibuffer and the various prompting and completion routines. We didn't even mention timers, apply, or funcall. And we've skirted the whole subject of tailoring Emacs's "undo" mechanism.

What we have done is to learn what kinds of things are possible in Emacs Lisp and what they tend to look like. We've investigated the process of developing an Emacs Lisp solution to a wide variety of problems. We've gotten a good, solid feel for where to begin, how to proceed, where to seek information, and what pitfalls to avoid.


B. Lisp Quick Reference


In this appendix:


Data Types

Control Structures

Code Objects

This appendix summarizes general Lisp syntax as used in Emacs, and some important Lisp functions. It does not summarize Emacs-specific features such as buffers, hook variables, keymaps, modes, and so on. For a complete Emacs Lisp reference, see The GNU Emacs Lisp Reference Manual. Details on obtaining it are in AppendixE.

A Lisp expression is a unit of data that can be evaluated. The expression may be composed of subexpressions, as in the cases of lists and vectors.

Every Lisp expression has a way to produce a value when evaluated. Most kinds of expression are self-evaluating, which means that they are their own value.

A Lisp expression can be treated as literal data instead of being evaluated. Non-self-evaluating expressions must be quoted in order to use them as literals and prevent them from being evaluated.

The symbol nil denotes falsehood. It is exactly the same object as the empty list, (). Every other Lisp object denotes truth, but the symbol t is reserved to mean truth anyway.


C. Debugging and Profiling


In this appendix:


The Debugger


The Profiler

This appendix describes some facilities in Emacs for testing and debugging your Lisp programs.

A Lisp expression in any buffer can be evaluated by placing the cursor at the end of the expression and pressing C-x C-e (eval-last-sexp). The keystroke M-: (eval-expression) prompts for a Lisp expression to evaluate in the minibuffer. You can also use the commands eval-region and eval-current-buffer.

The *scratch* buffer is normally in Lisp Interaction mode (and if it isn't, it can be put in that mode with M-x lisp-interaction-mode RET). In that mode, C-j is normally eval-print-last-sexp, which is like eval-last-sexp except that it also inserts the result of evaluation into the buffer. Also in Lisp Interaction mode is C-M-x, eval-defun, which evaluates the "defun" that point is in. The meaning of "defun" in this context is broad; it means the enclosing Lisp expression (if there is one) that begins with an open-parenthesis at the left margin. Finally, Lisp Interaction mode allows you to type partial Lisp symbols and complete them with M-TAB.


D. Sharing Your Code


In this appendix:

Preparing Source Files




If you write a terrific new Emacs mode, or feature, or game, or whatever, it's in the spirit of free software for you to share it with others by posting it to the gnu.emacs.sources newsgroup. This appendix describes the conventions for sharing Emacs Lisp code.

Before sharing your code with the world, it's considerate to first test it with reasonable thoroughness, fixing any bugs you happen to find. Learn more about testing and debugging in AppendixC.

Once the code is working the way you'd like it to, you should add a comment block to the beginning of each source file describing the file, its copyright (see below), its authorship, its version information, and other commentary. Here's a typical beginning:

The file should end with a comment line like this:

which will help identify the file boundary if the file is sent through email (which might cause signature and other lines to be appended).

If your package includes more than one file, it's customary to create a file called README describing the package, the files in it, and how to install it; then to combine all the files into a single distribution file with the shar program. If you don't have shar, you can obtain the GNU version; refer to AppendixE.


E. Obtaining and Building Emacs


In this appendix:

Availability of Packages

Unpacking, Building, and Installing Emacs

All the software packages described in this book, with the exception of TEX, are GNU software from the Free Software Foundation. Their software and other packages can be retrieved via anonymous FTP from the Internet site in the directory /pub/gnu. There are numerous mirror sites, information about which is in GNUinfo/FTP.

If you cannot download the packages you want from the Internet, or if you wish an easier solution, you can order software distributions from the Free Software Foundation. They are available in diskette, tape, and CD-ROM form. You can also order printed, bound copies of many GNU manuals, including several about Emacs, plus the Texinfo manual mentioned in AppendixD. For more information, including prices, contact the FSF:

The packages mentioned in this book that are available from the FSF are:

The editor itself, plus a huge number of Lisp extensions. Available in source form as file emacs-x.y.tar.gz, where x and y are the major and minor version numbers of the latest version (presently 19.34).



Print Book

Format name
File size
0 Bytes
Not Allowed
Not Allowed
Read aloud
Format name
Read aloud
In metadata
In metadata
File size
In metadata