home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SGI Freeware 2001 May
/
SGI Freeware 2001 May - Disc 3.iso
/
dist
/
fw_elisp-intro.idb
/
usr
/
freeware
/
info
/
emacs-lisp-intro.info-5.z
/
emacs-lisp-intro.info-5
Encoding:
Amiga
Atari
Commodore
DOS
FM Towns/JPY
Macintosh
Macintosh JP
Macintosh to JP
NeXTSTEP
RISC OS/Acorn
Shift JIS
UTF-8
Wrap
GNU Info File
|
1998-10-28
|
49.4 KB
|
1,251 lines
This is Info file emacs-lisp-intro.info, produced by Makeinfo version
1.67 from the input file emacs-lisp-intro.texi.
This is an introduction to `Programming in Emacs Lisp', for people
who are not programmers.
Edition 1.05, 21 October 1997
Copyright (C) 1990, '91, '92, '93, '94, '95, '97 Free Software
Foundation, Inc.
Permission is granted to make and distribute verbatim copies of this
manual provided the copyright notice and this permission notice are
preserved on all copies.
Permission is granted to copy and distribute modified versions of
this manual under the conditions for verbatim copying, provided also
that the sections entitled "Copying" and "GNU General Public License"
are included exactly as in the original, and provided that the entire
resulting derived work is distributed under the terms of a permission
notice identical to this one.
Permission is granted to copy and distribute translations of this
manual into another language, under the above conditions for modified
versions, except that this permission notice may be stated in a
translation approved by the Free Software Foundation.
File: emacs-lisp-intro.info, Node: beginning-of-buffer, Next: Second Buffer Related Review, Prev: insert-buffer, Up: More Complex
Complete Definition of `beginning-of-buffer'
============================================
The basic structure of the `beginning-of-buffer' function has
already been discussed. (*Note A Simplified `beginning-of-buffer'
Definition: simplified-beginning-of-buffer.) This section describes the
complex part of the definition.
As previously described, when invoked without an argument,
`beginning-of-buffer' moves the cursor to the beginning of the buffer,
leaving the mark at the previous position. However, when the command
is invoked with a number between one and ten, the function considers
that number to be a fraction of the length of the buffer, measured in
tenths, and Emacs moves the cursor that fraction of the way from the
beginning of the buffer. Thus, you can either call this function with
the key command `M-<', which will move the cursor to the beginning of
the buffer, or with a key command such as `C-u 7 M-<' which will move
the cursor to a point 70% of the way through the buffer. If a number
bigger than ten is used for the argument, it moves to the end of the
buffer.
The `beginning-of-buffer' function can be called with or without an
argument. The use of the argument is optional.
* Menu:
* Optional Arguments::
* beginning-of-buffer opt arg:: Example with optional argument.
* beginning-of-buffer complete::
File: emacs-lisp-intro.info, Node: Optional Arguments, Next: beginning-of-buffer opt arg, Prev: beginning-of-buffer, Up: beginning-of-buffer
Optional Arguments
------------------
Unless told otherwise, Lisp expects that a function with an argument
in its function definition will be called with a value for that
argument. If that does not happen, you get an error and a message that
says `Wrong number of arguments'.
However, optional arguments are a feature of Lisp: a "keyword" may
be used to tell the Lisp interpreter that an argument is optional. The
keyword is `&optional'. (The `&' in front of `optional' is part of the
keyword.) In a function definition, if an argument follows the keyword
`&optional', a value does not need to be passed to that argument when
the function is called.
The first line of the function definition of `beginning-of-buffer'
therefore looks like this:
(defun beginning-of-buffer (&optional arg)
In outline, the whole function looks like this:
(defun beginning-of-buffer (&optional arg)
"DOCUMENTATION..."
(interactive "P")
(push-mark)
(goto-char
(IF-THERE-IS-AN-ARGUMENT
FIGURE-OUT-WHERE-TO-GO
ELSE-GO-TO
(point-min))))
The function is similar to `simplified-beginning-of-buffer' except
that the `interactive' expression has `"P"' as an argument and the
`goto-char' function is followed by an if-then-else expression that
figures out where to put the cursor if there is an argument.
The `"P"' in the `interactive' expression tells Emacs to pass a
prefix argument, if there is one, to the function. A prefix argument
is made by typing the <META> key followed by a number, or by typing
`C-u' and then a number (if you don't type a number, `C-u' defaults to
4).
The true-or-false-test of the `if' expression is simple: it is
simply the argument `arg'. If `arg' has a value that is not `nil',
which will be the case if `beginning-of-buffer' is called with an
argument, then this true-or-false-test will return true and the
then-part of the `if' expression will be evaluated. On the other hand,
if `beginning-of-buffer' is not called with an argument, the value of
`arg' will be `nil' and the else-part of the `if' expression will be
evaluated. The else-part is simply `point-min', and when this is the
outcome, the whole `goto-char' expression is `(goto-char (point-min))',
which is how we saw the `beginning-of-buffer' function in its simplified
form.
File: emacs-lisp-intro.info, Node: beginning-of-buffer opt arg, Next: beginning-of-buffer complete, Prev: Optional Arguments, Up: beginning-of-buffer
`beginning-of-buffer' with an Argument
--------------------------------------
When `beginning-of-buffer' is called with an argument, an expression
is evaluated which calculates what value to pass to `goto-char'. This
expression is rather complicated at first sight. It includes an inner
`if' expression and much arithmetic. It looks like this:
(if (> (buffer-size) 10000)
;; Avoid overflow for large buffer sizes!
(* (prefix-numeric-value arg) (/ (buffer-size) 10))
(/
(+ 10
(*
(buffer-size) (prefix-numeric-value arg))) 10))
Like other complex-looking expressions, this one can be distangled by
looking at it as parts of a template, in this case, the template for an
if-then-else expression. When in skeletal form, the expression looks
like this:
(if (BUFFER-IS-LARGE
DIVIDE-BUFFER-SIZE-BY-10-AND-MULTIPLY-BY-ARG
ELSE-USE-ALTERNATE-CALCULATION
The true-or-false-test of this inner `if' expression checks the size
of the buffer. The reason for this is that version 18 Emacs Lisp uses
numbers that are no bigger than eight million or so (bigger numbers are
not needed) and in the computation that follows, Emacs might try to use
over-large numbers if the buffer were large. The term `overflow',
mentioned in the comment, means numbers that are over large.
There are two cases: if the buffer is large and if it is not.
* Menu:
* large-case:: Division and multiplication in a large buffer.
* small-case:: Functions embedded in parentheses.
File: emacs-lisp-intro.info, Node: large-case, Next: small-case, Prev: beginning-of-buffer opt arg, Up: beginning-of-buffer opt arg
What happens in a large buffer
..............................
In `beginning-of-buffer', the inner `if' expression tests whether
the size of the buffer is greater than 10,000 characters. To do this,
it uses the `>' function and the `buffer-size' function. The line
looks like this:
(if (> (buffer-size) 10000)
When the buffer is large, the then-part of the `if' expression is
evaluated. It reads like this (after formatting for easy reading):
(*
(prefix-numeric-value arg)
(/ (buffer-size) 10))
This expression is a multiplication, with two arguments to the function
`*'.
The first argument is `(prefix-numeric-value arg)'. When `"P"' is
used as the argument for `interactive', the value passed to the
function as its argument is passed a "raw prefix argument", and not a
number. (It is a number in a list.) To perform the arithmetic, a
conversion is necessary, and `prefix-numeric-value' does the job.
The second argument is `(/ (buffer-size) 10)'. This expression
divides the numeric value of the buffer by ten. This produces a number
that tells how many characters make up one tenth of the buffer size.
(In Lisp, `/' is used for division, just as `*' is used for
multiplication.)
In the multiplication expression as a whole, this amount is
multiplied by the value of the prefix argument--the multiplication
looks like this:
(* NUMERIC-VALUE-OF-PREFIX-ARG
NUMBER-OF-CHARACTERS-IN-ONE-TENTH-OF-THE-BUFFER)
If, for example, the prefix argument is `7', the one-tenth value will
be multiplied by 7 to give a position 70% of the way through the buffer.
The result of all this is that if the buffer is large, the
`goto-char' expression reads like this:
(goto-char (* (prefix-numeric-value arg)
(/ (buffer-size) 10)))
This puts the cursor where we want it.
File: emacs-lisp-intro.info, Node: small-case, Prev: large-case, Up: beginning-of-buffer opt arg
What happens in a small buffer
..............................
If the buffer contains fewer than 10,000 characters, a slightly
different computation is performed. You might think this is not
necessary, since the first computation could do the job. However, in a
small buffer, the first method may not put the cursor on exactly the
desired line; the second method does a better job.
The code looks like this:
(/ (+ 10 (* (buffer-size) (prefix-numeric-value arg))) 10))
This is code in which you figure out what happens by discovering how the
functions are embedded in parentheses. It is easier to read if you
reformat it with each expression indented more deeply than its
enclosing expression:
(/
(+ 10
(*
(buffer-size)
(prefix-numeric-value arg)))
10))
Looking at parentheses, we see that the innermost operation is
`(prefix-numeric-value arg)', which converts the raw argument to a
number. This number is multiplied by the buffer size in the following
expression:
(* (buffer-size) (prefix-numeric-value arg)
This multiplication creates a number that may be larger than the size of
the buffer--seven times larger if the argument is 7, for example. Ten
is then added to this number and finally the large number is divided by
ten to provide a value that is one character larger than the percentage
position in the buffer.
The number that results from all this is passed to `goto-char' and
the cursor is moved to that point.
File: emacs-lisp-intro.info, Node: beginning-of-buffer complete, Prev: beginning-of-buffer opt arg, Up: beginning-of-buffer
The Complete `beginning-of-buffer'
----------------------------------
Here is the complete text of the `beginning-of-buffer' function:
(defun beginning-of-buffer (&optional arg)
"Move point to the beginning of the buffer;
leave mark at previous position.
With arg N, put point N/10 of the way
from the true beginning.
Don't use this in Lisp programs!
\(goto-char (point-min)) is faster
and does not set the mark."
(interactive "P")
(push-mark)
(goto-char
(if arg
(if (> (buffer-size) 10000)
;; Avoid overflow for large buffer sizes!
(* (prefix-numeric-value arg)
(/ (buffer-size) 10))
(/ (+ 10 (* (buffer-size)
(prefix-numeric-value arg)))
10))
(point-min)))
(if arg (forward-line 1)))
Except for two small points, the previous discussion shows how this
function works. The first point deals with a detail in the
documentation string, and the second point concerns the last line of
the function.
In the documentation string, there is reference to an expression:
\(goto-char (point-min))
A `\' is used before the first parenthesis of this expression. This
`\' tells the Lisp interpreter that the expression should be printed as
shown in the documentation rather than evaluated as a symbolic
expression, which is what it looks like.
Finally, the last line of the `beginning-of-buffer' command says to
move point to the beginning of the next line if the command is invoked
with an argument:
(if arg (forward-line 1)))
This puts the cursor at the beginning of the first line after the
appropriate tenths position in the buffer. This is a flourish that
means that the cursor is always located *at least* the requested tenths
of the way through the buffer, which is a nicety that is, perhaps, not
necessary, but which, if it did not occur, would be sure to draw
complaints.
File: emacs-lisp-intro.info, Node: Second Buffer Related Review, Next: &optional Exercise, Prev: beginning-of-buffer, Up: More Complex
Review
======
Here is a brief summary of some of the topics covered in this
chapter.
`or'
Evaluate each argument in sequence, and return the value of the
first argument that is not `nil'; if none return a value that is
not `nil', return `nil'. In brief, return the first true value of
the arguments; return a true value if one *or* any of the other
are true.
`and'
Evaluate each argument in sequence, and if any are `nil', return
`nil'; if none are `nil', return the value of the last argument.
In brief, return a true value only if all the arguments are true;
return a true value if one *and* each of the others is true.
`&optional'
A keyword used to indicate that an argument to a function
definition is optional; this means that the function can be
evaluated without the argument, if desired.
`prefix-numeric-value'
Convert the `raw prefix argument' produced by `(interactive "P")'
to a numeric value.
`forward-line'
Move point forward to the beginning of the next line, or if the
argument is greater than one, forward that many lines. If it
can't move as far forward as it is supposed to, `forward-line'
goes forward as far as it can and then returns a count of the
number of additional lines it was supposed to move but couldn't.
`erase-buffer'
Delete the entire contents of the current buffer.
`bufferp'
Return `t' if its argument is a buffer; otherwise return `nil'.
File: emacs-lisp-intro.info, Node: &optional Exercise, Prev: Second Buffer Related Review, Up: More Complex
`&optional' Argument Exercise
=============================
Write an interactive function with an optional argument that tests
whether its argument, a number, is greater or less than the value of
`fill-column', and tells you which, in a message. However, if you do
not pass an argument to the function, use 56 as a default value.
File: emacs-lisp-intro.info, Node: Narrowing & Widening, Next: car cdr & cons, Prev: More Complex, Up: Top
Narrowing and Widening
**********************
Narrowing is a feature of Emacs that makes it possible for you to
focus on a specific part of a buffer, and work without accidentally
changing other parts. Narrowing is normally disabled since it can
confuse novices.
* Menu:
* narrowing advantages:: The Advantages of Narrowing
* save-restriction:: The `save-restriction' special form.
* what-line:: The number of the line that point is on.
* narrow Exercise::
File: emacs-lisp-intro.info, Node: narrowing advantages, Next: save-restriction, Prev: Narrowing & Widening, Up: Narrowing & Widening
The Advantages of Narrowing
===========================
With narrowing, the rest of a buffer is made invisible, as if it
weren't there. This is an advantage if, for example, you want to
replace a word in one part of a buffer but not in another: you narrow
to the part you want and the replacement is carried out only in that
section, not in the rest of the buffer. Searches will only work within
a narrowed region, not outside of one, so if you are fixing a part of a
document, you can keep yourself from accidentally finding parts you do
not need to fix by narrowing just to the region you want.
However, narrowing does make the rest of the buffer invisible, which
can scare people who inadvertently invoke narrowing and think they have
deleted a part of their file. Moreover, the `undo' command (which is
usually bound to `C-x u') does not turn off narrowing (nor should it),
so people can become quite desperate if they do not know that they can
return the rest of a buffer to visibility with the `widen' command.
(In Emacs version 18, the key binding for `widen' is `C-x w'; in
version 19, it is `C-x n w'.)
Narrowing is just as useful to the Lisp interpreter as to a human.
Often, an Emacs Lisp function is designed to work on just part of a
buffer; or conversely, an Emacs Lisp function needs to work on all of a
buffer that has been narrowed. The `what-line' function, for example,
removes the narrowing from a buffer, if it has any narrowing and when
it has finished its job, restores the narrowing to what it was. On the
other hand, the `count-lines' function, which is called by `what-line',
uses narrowing to restrict itself to just that portion of the buffer in
which it is interested and then restores the previous situation.
File: emacs-lisp-intro.info, Node: save-restriction, Next: what-line, Prev: narrowing advantages, Up: Narrowing & Widening
The `save-restriction' Special Form
===================================
In Emacs Lisp, you can use the `save-restriction' special form to
keep track of whatever narrowing is in effect, if any. When the Lisp
interpreter meets with `save-restriction', it executes the code in the
body of the `save-restriction' expression, and then undoes any changes
to narrowing that the code caused. If, for example, the buffer is
narrowed and the code that follows `save-restriction' gets rid of the
narrowing, `save-restriction' returns the buffer to its narrowed region
afterwards. In the `what-line' command, any narrowing the buffer may
have is undone by the `widen' command that immediately follows the
`save-restriction' command. Any original narrowing is restored just
before the completion of the function.
The template for a `save-restriction' expression is simple:
(save-restriction
BODY... )
The body of the `save-restriction' is one or more expressions that will
be evaluated in sequence by the Lisp interpreter.
Finally, a point to note: when you use both `save-excursion' and
`save-restriction', one right after the other, you should use
`save-excursion' outermost. If you write them in reverse order, you
may fail to record narrowing in the buffer to which Emacs switches
after calling `save-excursion'. Thus, when written together,
`save-excursion' and `save-restriction' should be written like this:
(save-excursion
(save-restriction
BODY...))
File: emacs-lisp-intro.info, Node: what-line, Next: narrow Exercise, Prev: save-restriction, Up: Narrowing & Widening
`what-line'
===========
The `what-line' command tells you the number of the line in which
the cursor is located. The function illustrates the use of the
`save-restriction' and `save-excursion' commands. Here is the text of
the function in full:
(defun what-line ()
"Print the current line number (in the buffer) of point."
(interactive)
(save-restriction
(widen)
(save-excursion
(beginning-of-line)
(message "Line %d"
(1+ (count-lines 1 (point)))))))
The function has a documentation line and is interactive, as you
would expect. The next two lines use the functions `save-restriction'
and `widen'.
The `save-restriction' special form notes whatever narrowing is in
effect, if any, in the current buffer and restores that narrowing after
the code in the body of the `save-restriction' has been evaluated.
The `save-restriction' special form is followed by `widen'. This
function undoes any narrowing the current buffer may have had when
`what-line' was called. (The narrowing that was there is the narrowing
that `save-restriction' remembers.) This widening makes it possible
for the line counting commands to count from the beginning of the
buffer. Otherwise, they would have been limited to counting within the
accessible region. Any original narrowing is restored just before the
completion of the function by the `save-restriction' special form.
The call to `widen' is followed by `save-excursion', which saves the
location of the cursor (i.e., of point) and of the mark, and restores
them after the code in the body of the `save-excursion' uses the
`beginning-of-line' function to move point.
(Note that the `(widen)' expression comes between `save-restriction'
and `save-excursion'. When you write the two `save- ...' expressions
in sequence, write `save-excursion' outermost.)
The last two lines of the `what-line' function are functions to
count the number of lines in the buffer and then print the number in the
echo area.
(message "Line %d"
(1+ (count-lines 1 (point)))))))
The `message' function prints a one-line message at the bottom of the
Emacs screen. The first argument is inside of quotation marks and is
printed as a string of characters. However, it may contain `%d', `%s',
or `%c' to print arguments that follow the string. `%d' prints the
argument as a decimal, so the message will say something such as `Line
243'.
The number that is printed in place of the `%d' is computed by the
last line of the function:
(1+ (count-lines 1 (point)))
What this does is count the lines from the first position of the
buffer, indicated by the `1', up to `(point)', and then add one to that
number. (The `1+' function adds one to its argument.) We add one to
it because line 2 has only one line before it, and `count-lines' counts
only the lines *before* the current line.
After `count-lines' has done it job, and the message has been
printed in the echo area, the `save-excursion' restores point and mark
to their original positions; and `save-restriction' restores the
original narrowing, if any.
File: emacs-lisp-intro.info, Node: narrow Exercise, Prev: what-line, Up: Narrowing & Widening
Exercise with Narrowing
=======================
Write a function that will display the first 60 characters of the
current buffer, even if you have narrowed the buffer to its latter half
so that the first line is inaccessible. Restore point, mark, and
narrowing. For this exercise, you need to use `save-restriction',
`widen', `goto-char', `point-min', `buffer-substring', `message', and
other functions, a whole potpourri.
File: emacs-lisp-intro.info, Node: car cdr & cons, Next: Cutting & Storing Text, Prev: Narrowing & Widening, Up: Top
`car', `cdr', `cons': Fundamental Functions
*******************************************
In Lisp, `car', `cdr', and `cons' are fundamental functions. The
`cons' function is used to construct lists, and the `car' and `cdr'
functions are used to take them apart.
In the walk through of the `copy-region-as-kill' function, we will
see `cons' as well as two variants on `cdr', namely, `setcdr' and
`nthcdr'. (*Note copy-region-as-kill::.)
* Menu:
* Strange Names:: An historical aside: why the strange names?
* car & cdr:: Functions for extracting part of a list.
* cons:: Constructing a list.
* nthcdr:: Calling `cdr' repeatedly.
* setcar:: Changing the first element of a list.
* setcdr:: Changing the rest of a list.
* cons Exercise::
File: emacs-lisp-intro.info, Node: Strange Names, Next: car & cdr, Prev: car cdr & cons, Up: car cdr & cons
Strange Names
=============
The name of the `cons' function is not unreasonable: it is an
abbreviation of the word `construct'. The origins of the names for
`car' and `cdr', on the other hand, are esoteric: `car' is an acronym
from the phrase `Contents of the Address part of the Register'; and
`cdr' (pronounced `could-er') is an acronym from the phrase `Contents
of the Decrement part of the Register'. These phrases refer to
specific pieces of hardware on the very early computer on which the
original Lisp was developed. Besides being obsolete, the phrases have
been completely irrelevant for more than 25 years to anyone thinking
about Lisp. Nonetheless, although a few brave scholars have begun to
use more reasonable names for these functions, the old terms are still
in use. In particular, since the terms are used in the Emacs Lisp
source code, we will use them in this introduction.
File: emacs-lisp-intro.info, Node: car & cdr, Next: cons, Prev: Strange Names, Up: car cdr & cons
`car' and `cdr'
===============
The `car' of a list is, quite simply, the first item in the list.
Thus the `car' of the list `(rose violet daisy buttercup)' is `rose'.
If you are reading this in Info in GNU Emacs, you can see this by
evaluating the following:
(car '(rose violet daisy buttercup))
After evaluating the expression, `rose' will appear in the echo area.
Clearly, a more reasonable name for the `car' function would be
`first' and this is often suggested.
`car' does not remove the first item from the list; it only reports
what it is. After `car' has been applied to a list, the list is still
the same as it was. In the jargon, `car' is `non-destructive'. This
feature turns out to be important.
The `cdr' of a list is the rest of the list, that is, the `cdr'
function returns the part of the list that follows the first item.
Thus, while the `car' of the list `'(rose violet daisy buttercup)' is
`rose', the rest of the list, the value returned by `cdr', is `(violet
daisy buttercup)'.
You can see this by evaluating the following in the usual way:
(cdr '(rose violet daisy buttercup))
When you evaluate this, `(violet daisy buttercup)' will appear in the
echo area.
Like `car', `cdr' does not remove any elements from the list--it
just returns a report of what the second and subsequent elements are.
Incidentally, in the example, the list of flowers is quoted. If it
were not, the Lisp interpreter would try to evaluate the list by calling
`rose' as a function. In this example, we do not want to do that.
Clearly, a more reasonable name for `cdr' would be `rest'.
(There is a lesson here: when you name new functions, consider very
carefully about what you are doing, since you may be stuck with the
names for far longer than you expect. The reason this document
perpetuates these names is that the Emacs Lisp source code uses them,
and if I did not use them, you would have a hard time reading the code;
but do please try to avoid using these terms yourself. The people who
come after you will be grateful to you.)
When `car' and `cdr' are applied to a list made up of symbols, such
as the list `(pine fir oak maple)', the element of the list returned by
the function `car' is the symbol `pine' without any parentheses around
it. `pine' is the first element in the list. However, the `cdr' of
the list is a list itself, `(fir oak maple)', as you can see by
evaluating the following expressions in the usual way:
(car '(pine fir oak maple))
(cdr '(pine fir oak maple))
On the other hand, in a list of lists, the first element is itself a
list. `car' returns this first element as a list. For example, the
following list contains three sub-lists, a list of carnivores, a list
of herbivores and a list of sea mammals:
(car '((lion tiger cheetah)
(gazelle antelope zebra)
(whale dolphin seal)))
In this case, the first element or `car' of the list is the list of
carnivores, `(lion tiger cheetah)', and the rest of the list is
`((gazelle antelope zebra) (whale dolphin seal))'.
(cdr '((lion tiger cheetah)
(gazelle antelope zebra)
(whale dolphin seal)))
It is worth saying again that `car' and `cdr' are
non-destructive--that is, they do not modify or change lists to which
they are applied. This is very important for how they are used.
Also, in the first chapter, in the discussion about atoms, I said
that in Lisp, "certain kinds of atom, such as an array, can be separated
into parts; but the mechanism for doing this is different from the
mechanism for splitting a list. As far as Lisp is concerned, the atoms
of a list are unsplittable." (*Note Lisp Atoms::.) The `car' and
`cdr' functions are used for splitting lists and are considered
fundamental to Lisp. Since they cannot split or gain access to the
parts of an array, an array is considered an atom. Conversely, the
other fundamental function, `cons', can put together or construct a
list, but not an array. (Arrays are handled by array-specific
functions. *Note Arrays: (elisp)Arrays.)
File: emacs-lisp-intro.info, Node: cons, Next: nthcdr, Prev: car & cdr, Up: car cdr & cons
`cons'
======
The `cons' function constructs lists; it is the inverse of `car' and
`cdr'. For example, `cons' can be used to make a four element list
from the three element list, `(fir oak maple)':
(cons 'pine '(fir oak maple))
After evaluating this list, you will see
(pine fir oak maple)
appear in the echo area. `cons' puts a new element at the beginning of
a list; it attaches or pushes elements onto the list.
`cons' must have a list to attach to.(1) You cannot start from
absolutely nothing. If you are building a list, you need to provide at
least an empty list at the beginning. Here is a series of `cons''s
that build up a list of flowers. If you are reading this in Info in
GNU Emacs, you can evaluate each of the expressions in the usual way;
the value is printed in this text after `=>', which you may read as
`evaluates to'.
(cons 'buttercup ())
=> (buttercup)
(cons 'daisy '(buttercup))
=> (daisy buttercup)
(cons 'violet '(daisy buttercup))
=> (violet daisy buttercup)
(cons 'rose '(violet daisy buttercup))
=> (rose violet daisy buttercup)
In the first example, the empty list is shown as `()' and a list made
up of `buttercup' followed by the empty list is constructed. As you
can see, the empty list is not shown in the list that was constructed.
All that you see is `(buttercup)'. The empty list is not counted as an
element of a list because there is nothing in an empty list. Generally
speaking, an empty list is invisible.
The second example, `(cons 'daisy '(buttercup))' constructs a new,
two element list by putting `daisy' in front of `buttercup'; and the
third example constructs a three element list by putting `violet' in
front of `daisy' and `buttercup'.
* Menu:
* length:: How to find the length of a list.
---------- Footnotes ----------
(1) Actually, you can `cons' an element to an atom to produce a
dotted pair. Dotted pairs are not discussed here; see *Note Dotted
Pair Notation: (elisp)Dotted Pair Notation.
File: emacs-lisp-intro.info, Node: length, Prev: cons, Up: cons
Find the Length of a List: `length'
-----------------------------------
You can find out how many elements there are in a list by using the
Lisp function `length', as in the following examples:
(length '(buttercup))
=> 1
(length '(daisy buttercup))
=> 2
(length (cons 'violet '(daisy buttercup)))
=> 3
In the third example, the `cons' function is used to construct a three
element list which is then passed to the `length' function as its
argument.
We can also use `length' to count the number of elements in an empty
list:
(length ())
=> 0
As you would expect, the number of elements in an empty list is zero.
An interesting experiment is to find out what happens if you try to
find the length of no list at all; that is, if you try to call `length'
without giving it an argument, not even an empty list:
(length )
What you see, if you evaluate this, is the error message
Wrong number of arguments: #<subr length>, 0
This means that the function receives the wrong number of arguments,
zero, when it expects some other number of arguments. In this case,
one argument is expected, the argument being a list whose length the
function is measuring. (Note that *one* list is *one* argument, even
if the list has many elements inside it.)
The part of the error message that says `#<subr length>' is the name
of the function. This is written with a special notation, `#<subr',
that indicates that the function `length' is one of the primitive
functions written in C rather than in Emacs Lisp. (`subr' is an
abbreviation for `subroutine'.) *Note What Is a Function?: (elisp)What
Is a Function, for more about subroutines.
File: emacs-lisp-intro.info, Node: nthcdr, Next: setcar, Prev: cons, Up: car cdr & cons
`nthcdr'
========
The `nthcdr' function is associated with the `cdr' function. What
it does is take the `cdr' of a list repeatedly.
If you take the `cdr' of the list `(pine fir oak maple)', you will
be returned the list `(fir oak maple)'. If you repeat this on what was
returned, you will be returned the list `(oak maple)'. (Of course,
repeated `cdr'ing on the original list will just give you the original
`cdr' since the function does not change the list. You need to
evaluate the `cdr' of the `cdr' and so on.) If you continue this,
eventually you will be returned an empty list, which in this case,
instead of being shown as `()' is shown as `nil'.
For review, here is a series of repeated `cdr's, the text following
the `=>' shows what is returned.
(cdr '(pine fir oak maple))
=>(fir oak maple)
(cdr '(fir oak maple))
=> (oak maple)
(cdr '(oak maple))
=>(maple)
(cdr '(maple))
=> nil
(cdr 'nil)
=> nil
(cdr ())
=> nil
You can also do several `cdr's without printing the values in
between, like this:
(cdr (cdr '(pine fir oak maple)))
=> (oak maple)
In this case, the Lisp interpreter evaluates the innermost list first.
The innermost list is quoted, so it just passes the list as it is to the
innermost `cdr'. This `cdr' passes a list made up of the second and
subsequent elements of the list to the outermost `cdr', which produces
a list composed of the third and subsequent elements of the original
list. In this example, the `cdr' function is repeated and returns a
list that consists of the original list without its first two elements.
The `nthcdr' function does the same as repeating the call to `cdr'.
In the following example, the argument 2 is passed to the function
`nthcdr', along with the list, and the value returned is the list
without its first two items, which is exactly the same as repeating
`cdr' twice on the list:
(nthcdr 2 '(pine fir oak maple))
=> (oak maple)
Using the original four element list, we can see what happens when
various numeric arguments are passed to `nthcdr', including 0, 1, and 5:
;; Leave the list as it was.
(nthcdr 0 '(pine fir oak maple))
=> (pine fir oak maple)
;; Return a copy without the first element.
(nthcdr 1 '(pine fir oak maple))
=> (fir oak maple)
;; Return a copy of the list without three elements.
(nthcdr 3 '(pine fir oak maple))
=> (maple)
;; Return a copy lacking all four elements.
(nthcdr 4 '(pine fir oak maple))
=> nil
;; Return a copy lacking all elements.
(nthcdr 5 '(pine fir oak maple))
=> nil
It is worth mentioning that `nthcdr', like `cdr', does not change
the original list--the function is non-destructive. This is in sharp
contrast to the `setcar' and `setcdr' functions.
File: emacs-lisp-intro.info, Node: setcar, Next: setcdr, Prev: nthcdr, Up: car cdr & cons
`setcar'
========
As you might guess from their names, the `setcar' and `setcdr'
functions set the `car' or the `cdr' of a list to a new value. They
actually change the original list, unlike `car' and `cdr' which leave
the original list as it was. One way to find out how this works is to
experiment. We will start with the `setcar' function.
First, we can make a list and then set the value of a variable to the
list, using the `setq' function. Here is a list of animals:
(setq animals '(giraffe antelope tiger lion))
If you are reading this in Info inside of GNU Emacs, you can evaluate
this expression in the usual fashion, by positioning the cursor after
the expression and typing `C-x C-e'. (I'm doing this right here as I
write this. This is one of the advantages of having the interpreter
built into the computing environment.)
When we evaluate the variable `animals', we see that it is bound to
the list `(giraffe antelope tiger lion)':
animals
=> (giraffe antelope tiger lion)
Put another way, the variable `animals' points to the list `(giraffe
antelope tiger lion)'.
Next, evaluate the function `setcar' while passing it two arguments,
the variable `animals' and the quoted symbol `hippopotamus'; this is
done by writing the three element list `(setcar animals 'hippopotamus)'
and then evaluating it in the usual fashion:
(setcar animals 'hippopotamus)
After evaluating this expression, evaluate the variable `animals'
again. You will see that the list of animals has changed:
animals
=> (hippopotamus antelope tiger lion)
The first element on the list, `giraffe' is replaced by `hippopotamus'.
So we can see that `setcar' did not add a new element to the list as
`cons' would have; it replaced `giraffe' with `hippopotamus'; it
*changed* the list.
File: emacs-lisp-intro.info, Node: setcdr, Next: cons Exercise, Prev: setcar, Up: car cdr & cons
`setcdr'
========
The `setcdr' function is similar to the `setcar' function, except
that the function replaces the second and subsequent elements of a list
rather than the first element.
To see how this works, set the value of the variable to a list of
domesticated animals by evaluating the following expression:
(setq domesticated-animals '(horse cow sheep goat))
If you now evaluate the list, you will be returned the list `(horse cow
sheep goat)':
domesticated-animals
=> (horse cow sheep goat)
Next, evaluate `setcdr' with two arguments, the name of the variable
which has a list as its value, and the list to which the `cdr' of the
first list will be set;
(setcdr domesticated-animals '(cat dog))
If you evaluate this expression, the list `(cat dog)' will appear in
the echo area. This is the value returned by the function. The result
we are interested in is the "side effect", which we can see by
evaluating the variable `domesticated-animals':
domesticated-animals
=> (horse cat dog)
Indeed, the list is changed from `(horse cow sheep goat)' to `(horse
cat dog)'. The `cdr' of the list is changed from `(cow sheep goat)' to
`(cat dog)'.
File: emacs-lisp-intro.info, Node: cons Exercise, Prev: setcdr, Up: car cdr & cons
Exercise
========
Construct a list of four birds by evaluating several expressions with
`cons'. Find out what happens when you `cons' a list onto itself.
Replace the first element of the list of four birds with a fish.
Replace the rest of that list with a list of other fish.
File: emacs-lisp-intro.info, Node: Cutting & Storing Text, Next: List Implementation, Prev: car cdr & cons, Up: Top
Cutting and Storing Text
************************
Whenever you cut or clip text out of a buffer with a `kill' command
in GNU Emacs, it is stored in a list and you can bring it back with a
`yank' command.
(The use of the word `kill' in Emacs for processes which specifically
*do not* destroy the values of the entities is an unfortunate
historical accident. A much more appropriate word would be `clip' since
that is what the kill commands do; they clip text out of a buffer and
put it into storage from which it can be brought back. I have often
been tempted to replace globally all occurrences of `kill' in the Emacs
sources with `clip' and all occurrences of `killed' with `clipped'.)
* Menu:
* Storing Text:: Text is stored in a list.
* zap-to-char:: Cutting out text up to a character.
* kill-region:: Cutting text out of a region.
* delete-region:: A digression into C.
* defvar:: How to give a variable an initial value.
* copy-region-as-kill:: A definition for copying text.
* cons & search-fwd Review::
* search Exercises::
File: emacs-lisp-intro.info, Node: Storing Text, Next: zap-to-char, Prev: Cutting & Storing Text, Up: Cutting & Storing Text
Storing Text in a List
======================
When text is cut out of a buffer, it is stored on a list. Successive
pieces of text are stored on the list successively, so the list might
look like this:
("a piece of text" "last piece")
The function `cons' can be used to add a piece of text to the list,
like this:
(cons "another piece"
'("a piece of text" "last piece"))
If you evaluate this expression, a list of three elements will appear in
the echo area:
("another piece" "a piece of text" "last piece")
With the `car' and `nthcdr' functions, you can retrieve whichever
piece of text you want. For example, in the following code, `nthcdr 1
...' returns the list with the first item removed; and the `car'
returns the first element of that remainder--the second element of the
original list:
(car (nthcdr 1 '("another piece"
"a piece of text"
"last piece")))
=> "a piece of text"
The actual functions in Emacs are more complex than this, of course.
The code for cutting and retrieving text has to be written so that
Emacs can figure out which element in the list you want--the first,
second, third, or whatever. In addition, when you get to the end of
the list, Emacs should give you the first element of the list, rather
than nothing at all.
The list that holds the pieces of text is called the "kill ring".
This chapter leads up to a description of the kill ring and how it is
used by first tracing how the `zap-to-char' function works. This
function uses (or `calls') a function that invokes a function that
manipulates the kill ring. Thus, before reaching the mountains, we
climb the foothills.
A subsequent chapter describes how text that is cut from the buffer
is retrieved. *Note Yanking Text Back: Yanking.
File: emacs-lisp-intro.info, Node: zap-to-char, Next: kill-region, Prev: Storing Text, Up: Cutting & Storing Text
`zap-to-char'
=============
The `zap-to-char' function is written differently in GNU Emacs
version 18 and version 19. The version 19 implementation is simpler,
and works slightly differently. We will first show the function as it
is written for version 19 and then for version 18.
The Emacs version 19 implementation of the interactive `zap-to-char'
function removes the text in the region between the location of the
cursor (i.e., of point) up to and including the next occurrence of a
specified character. The text that `zap-to-char' removes is put in the
kill ring; and it can be retrieved from the kill ring by typing `C-y'
(`yank'). If the command is given an argument, it removes text through
that number of occurrences. Thus, if the cursor were at the beginning
of this sentence and the character were `s', `Thus' would be removed.
If the argument were two, `Thus, if the curs' would be removed, up to
and including the `s' in `cursor'.
The Emacs version 18 implementation removes the text from point up to
*but not including* the specified character. Thus, in the example
shown in the previous paragraph, the `s' would *not* be removed.
In addition, the version 18 implementation will go to the end of the
buffer if the specified character is not found; but the version 19
implementation will simply generate an error (and not remove any text).
In order to determine how much text to remove, both versions of
`zap-to-char' use a search function. Searches are used extensively in
code that manipulates text, and it is worth focusing attention on the
search function as well as on the deletion command.
Here is the complete text of the version 19 implementation of the
function:
(defun zap-to-char (arg char) ; version 19 implementation
"Kill up to and including ARG'th occurrence of CHAR.
Goes backward if ARG is negative; error if CHAR not found."
(interactive "*p\ncZap to char: ")
(kill-region (point)
(progn
(search-forward
(char-to-string char) nil nil arg)
(point))))
* Menu:
* zap-to-char interactive:: A three part interactive expression.
* zap-to-char body:: A short overview.
* search-forward:: How to search for a string.
* progn:: The `progn' function.
* Summing up zap-to-char:: Using `point' and `search-forward'.
* v-18-zap-to-char:: The version 18 implementation.
File: emacs-lisp-intro.info, Node: zap-to-char interactive, Next: zap-to-char body, Prev: zap-to-char, Up: zap-to-char
The `interactive' Expression
----------------------------
The interactive expression in the `zap-to-char' command looks like
this:
(interactive "*p\ncZap to char: ")
The part within quotation marks, `"*p\ncZap to char: "', specifies
three different things. First, and most simply, the asterisk, `*',
causes an error to be signalled if the buffer is read-only. This means
that if you try `zap-to-char' in a read-only buffer you will not be
able to remove text, and you will receive a message that says "Buffer is
read-only"; your terminal may beep at you as well.
The second part of `"*p\ncZap to char: "' is the `p'. This part is
ended by a newline, `\n'. The `p' means that the first argument to the
function will be passed the value of a `processed prefix'. The prefix
argument is passed by typing `C-u' and a number, or `M-' and a number.
If the function is called interactively without a prefix, 1 is passed
to this argument.
The third part of `"*p\ncZap to char: "' is `cZap to char: '. In
this part, the lower case `c' indicates that `interactive' expects a
prompt and that the argument will be a character. The prompt follows
the `c' and is the string `Zap to char: ' (with a space after the colon
to make it look good).
What all this does is prepare the arguments to `zap-to-char' so they
are of the right type, and give the user a prompt.
File: emacs-lisp-intro.info, Node: zap-to-char body, Next: search-forward, Prev: zap-to-char interactive, Up: zap-to-char
The Body of `zap-to-char'
-------------------------
The body of the `zap-to-char' function contains the code that kills
(that is, removes) the text in the region from the current position of
the cursor up to and including the specified character. The first part
of the code looks like this:
(kill-region (point) ...
`(point)' is the current position of the cursor.
The next part of the code is an expression using `progn'. The body
of the `progn' consists of calls to `search-forward' and `point'.
It is easier to understand how `progn' works after learning about
`search-forward', so we will look at `search-forward' and then at
`progn'.
File: emacs-lisp-intro.info, Node: search-forward, Next: progn, Prev: zap-to-char body, Up: zap-to-char
The `search-forward' Function
-----------------------------
The `search-forward' function is used to locate the
zapped-for-character in `zap-to-char'. If the search is successful,
`search-forward' leaves point immediately after the last character in
the target string. (In this case the target string is just one
character long.) If the search is backwards, `search-forward' leaves
point just before the first character in the target. Also,
`search-forward' returns `t' for true. (Moving point is therefore a
`side effect'.)
In `zap-to-char', the `search-forward' function looks like this:
(search-forward (char-to-string char) nil nil arg)
The `search-forward' function takes four arguments:
1. The first argument is the target, what is searched for. This must
be a string, such as `"z"'.
As it happens, the argument passed to `zap-to-char' is a single
character. Because of the way computers are built, the Lisp
interpreter treats a single character as being different from a
string of characters. Inside the computer, a single character has
a different electronic format than a string of one character. (A
single character can often be recorded in the computer using
exactly one byte; but a string may be longer or shorter, and the
computer needs to be ready for this.) Since the `search-forward'
function searches for a string, the character that the
`zap-to-char' function receives as its argument must be converted
inside the computer from one format to the other; otherwise the
`search-forward' function will fail. The `char-to-string'
function is used to make this conversion.
2. The second argument bounds the search; it is specified as a
position in the buffer. In this case, the search can go to the
end of the buffer, so no bound is set and the second argument is
`nil'.
3. The third argument tells the function what it should do if the
search fails--it can signal an error (and print a message) or it
can return `nil'. A `nil' as the third argument causes the
function to signal an error when the search fails.
4. The fourth argument to `search-forward' is the repeat count--how
many occurrences of the string to look for. This argument is
optional and if the function is called without a repeat count,
this argument is passed the value 1. If this argument is
negative, the search goes backwards.
In template form, a `search-forward' expression looks like this:
(search-forward "TARGET-STRING"
LIMIT-OF-SEARCH
WHAT-TO-DO-IF-SEARCH-FAILS
REPEAT-COUNT)
We will look at `progn' next.