When the Lisp interpreter evaluates a list, it looks to see whether the first symbol on the list has a function definition attached to it; or, put another way, whether the symbol points to a function definition. If it does, the computer carries out the instructions in the definition. A symbol that has a function definition is called, simply, a function (although, properly speaking, the definition is the function and the symbol refers to it.)
- Primitive Functions
- defun: The
defun
macro. - Install: Install a function definition.
- Interactive: Making a function interactive.
- Interactive Options: Different options for
interactive
. - Permanent Installation: Installing code permanently.
- let: Creating and initializing local variables.
- if: What if?
- else: If–then–else expressions.
- Truth & Falsehood: What Lisp considers false and true.
- save-excursion: Keeping track of point and buffer.
- Review
- defun Exercises
An Aside about Primitive Functions
All functions are defined in terms of other functions, except for a few primitive functions that are written in the C programming language. When you write functions’ definitions, you will write them in Emacs Lisp and use other functions as your building blocks. Some of the functions you will use will themselves be written in Emacs Lisp (perhaps by you) and some will be primitives written in C. The primitive functions are used exactly like those written in Emacs Lisp and behave like them. They are written in C so we can easily run GNU Emacs on any computer that has sufficient power and can run C.
Let me re-emphasize this: when you write code in Emacs Lisp, you do not distinguish between the use of functions written in C and the use of functions written in Emacs Lisp. The difference is irrelevant. I mention the distinction only because it is interesting to know. Indeed, unless you investigate, you won’t know whether an already-written function is written in Emacs Lisp or C.
3.1 The defun
Macro
In Lisp, a symbol such as mark-whole-buffer
has code attached to it that tells the computer what to do when the function is called. This code is called the function definition and is created by evaluating a Lisp expression that starts with the symbol defun
(which is an abbreviation for define function).
In subsequent sections, we will look at function definitions from the Emacs source code, such as mark-whole-buffer
. In this section, we will describe a simple function definition so you can see how it looks. This function definition uses arithmetic because it makes for a simple example. Some people dislike examples using arithmetic; however, if you are such a person, do not despair. Hardly any of the code we will study in the remainder of this introduction involves arithmetic or mathematics. The examples mostly involve text in one way or another.
A function definition has up to five parts following the word defun
:
The name of the symbol to which the function definition should be attached.
A list of the arguments that will be passed to the function. If no arguments will be passed to the function, this is an empty list,
()
.Documentation describing the function. (Technically optional, but strongly recommended.)
Optionally, an expression to make the function interactive so you can use it by typing
M-x
and then the name of the function; or by typing an appropriate key or keychord.
The code that instructs the computer what to do: the body of the function definition.
It is helpful to think of the five parts of a function definition as being organized in a template, with slots for each part:
1 | (defun function-name (arguments...) |
As an example, here is the code for a function that multiplies its argument by 7. (This example is not interactive. See Making a Function Interactive, for that information.)
1 | (defun multiply-by-seven (number) |
This definition begins with a parenthesis and the symbol defun
, followed by the name of the function.
The name of the function is followed by a list that contains the arguments that will be passed to the function. This list is called the argument list. In this example, the list has only one element, the symbol, number
. When the function is used, the symbol will be bound to the value that is used as the argument to the function.
Instead of choosing the word number
for the name of the argument, I could have picked any other name. For example, I could have chosen the word multiplicand
. I picked the word “number” because it tells what kind of value is intended for this slot; but I could just as well have chosen the word “multiplicand” to indicate the role that the value placed in this slot will play in the workings of the function. I could have called it foogle
, but that would have been a bad choice because it would not tell humans what it means. The choice of name is up to the programmer and should be chosen to make the meaning of the function clear.
Indeed, you can choose any name you wish for a symbol in an argument list, even the name of a symbol used in some other function: the name you use in an argument list is private to that particular definition. In that definition, the name refers to a different entity than any use of the same name outside the function definition. Suppose you have a nick-name “Shorty” in your family; when your family members refer to “Shorty”, they mean you. But outside your family, in a movie, for example, the name “Shorty” refers to someone else. Because a name in an argument list is private to the function definition, you can change the value of such a symbol inside the body of a function without changing its value outside the function. The effect is similar to that produced by a let
expression. (See let
.)
The argument list is followed by the documentation string that describes the function. This is what you see when you type C-h f and the name of a function. Incidentally, when you write a documentation string like this, you should make the first line a complete sentence since some commands, such as apropos
, print only the first line of a multi-line documentation string. Also, you should not indent the second line of a documentation string, if you have one, because that looks odd when you use C-h f (describe-function
). The documentation string is optional, but it is so useful, it should be included in almost every function you write.
The third line of the example consists of the body of the function definition. (Most functions’ definitions, of course, are longer than this.) In this function, the body is the list, (* 7 number)
, which says to multiply the value of number by 7. (In Emacs Lisp, *
is the function for multiplication, just as +
is the function for addition.)
When you use the multiply-by-seven
function, the argument number
evaluates to the actual number you want used. Here is an example that shows how multiply-by-seven
is used; but don’t try to evaluate this yet!
1 | (multiply-by-seven 3) |
The symbol number
, specified in the function definition in the next section, is bound to the value 3 in the actual use of the function. Note that although number
was inside parentheses in the function definition, the argument passed to the multiply-by-seven
function is not in parentheses. The parentheses are written in the function definition so the computer can figure out where the argument list ends and the rest of the function definition begins.
If you evaluate this example, you are likely to get an error message. (Go ahead, try it!) This is because we have written the function definition, but not yet told the computer about the definition—we have not yet loaded the function definition in Emacs. Installing a function is the process that tells the Lisp interpreter the definition of the function. Installation is described in the next section.
3.2 Install a Function Definition
If you are reading this inside of Info in Emacs, you can try out the multiply-by-seven
function by first evaluating the function definition and then evaluating (multiply-by-seven 3)
. A copy of the function definition follows. Place the cursor after the last parenthesis of the function definition and type C-x C-e. When you do this, multiply-by-seven
will appear in the echo area. (What this means is that when a function definition is evaluated, the value it returns is the name of the defined function.) At the same time, this action installs the function definition.
1 | (defun multiply-by-seven (number) |
By evaluating this defun
, you have just installed multiply-by-seven
in Emacs. The function is now just as much a part of Emacs as forward-word
or any other editing function you use. (multiply-by-seven
will stay installed until you quit Emacs. To reload code automatically whenever you start Emacs, see Installing Code Permanently.)
- Effect of installation
- Change a defun: How to change a function definition.
The effect of installation
You can see the effect of installing multiply-by-seven
by evaluating the following sample. Place the cursor after the following expression and type C-x C-e. The number 21 will appear in the echo area.
1 | (multiply-by-seven 3) |
If you wish, you can read the documentation for the function by typing C-h f (describe-function
) and then the name of the function, multiply-by-seven
. When you do this, aHelp window will appear on your screen that says:
1 | multiply-by-seven is a Lisp function. |
(To return to a single window on your screen, type C-x 1.)
3.2.1 Change a Function Definition
If you want to change the code in multiply-by-seven
, just rewrite it. To install the new version in place of the old one, evaluate the function definition again. This is how you modify code in Emacs. It is very simple.
As an example, you can change the multiply-by-seven
function to add the number to itself seven times instead of multiplying the number by seven. It produces the same answer, but by a different path. At the same time, we will add a comment to the code; a comment is text that the Lisp interpreter ignores, but that a human reader may find useful or enlightening. The comment is that this is the second version.
1 | (defun multiply-by-seven (number) ; Second version. |
The comment follows a semicolon, ‘;’. In Lisp, everything on a line that follows a semicolon is a comment. The end of the line is the end of the comment. To stretch a comment over two or more lines, begin each line with a semicolon.
See Beginning a .emacs File, and Comments, for more about comments.
You can install this version of the multiply-by-seven
function by evaluating it in the same way you evaluated the first function: place the cursor after the last parenthesis and type C-x C-e.
In summary, this is how you write code in Emacs Lisp: you write a function; install it; test it; and then make fixes or enhancements and install it again.
3.3 Make a Function Interactive
You make a function interactive by placing a list that begins with the special form interactive
immediately after the documentation. A user can invoke an interactive function by typing M-x and then the name of the function; or by typing the keys to which it is bound, for example, by typing C-n for next-line
or C-x h for mark-whole-buffer
.
Interestingly, when you call an interactive function interactively, the value returned is not automatically displayed in the echo area. This is because you often call an interactive function for its side effects, such as moving forward by a word or line, and not for the value returned. If the returned value were displayed in the echo area each time you typed a key, it would be very distracting.
- Interactive multiply-by-seven: An overview.
- multiply-by-seven in detail: The interactive version.
An Interactive multiply-by-seven
, An Overview
Both the use of the special form interactive
and one way to display a value in the echo area can be illustrated by creating an interactive version of multiply-by-seven
.
Here is the code:
1 | (defun multiply-by-seven (number) ; Interactive version. |
You can install this code by placing your cursor after it and typing C-x C-e. The name of the function will appear in your echo area. Then, you can use this code by typing C-u and a number and then typing M-x multiply-by-seven and pressing
Speaking more generally, you invoke a function like this in either of two ways:
- By typing a prefix argument that contains the number to be passed, and then typing M-x and the name of the function, as with C-u 3 M-x forward-sentence; or,
- By typing whatever key or keychord the function is bound to, as with C-u 3 M-e.
Both the examples just mentioned work identically to move point forward three sentences. (Since multiply-by-seven
is not bound to a key, it could not be used as an example of key binding.)
(See Some Keybindings, to learn how to bind a command to a key.)
A prefix argument is passed to an interactive function by typing the key followed by a number, for example, M-3 M-e, or by typing C-u and then a number, for example, C-u 3 M-e (if you type C-u without a number, it defaults to 4).
3.4 Different Options for interactive
In the example, multiply-by-seven
used "p"
as the argument to interactive
. This argument told Emacs to interpret your typing either C-u followed by a number or followed by a number as a command to pass that number to the function as its argument. Emacs has more than twenty characters predefined for use with interactive
. In almost every case, one of these options will enable you to pass the right information interactively to a function. (See Code Characters for interactive
.)
Consider the function zap-to-char
. Its interactive expression is
1 | (interactive "p\ncZap to char: ") |
The first part of the argument to interactive
is ‘p’, with which you are already familiar. This argument tells Emacs to interpret a prefix, as a number to be passed to the function. You can specify a prefix either by typing C-u followed by a number or by typing followed by a number. The prefix is the number of specified characters. Thus, if your prefix is three and the specified character is ‘x’, then you will delete all the text up to and including the third next ‘x’. If you do not set a prefix, then you delete all the text up to and including the specified character, but no more.
The ‘c’ tells the function the name of the character to which to delete.
More formally, a function with two or more arguments can have information passed to each argument by adding parts to the string that follows interactive
. When you do this, the information is passed to each argument in the same order it is specified in the interactive
list. In the string, each part is separated from the next part by a ‘\n’, which is a newline. For example, you can follow ‘p’ with a ‘\n’ and an ‘cZap to char: ’. This causes Emacs to pass the value of the prefix argument (if there is one) and the character.
In this case, the function definition looks like the following, where arg
and char
are the symbols to which interactive
binds the prefix argument and the specified character:
1 | (defun name-of-function (arg char) |
(The space after the colon in the prompt makes it look better when you are prompted. See The Definition of copy-to-buffer
, for an example.)
When a function does not take arguments, interactive
does not require any. Such a function contains the simple expression (interactive)
. The mark-whole-buffer
function is like this.
Alternatively, if the special letter-codes are not right for your application, you can pass your own arguments to interactive
as a list.
See The Definition of append-to-buffer
, for an example. See Using Interactive
, for a more complete explanation about this technique.
3.5 Install Code Permanently
When you install a function definition by evaluating it, it will stay installed until you quit Emacs. The next time you start a new session of Emacs, the function will not be installed unless you evaluate the function definition again.
At some point, you may want to have code installed automatically whenever you start a new session of Emacs. There are several ways of doing this:
- If you have code that is just for yourself, you can put the code for the function definition in your .emacs initialization file. When you start Emacs, your .emacs file is automatically evaluated and all the function definitions within it are installed. See Your .emacs File.
- Alternatively, you can put the function definitions that you want installed in one or more files of their own and use the
load
function to cause Emacs to evaluate and thereby install each of the functions in the files. See Loading Files. - Thirdly, if you have code that your whole site will use, it is usual to put it in a file called site-init.el that is loaded when Emacs is built. This makes the code available to everyone who uses your machine. (See the INSTALL file that is part of the Emacs distribution.)
Finally, if you have code that everyone who uses Emacs may want, you can post it on a computer network or send a copy to the Free Software Foundation. (When you do this, please license the code and its documentation under a license that permits other people to run, copy, study, modify, and redistribute the code and which protects you from having your work taken from you.) If you send a copy of your code to the Free Software Foundation, and properly protect yourself and others, it may be included in the next release of Emacs. In large part, this is how Emacs has grown over the past years, by donations.
3.6 let
The let
expression is a special form in Lisp that you will need to use in most function definitions.
let
is used to attach or bind a symbol to a value in such a way that the Lisp interpreter will not confuse the variable with a variable of the same name that is not part of the function.
To understand why the let
special form is necessary, consider the situation in which you own a home that you generally refer to as “the house”, as in the sentence, “The house needs painting.” If you are visiting a friend and your host refers to “the house”, he is likely to be referring to his house, not yours, that is, to a different house.
If your friend is referring to his house and you think he is referring to your house, you may be in for some confusion. The same thing could happen in Lisp if a variable that is used inside of one function has the same name as a variable that is used inside of another function, and the two are not intended to refer to the same value. The let
special form prevents this kind of confusion.
let
Prevents Confusion
The let
special form prevents confusion. let
creates a name for a local variable that overshadows any use of the same name outside the let
expression. This is like understanding that whenever your host refers to “the house”, he means his house, not yours. (Symbols used in argument lists work the same way. See The defun
Macro.)
Local variables created by a let
expression retain their value only within the let
expression itself (and within expressions called within the let
expression); the local variables have no effect outside the let
expression.
Another way to think about let
is that it is like a setq
that is temporary and local. The values set by let
are automatically undone when the let
is finished. The setting only affects expressions that are inside the bounds of the let
expression. In computer science jargon, we would say the binding of a symbol is visible only in functions called in the let
form; in Emacs Lisp, scoping is dynamic, not lexical.
let
can create more than one variable at once. Also, let
gives each variable it creates an initial value, either a value specified by you, or nil
. (In the jargon, this is binding the variable to the value.) After let
has created and bound the variables, it executes the code in the body of the let
, and returns the value of the last expression in the body, as the value of the whole let
expression. (“Execute” is a jargon term that means to evaluate a list; it comes from the use of the word meaning “to give practical effect to” (Oxford English Dictionary). Since you evaluate an expression to perform an action, “execute” has evolved as a synonym to “evaluate”.)
3.6.2 Sample let
Expression
The following expression creates and gives initial values to the two variables zebra
and tiger
. The body of the let
expression is a list which calls the message
function.
1 | (let ((zebra "stripes") |
Here, the varlist is ((zebra "stripes") (tiger "fierce"))
.
The two variables are zebra
and tiger
. Each variable is the first element of a two-element list and each value is the second element of its two-element list. In the varlist, Emacs binds the variable zebra
to the value "stripes"
9, and binds the variable tiger
to the value "fierce"
. In this example, both values are strings. The values could just as well have been another list or a symbol. The body of the let
follows after the list holding the variables. In this example, the body is a list that uses the message
function to print a string in the echo area.
You may evaluate the example in the usual fashion, by placing the cursor after the last parenthesis and typing C-x C-e. When you do this, the following will appear in the echo area:
1 | "One kind of animal has stripes and another is fierce." |
As we have seen before, the message
function prints its first argument, except for ‘%s’. In this example, the value of the variable zebra
is printed at the location of the first ‘%s’ and the value of the variable tiger
is printed at the location of the second ‘%s’.
3.6.3 Uninitialized Variables in a let
Statement
If you do not bind the variables in a let
statement to specific initial values, they will automatically be bound to an initial value of nil
, as in the following expression:
1 | (let ((birch 3) |
Here, the varlist is ((birch 3) pine fir (oak 'some))
.
If you evaluate this expression in the usual way, the following will appear in your echo area:
1 | "Here are 3 variables with nil, nil, and some value." |
In this example, Emacs binds the symbol birch
to the number 3, binds the symbols pine
and fir
to nil
, and binds the symbol oak
to the value some
.
Note that in the first part of the let
, the variables pine
and fir
stand alone as atoms that are not surrounded by parentheses; this is because they are being bound to nil
, the empty list. But oak
is bound to some
and so is a part of the list (oak 'some)
. Similarly, birch
is bound to the number 3 and so is in a list with that number. (Since a number evaluates to itself, the number does not need to be quoted. Also, the number is printed in the message using a ‘%d’ rather than a ‘%s’.) The four variables as a group are put into a list to delimit them from the body of the let
.
3.7 The if
Special Form
A third special form, in addition to defun
and let
, is the conditional if
. This form is used to instruct the computer to make decisions. You can write function definitions without using if
, but it is used often enough, and is important enough, to be included here. It is used, for example, in the code for the function beginning-of-buffer
.
The basic idea behind an if
, is that if a test is true, then an expression is evaluated. If the test is not true, the expression is not evaluated. For example, you might make a decision such as, “if it is warm and sunny, then go to the beach!”
if
in more detail
An if
expression written in Lisp does not use the word “then”; the test and the action are the second and third elements of the list whose first element is if
. Nonetheless, the test part of an if
expression is often called the if-part and the second argument is often called the then-part.
Also, when an if
expression is written, the true-or-false-test is usually written on the same line as the symbol if
, but the action to carry out if the test is true, the then-part, is written on the second and subsequent lines. This makes the if
expression easier to read.
1 | (if true-or-false-test |
The true-or-false-test will be an expression that is evaluated by the Lisp interpreter.
Here is an example that you can evaluate in the usual manner. The test is whether the number 5 is greater than the number 4. Since it is, the message ‘5 is greater than 4!’ will be printed.
1 | (if (> 5 4) ; if-part |
(The function >
tests whether its first argument is greater than its second argument and returns true if it is.) Of course, in actual use, the test in an if
expression will not be fixed for all time as it is by the expression (> 5 4)
. Instead, at least one of the variables used in the test will be bound to a value that is not known ahead of time. (If the value were known ahead of time, we would not need to run the test!)
For example, the value may be bound to an argument of a function definition. In the following function definition, the character of the animal is a value that is passed to the function. If the value bound to characteristic
is "fierce"
, then the message, ‘It is a tiger!’ will be printed; otherwise, nil
will be returned.
1 | (defun type-of-animal (characteristic) |
If you are reading this inside of GNU Emacs, you can evaluate the function definition in the usual way to install it in Emacs, and then you can evaluate the following two expressions to see the results:
1 | (type-of-animal "fierce") |
When you evaluate (type-of-animal "fierce")
, you will see the following message printed in the echo area: "It is a tiger!"
; and when you evaluate (type-of-animal "striped")
you will see nil
printed in the echo area.
if
in more detail
An if
expression written in Lisp does not use the word “then”; the test and the action are the second and third elements of the list whose first element is if
. Nonetheless, the test part of an if
expression is often called the if-part and the second argument is often called the then-part.
Also, when an if
expression is written, the true-or-false-test is usually written on the same line as the symbol if
, but the action to carry out if the test is true, the then-part, is written on the second and subsequent lines. This makes the if
expression easier to read.
1 | (if true-or-false-test |
The true-or-false-test will be an expression that is evaluated by the Lisp interpreter.
Here is an example that you can evaluate in the usual manner. The test is whether the number 5 is greater than the number 4. Since it is, the message ‘5 is greater than 4!’ will be printed.
1 | (if (> 5 4) ; if-part |
(The function >
tests whether its first argument is greater than its second argument and returns true if it is.) Of course, in actual use, the test in an if
expression will not be fixed for all time as it is by the expression (> 5 4)
. Instead, at least one of the variables used in the test will be bound to a value that is not known ahead of time. (If the value were known ahead of time, we would not need to run the test!)
For example, the value may be bound to an argument of a function definition. In the following function definition, the character of the animal is a value that is passed to the function. If the value bound to characteristic
is "fierce"
, then the message, ‘It is a tiger!’ will be printed; otherwise, nil
will be returned.
1 | (defun type-of-animal (characteristic) |
If you are reading this inside of GNU Emacs, you can evaluate the function definition in the usual way to install it in Emacs, and then you can evaluate the following two expressions to see the results:
1 | (type-of-animal "fierce") |
When you evaluate (type-of-animal "fierce")
, you will see the following message printed in the echo area: "It is a tiger!"
; and when you evaluate (type-of-animal "striped")
you will see nil
printed in the echo area.
3.7.1 The type-of-animal
Function in Detail
Let’s look at the type-of-animal
function in detail.
The function definition for type-of-animal
was written by filling the slots of two templates, one for a function definition as a whole, and a second for an if
expression.
The template for every function that is not interactive is:
1 | (defun name-of-function (argument-list) |
The parts of the function that match this template look like this:
1 | (defun type-of-animal (characteristic) |
The name of function is type-of-animal
; it is passed the value of one argument. The argument list is followed by a multi-line documentation string. The documentation string is included in the example because it is a good habit to write documentation string for every function definition. The body of the function definition consists of the if
expression.
The template for an if
expression looks like this:
1 | (if true-or-false-test |
In the type-of-animal
function, the code for the if
looks like this:
1 | (if (equal characteristic "fierce") |
Here, the true-or-false-test is the expression:
1 | (equal characteristic "fierce") |
In Lisp, equal
is a function that determines whether its first argument is equal to its second argument. The second argument is the string "fierce"
and the first argument is the value of the symbol characteristic
—in other words, the argument passed to this function.
In the first exercise of type-of-animal
, the argument "fierce"
is passed to type-of-animal
. Since "fierce"
is equal to "fierce"
, the expression, (equal characteristic "fierce")
, returns a value of true. When this happens, the if
evaluates the second argument or then-part of the if
: (message "It is a tiger!")
.
On the other hand, in the second exercise of type-of-animal
, the argument "striped"
is passed to type-of-animal
. "striped"
is not equal to "fierce"
, so the then-part is not evaluated and nil
is returned by the if
expression.
3.8 If–then–else Expressions
An if
expression may have an optional third argument, called the else-part, for the case when the true-or-false-test returns false. When this happens, the second argument or then-part of the overall if
expression is not evaluated, but the third or else-part is evaluated. You might think of this as the cloudy day alternative for the decision “if it is warm and sunny, then go to the beach, else read a book!”.
The word “else” is not written in the Lisp code; the else-part of an if
expression comes after the then-part. In the written Lisp, the else-part is usually written to start on a line of its own and is indented less than the then-part:
1 | (if true-or-false-test |
For example, the following if
expression prints the message ‘4 is not greater than 5!’ when you evaluate it in the usual way:
1 | (if (> 4 5) ; if-part |
Note that the different levels of indentation make it easy to distinguish the then-part from the else-part. (GNU Emacs has several commands that automatically indent if
expressions correctly. See GNU Emacs Helps You Type Lists.)
We can extend the type-of-animal
function to include an else-part by simply incorporating an additional part to the if
expression.
You can see the consequences of doing this if you evaluate the following version of the type-of-animal
function definition to install it and then evaluate the two subsequent expressions to pass different arguments to the function.
1 | (defun type-of-animal (characteristic) ; Second version. |
When you evaluate (type-of-animal "fierce")
, you will see the following message printed in the echo area: "It is a tiger!"
; but when you evaluate (type-of-animal "striped")
, you will see "It is not fierce!"
.
(Of course, if the characteristic were "ferocious"
, the message "It is not fierce!"
would be printed; and it would be misleading! When you write code, you need to take into account the possibility that some such argument will be tested by the if
and write your program accordingly.)
3.9 Truth and Falsehood in Emacs Lisp
There is an important aspect to the truth test in an if
expression. So far, we have spoken of “true” and “false” as values of predicates as if they were new kinds of Emacs Lisp objects. In fact, “false” is just our old friend nil
. Anything else—anything at all—is “true”.
The expression that tests for truth is interpreted as true if the result of evaluating it is a value that is not nil
. In other words, the result of the test is considered true if the value returned is a number such as 47, a string such as "hello"
, or a symbol (other than nil
) such as flowers
, or a list (so long as it is not empty), or even a buffer!
- nil explained:
nil
has two meanings.
An explanation of nil
Before illustrating a test for truth, we need an explanation of nil
.
In Emacs Lisp, the symbol nil
has two meanings. First, it means the empty list. Second, it means false and is the value returned when a true-or-false-test tests false. nil
can be written as an empty list, ()
, or as nil
. As far as the Lisp interpreter is concerned, ()
and nil
are the same. Humans, however, tend to use nil
for false and ()
for the empty list.
In Emacs Lisp, any value that is not nil
—is not the empty list—is considered true. This means that if an evaluation returns something that is not an empty list, an if
expression will test true. For example, if a number is put in the slot for the test, it will be evaluated and will return itself, since that is what numbers do when evaluated. In this conditional, the if
expression will test true. The expression tests false only when nil
, an empty list, is returned by evaluating the expression.
You can see this by evaluating the two expressions in the following examples.
In the first example, the number 4 is evaluated as the test in the if
expression and returns itself; consequently, the then-part of the expression is evaluated and returned: ‘true’ appears in the echo area. In the second example, the nil
indicates false; consequently, the else-part of the expression is evaluated and returned: ‘false’ appears in the echo area.
1 | (if 4 |
Incidentally, if some other useful value is not available for a test that returns true, then the Lisp interpreter will return the symbol t
for true. For example, the expression (> 5 4)
returns t
when evaluated, as you can see by evaluating it in the usual way:
1 | (> 5 4) |
On the other hand, this function returns nil
if the test is false.
1 | (> 4 5) |
An explanation of nil
Before illustrating a test for truth, we need an explanation of nil
.
In Emacs Lisp, the symbol nil
has two meanings. First, it means the empty list. Second, it means false and is the value returned when a true-or-false-test tests false. nil
can be written as an empty list, ()
, or as nil
. As far as the Lisp interpreter is concerned, ()
and nil
are the same. Humans, however, tend to use nil
for false and ()
for the empty list.
In Emacs Lisp, any value that is not nil
—is not the empty list—is considered true. This means that if an evaluation returns something that is not an empty list, an if
expression will test true. For example, if a number is put in the slot for the test, it will be evaluated and will return itself, since that is what numbers do when evaluated. In this conditional, the if
expression will test true. The expression tests false only when nil
, an empty list, is returned by evaluating the expression.
You can see this by evaluating the two expressions in the following examples.
In the first example, the number 4 is evaluated as the test in the if
expression and returns itself; consequently, the then-part of the expression is evaluated and returned: ‘true’ appears in the echo area. In the second example, the nil
indicates false; consequently, the else-part of the expression is evaluated and returned: ‘false’ appears in the echo area.
1 | (if 4 |
Incidentally, if some other useful value is not available for a test that returns true, then the Lisp interpreter will return the symbol t
for true. For example, the expression (> 5 4)
returns t
when evaluated, as you can see by evaluating it in the usual way:
1 | (> 5 4) |
On the other hand, this function returns nil
if the test is false.
1 | (> 4 5) |
Point and Mark
Before discussing save-excursion
, however, it may be useful first to review what point and mark are in GNU Emacs. Point is the current location of the cursor. Wherever the cursor is, that is point. More precisely, on terminals where the cursor appears to be on top of a character, point is immediately before the character. In Emacs Lisp, point is an integer. The first character in a buffer is number one, the second is number two, and so on. The function point
returns the current position of the cursor as a number. Each buffer has its own value for point.
The mark is another position in the buffer; its value can be set with a command such as C-set-mark-command
). If a mark has been set, you can use the command C-x C-x(exchange-point-and-mark
) to cause the cursor to jump to the mark and set the mark to be the previous position of point. In addition, if you set another mark, the position of the previous mark is saved in the mark ring. Many mark positions can be saved this way. You can jump the cursor to a saved mark by typing C-u C-
The part of the buffer between point and mark is called the region. Numerous commands work on the region, including center-region
, count-lines-region
, kill-region
, andprint-region
.
The save-excursion
special form saves the location of point and restores this position after the code within the body of the special form is evaluated by the Lisp interpreter. Thus, if point were in the beginning of a piece of text and some code moved point to the end of the buffer, the save-excursion
would put point back to where it was before, after the expressions in the body of the function were evaluated.
In Emacs, a function frequently moves point as part of its internal workings even though a user would not expect this. For example, count-lines-region
moves point. To prevent the user from being bothered by jumps that are both unexpected and (from the user’s point of view) unnecessary, save-excursion
is often used to keep point in the location expected by the user. The use of save-excursion
is good housekeeping.
To make sure the house stays clean, save-excursion
restores the value of point even if something goes wrong in the code inside of it (or, to be more precise and to use the proper jargon, “in case of abnormal exit”). This feature is very helpful.
In addition to recording the value of point, save-excursion
keeps track of the current buffer, and restores it, too. This means you can write code that will change the buffer and have save-excursion
switch you back to the original buffer. This is how save-excursion
is used in append-to-buffer
. (See The Definition of append-to-buffer
.)
3.10.1 Template for a save-excursion
Expression
The template for code using save-excursion
is simple:
1 | (save-excursion |
The body of the function is one or more expressions that will be evaluated in sequence by the Lisp interpreter. If there is more than one expression in the body, the value of the last one will be returned as the value of the save-excursion
function. The other expressions in the body are evaluated only for their side effects; and save-excursion
itself is used only for its side effect (which is restoring the position of point).
In more detail, the template for a save-excursion
expression looks like this:
1 | (save-excursion |
An expression, of course, may be a symbol on its own or a list.
In Emacs Lisp code, a save-excursion
expression often occurs within the body of a let
expression. It looks like this:
1 | (let varlist |
3.11 Review
In the last few chapters we have introduced a macro and a fair number of functions and special forms. Here they are described in brief, along with a few similar functions that have not been mentioned yet.
eval-last-sexp
Evaluate the last symbolic expression before the current location of point. The value is printed in the echo area unless the function is invoked with an argument; in that case, the output is printed in the current buffer. This command is normally bound to C-x C-e.
defun
Define function. This macro has up to five parts: the name, a template for the arguments that will be passed to the function, documentation, an optional interactive declaration, and the body of the definition.For example, in Emacs the function definition of
dired-unmark-all-marks
is as follows.(defun dired-unmark-all-marks () "Remove all marks from all files in the Dired buffer." (interactive) (dired-unmark-all-files ?\r))
interactive
Declare to the interpreter that the function can be used interactively. This special form may be followed by a string with one or more parts that pass the information to the arguments of the function, in sequence. These parts may also tell the interpreter to prompt for information. Parts of the string are separated by newlines, ‘\n’.Common code characters are:
b
The name of an existing buffer.f
The name of an existing file.p
The numeric prefix argument. (Note that thisp
is lower case.)r
Point and the mark, as two numeric arguments, smallest first. This is the only code letter that specifies two successive arguments rather than one.See Code Characters for ‘interactive’, for a complete list of code characters.let
Declare that a list of variables is for use within the body of the
let
and give them an initial value, eithernil
or a specified value; then evaluate the rest of the expressions in the body of thelet
and return the value of the last one. Inside the body of thelet
, the Lisp interpreter does not see the values of the variables of the same names that are bound outside of thelet
.For example,(let ((foo (buffer-name)) (bar (buffer-size))) (message "This buffer is %s and has %d characters." foo bar))
save-excursion
Record the values of point and the current buffer before evaluating the body of this special form. Restore the value of point and buffer afterward.For example,
(message "We are %d characters into this buffer." (- (point) (save-excursion (goto-char (point-min)) (point))))
if
Evaluate the first argument to the function; if it is true, evaluate the second argument; else evaluate the third argument, if there is one.The
if
special form is called a conditional. There are other conditionals in Emacs Lisp, butif
is perhaps the most commonly used.For example,(if (= 22 emacs-major-version) (message "This is version 22 Emacs") (message "This is not version 22 Emacs"))
<
>
<=
>=
The
<
function tests whether its first argument is smaller than its second argument. A corresponding function,>
, tests whether the first argument is greater than the second. Likewise,<=
tests whether the first argument is less than or equal to the second and>=
tests whether the first argument is greater than or equal to the second. In all cases, both arguments must be numbers or markers (markers indicate positions in buffers).=
The
=
function tests whether two arguments, both numbers or markers, are equal.equal
eq
Test whether two objects are the same.
equal
uses one meaning of the word “same” andeq
uses another:equal
returns true if the two objects have a similar structure and contents, such as two copies of the same book. On the other hand,eq
, returns true if both arguments are actually the same object.string<
string-lessp
string=
string-equal
The
string-lessp
function tests whether its first argument is smaller than the second argument. A shorter, alternative name for the same function (adefalias
) isstring<
.The arguments tostring-lessp
must be strings or symbols; the ordering is lexicographic, so case is significant. The print names of symbols are used instead of the symbols themselves.An empty string, ‘“”’, a string with no characters in it, is smaller than any string of characters.string-equal
provides the corresponding test for equality. Its shorter, alternative name isstring=
. There are no string test functions that correspond to >,>=
, or<=
.message
Print a message in the echo area. The first argument is a string that can contain ‘%s’, ‘%d’, or ‘%c’ to print the value of arguments that follow the string. The argument used by ‘%s’ must be a string or a symbol; the argument used by ‘%d’ must be a number. The argument used by ‘%c’ must be an ascii code number; it will be printed as the character with that ascii code. (Various other %-sequences have not been mentioned.)
setq
set
The
setq
function sets the value of its first argument to the value of the second argument. The first argument is automatically quoted bysetq
. It does the same for succeeding pairs of arguments. Another function,set
, takes only two arguments and evaluates both of them before setting the value returned by its first argument to the value returned by its second argument.buffer-name
Without an argument, return the name of the buffer, as a string.
buffer-file-name
Without an argument, return the name of the file the buffer is visiting.
current-buffer
Return the buffer in which Emacs is active; it may not be the buffer that is visible on the screen.
other-buffer
Return the most recently selected buffer (other than the buffer passed to
other-buffer
as an argument and other than the current buffer).switch-to-buffer
Select a buffer for Emacs to be active in and display it in the current window so users can look at it. Usually bound to C-x b.
set-buffer
Switch Emacs’s attention to a buffer on which programs will run. Don’t alter what the window is showing.
buffer-size
Return the number of characters in the current buffer.
point
Return the value of the current position of the cursor, as an integer counting the number of characters from the beginning of the buffer.
point-min
Return the minimum permissible value of point in the current buffer. This is 1, unless narrowing is in effect.
point-max
Return the value of the maximum permissible value of point in the current buffer. This is the end of the buffer, unless narrowing is in effect.
3.12 Exercises
- Write a non-interactive function that doubles the value of its argument, a number. Make that function interactive.
- Write a function that tests whether the current value of
fill-column
is greater than the argument passed to the function, and if so, prints an appropriate message.