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-11.z
/
emacs-lisp-intro.info-11
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
|
47.9 KB
|
1,267 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: Text and Auto-fill, Next: Mail Aliases, Prev: Beginning a .emacs File, Up: Emacs Initialization
Text and Auto Fill Mode
=======================
Now we come to the part that `turns on' Text mode and Auto Fill mode.
;;; Text mode and Auto Fill mode
; The next two lines put Emacs into Text mode
; and Auto Fill mode, and are for writers who
; want to start writing prose rather than code.
(setq default-major-mode 'text-mode)
(add-hook 'text-mode-hook 'turn-on-auto-fill)
Here is the first part of this `.emacs' file that does something
besides remind a forgetful human!
The first of the two lines in parentheses tells Emacs to turn on Text
mode when you find a file, *unless* that file should go into some other
mode, such as C mode.
When Emacs reads a file, it looks at the extension to the file name,
if any. (The extension is the part that comes after a `.'.) If the
file ends with a `.c' or `.h' extension then Emacs turns on C mode.
Also, Emacs looks at first nonblank line of the file; if the line says
`-*- C -*-', Emacs turns on C mode. Emacs possesses a list of
extensions and specifications that it uses automatically. In addition,
Emacs looks near the last page for a per-buffer, "local variables
list", if any.
*Note How Major Modes are Chosen: (emacs)Choosing Modes.
*Note Local Variables in Files: (emacs)File Variables.
Now, back to the `.emacs' file.
Here is the line again; how does it work?
(setq default-major-mode 'text-mode)
This line is a short, but complete Emacs Lisp expression.
We are already familiar with `setq'. It sets the following variable,
`default-major-mode', to the subsequent value, which is `text-mode'.
The single quote mark before `text-mode' tells Emacs to deal directly
with the `text-mode' variable, not with whatever it might stand for.
*Note Setting the Value of a Variable: set & setq, for a reminder of
how `setq' works. The main point is that there is no difference
between the procedure you use to set a value in your `.emacs' file and
the procedure you use anywhere else in Emacs.
Here is the second line:
(add-hook 'text-mode-hook 'turn-on-auto-fill)
In this line, the `add-hook' command, adds `turn-on-auto-fill' to the
variable called `text-mode-hook'. `turn-on-auto-fill' is the name of a
program, that, you guessed it!, turns on Auto Fill mode.
Every time Emacs turns on Text mode, Emacs runs the commands `hooked'
onto Text mode. So every time Emacs turns on Text mode, Emacs also
turns on Auto Fill mode.
In brief, the first line causes Emacs to enter Text mode when you
edit a file, unless the file name extension, first non-blank line, or
local variables tell Emacs otherwise.
Text mode among other actions, sets the syntax table to work
conveniently for writers. In Text mode, Emacs considers an apostrophe
as part of a word like a letter; but Emacs does not consider a period
or a space as part of a word. Thus, `M-f' moves you over `it's'. On
the other hand, in C mode, `M-f' stops just after the `t' of `it's'.
The second line causes Emacs to turn on Auto Fill mode when it turns
on Text mode. In Auto Fill mode, Emacs automatically breaks a line
that is too wide and brings the excessively wide part of the line down
to the next line. Emacs breaks lines between words, not within them.
When Auto Fill mode is turned off, lines continue to the right as you
type them. Depending on how you set the value of `truncate-lines', the
words you type either disappear off the right side of the screen, or
else are shown, in a rather ugly and unreadable manner, as a
continuation line on the screen.
File: emacs-lisp-intro.info, Node: Mail Aliases, Next: Indent Tabs Mode, Prev: Text and Auto-fill, Up: Emacs Initialization
Mail Aliases
============
Here is a `setq' to `turn on' mail aliases, along with more
reminders.
;;; Mail mode
; To enter mail mode, type `C-x m'
; To enter RMAIL (for reading mail),
; type `M-x rmail'
(setq mail-aliases t)
This `setq' command sets the value of the variable `mail-aliases' to
`t'. Since `t' means true, the line says, in effect, "Yes, use mail
aliases."
Mail aliases are convenient short names for long email addresses or
for lists of email addresses. The file where you keep your `aliases'
is `~/.mailrc'. You write an alias like this:
alias geo george@foobar.wiz.edu
When you write a message to George, address it to `geo'; the mailer
will automatically expand `geo' to the full address.
File: emacs-lisp-intro.info, Node: Indent Tabs Mode, Next: Keybindings, Prev: Mail Aliases, Up: Emacs Initialization
Indent Tabs Mode
================
By default, Emacs inserts tabs in place of multiple spaces when it
formats a region. (For example, you might indent many lines of text
all at once with the `indent-region' command.) Tabs look fine on a
terminal or with ordinary printing, but they produce badly indented
output when you use TeX or Texinfo since TeX ignores tabs.
The following turns off Indent Tabs mode:
;;; Prevent Extraneous Tabs
(setq-default indent-tabs-mode nil)
Note that this line uses `setq-default' rather than the `setq'
command that we have seen before. The `setq-default' command sets
values only in buffers that do not have their own local values for the
variable.
*Note Tabs vs. Spaces: (emacs)Just Spaces.
*Note Local Variables in Files: (emacs)File Variables.
File: emacs-lisp-intro.info, Node: Keybindings, Next: Loading Files, Prev: Indent Tabs Mode, Up: Emacs Initialization
Some Keybindings
================
Now for some personal keybindings:
;;; Compare windows
(global-set-key "\C-cw" 'compare-windows)
`compare-windows' is a nifty command that compares the text in your
current window with text in the next window. It makes the comparison
by starting at point in each window, moving over text in each window as
far as they match. I use this command all the time.
This also shows how to set a key globally, for all modes.
The command is `global-set-key'. It is followed by the keybinding.
In a `.emacs' file, the keybinding is written as shown: `\C-c' stands
for `control-c', which means `press the control key and the `c' key at
the same time'. The `w' means `press the `w' key'. The keybinding is
surrounded by double quotation marks. In documentation, you would
write this as `C-c w'. (If you were binding a <META> key, such as
`M-c', rather than a <CTL> key, you would write `\M-c'. *Note
Rebinding Keys in Your Init File: (emacs)Init Rebinding, for details.)
The command invoked by the keys is `compare-windows'. Note that
`compare-windows' is preceded by a single quote; otherwise, Emacs would
first try to evaluate the symbol to determine its value.
These three things, the double quotation marks, the backslash before
the `C', and the single quote mark are necessary parts of keybinding
that I tend to forget. Fortunately, I have come to remember that I
should look at my existing `.emacs' file, and adapt what is there.
As for the keybinding itself: `C-c w'. This combines the prefix
key, `C-c', with a single character, in this case, `w'. This set of
keys, `C-c' followed by a single character, is strictly reserved for
individuals' own use. If you ever write an extension to Emacs, please
avoid taking any of these keys for public use. Create a key like `C-c
C-w' instead. Otherwise, we will run out of `own' keys.
Here is another keybinding, with a comment:
;;; Keybinding for `occur'
; I use occur a lot, so let's bind it to a key:
(global-set-key "\C-co" 'occur)
The `occur' command shows all the lines in the current buffer that
contain a match for a regular expression. Matching lines are shown in
a buffer called `*Occur*'. That buffer serves as a menu to jump to
occurrences.
Here is how to unbind a key, so it does not work:
;;; Unbind `C-x f'
(global-unset-key "\C-xf")
There is a reason for this unbinding: I found I inadvertently typed
`C-x f' when I meant to type `C-x C-f'. Rather than find a file, as I
intended, I accidentally set the width for filled text, almost always
to a width I did not want. Since I hardly ever reset my default width,
I simply unbound the key.
The following rebinds an existing key:
;;; Rebind `C-x C-b' for `buffer-menu'
(global-set-key "\C-x\C-b" 'buffer-menu)
By default, `C-x C-b' runs the `list-buffers' command. This command
lists your buffers in *another* window. Since I almost always want to
do something in that window, I prefer the `buffer-menu' command, which
not only lists the buffers, but moves point into that window.
File: emacs-lisp-intro.info, Node: Loading Files, Next: Autoload, Prev: Keybindings, Up: Emacs Initialization
Loading Files
=============
Many people in the GNU Emacs community have written extensions to
Emacs. As time goes by, these extensions are often included in new
releases. For example, the Calendar and Diary packages are now part of
the standard Emacs version 19 distribution; they were not part of the
standard Emacs version 18 distribution.
(Calc, which I consider a vital part of Emacs, would be part of the
standard distribution except that it is so large it is packaged
separately.)
You can use a `load' command to evaluate a complete file and thereby
install all the functions and variables in the file into Emacs. For
example:
(load "~/emacs/kfill")
This evaluates, i.e. loads, the `kfill.el' file (or if it exists,
the faster, byte compiled `kfill.elc' file) from the `emacs'
sub-directory of your home directory.
(`kfill.el' was adapted from Kyle E. Jones' `filladapt.el' package
by Bob Weiner and "provides no muss, no fuss word wrapping and filling
of paragraphs with hanging indents, included text from news and mail
messages, and Lisp, C++, PostScript or shell comments." I use it all
the time and hope it is incorporated into the standard distribution.)
If you load many extensions, as I do, then instead of specifying the
exact location of the extension file, as shown above, you can specify
that directory as part of Emacs's `load-path'. Then, when Emacs loads
a file, it will search that directory as well as its default list of
directories. (The default list is specified in `paths.h' when Emacs is
built.)
The following command adds your `~/emacs' directory to the existing
load path:
;;; Emacs Load Path
(setq load-path (cons "~/emacs" load-path))
Incidentally, `load-library' is an interactive interface to the
`load' function. The complete function looks like this:
(defun load-library (library)
"Load the library named LIBRARY.
This is an interface to the function `load'."
(interactive "sLoad library: ")
(load library))
The name of the function, `load-library', comes from the use of
`library' as a conventional synonym for `file'. The source for the
`load-library' command is in the `files.el' library.
Another interactive command that does a slightly different job is
`load-file'. *Note Libraries of Lisp Code for Emacs: (emacs)Lisp
Libraries, for information on the distinction between `load-library'
and this command.
File: emacs-lisp-intro.info, Node: Autoload, Next: Simple Extension, Prev: Loading Files, Up: Emacs Initialization
Autoloading
===========
Instead of installing a function by loading the file that contains
it, or by evaluating the function definition, you can make the function
available but not actually install it until it is first called. This
is called "autoloading".
When you execute an autoloaded function, Emacs automatically
evaluates the file that contains the definition, and then calls the
function.
Emacs starts quicker with autoloaded functions, since their libraries
are not loaded right away; but you need to wait a moment when you first
use such a function, while its containing file is evaluated.
Rarely used functions are frequently autoloaded. The `loaddefs.el'
library contains hundreds of autoloaded functions, from `bookmark-set'
to `wordstar-mode'. Of course, you may come to use a `rare' function
frequently. In this case, you should load that function's file with a
`load' expression in your `.emacs' file.
In my `.emacs' file for Emacs version 19.23, I load 17 libraries
that contain functions that would otherwise be autoloaded. (Actually,
it would have been better to include these files in my `dumped' Emacs
when I built it, but I forgot. *Note Building Emacs: (elisp)Building
Emacs, and the `INSTALL' file for more about dumping.)
You may also want to include autoloaded expressions in your `.emacs'
file. `autoload' is a built-in function that takes up to five
arguments, the final three of which are optional. The first argument
is the name of the function to be autoloaded; the second is the name of
the file to be loaded. The third argument is documentation for the
function, and the fourth tells whether the function can be called
interactively. The fifth argument tells what type of
object--`autoload' can handle a keymap or macro as well as a function
(the default is a function).
Here is a typical example:
(autoload 'html-helper-mode
"html-helper-mode" "Edit HTML documents" t)
This expression autoloads the `html-helper-mode' function from the
`html-helper-mode.el' file (or, if it exists, from the byte compiled
file `html-helper-mode.elc'.) The file must be located in a directory
specified by `load-path'. The documentation says that this is a mode
to help you edit documents written in the HyperText Markup Language.
You can call this mode interactively by typing `M-x html-helper-mode'.
(You need to duplicate the function's regular documentation in the
autoload expression because the regular function is not yet loaded, so
its documentation is not available.)
*Note Autoload: (elisp)Autoload, for more information.
File: emacs-lisp-intro.info, Node: Simple Extension, Next: Keymaps, Prev: Autoload, Up: Emacs Initialization
A Simple Extension: `line-to-top-of-window'
===========================================
Here is a simple extension to Emacs that moves the line point is on
to the top of the window. I use this all the time, to make text easier
to read.
You can put the following code into a separate file and then load it
from your `.emacs' file, or you can include it within your `.emacs'
file.
Here is the definition:
;;; Line to top of window;
;;; replace three keystroke sequence C-u 0 C-l
(defun line-to-top-of-window ()
"Move the line point is on to top of window."
(interactive)
(recenter 0))
Now for the keybinding.
Although most of an Emacs version 18 `.emacs' file works with
version 19, there are some differences (also, of course, there are new
features in Emacs 19).
In version 19 Emacs, you can write a function key like this: `[f6]'.
In version 18, you must specify the key strokes sent by the keyboard
when you press that function key. For example, a Zenith 29 keyboard
sends <ESC P> when I press its sixth function key; an Ann Arbor
Ambassador keyboard sends <ESC O F>. Write these keystrokes as `\eP'
and `\eOF', respectively.
In my version 18 `.emacs' file, I bind `line-to-top-of-window' to a
key that depends on the type of terminal:
(defun z29-key-bindings ()
"Function keybindings for Z29 terminal."
;; ...
(global-set-key "\eP" 'line-to-top-of-window))
(defun aaa-key-bindings ()
"Function keybindings for Ann Arbor Ambassador"
;; ...
(global-set-key "\eOF" 'line-to-top-of-window))
(You can find out what a function key sends by typing the function key,
and then typing `C-h l' (`view-lossage') which displays the last 100
input keystrokes.)
After specifying the key bindings, I evaluate an expression that
chooses among keybindings, depending on the type of terminal I am
using. However, before doing that, I turn off the predefined, default
terminal-specific keybindings, which overwrite bindings in the `.emacs'
if they clash.
;;; Turn Off Predefined Terminal Keybindings
; The following turns off the predefined
; terminal-specific keybindings such as the
; vt100 keybindings in lisp/term/vt100.el.
; If there are no predefined terminal
; keybindings, or if you like them,
; comment this out.
(setq term-file-prefix nil)
Here is the selection expression itself:
(let ((term (getenv "TERM")))
(cond
((equal term "z29") (z29-key-bindings))
((equal term "aaa") (aaa-key-bindings))
(t (message
"No binding for terminal type %s."
term))))
In Emacs version 19, function keys (as well as mouse button events
and non-ASCII characters) are written within square brackets, without
quotation marks. I bind `line-to-top-of-window' to my <F6> function
key like this:
(global-set-key [f6] 'line-to-top-of-window)
Much simpler!
For more information, see *Note Rebinding Keys in Your Init File:
(emacs)Init Rebinding.
If you run both Emacs 18 and Emacs 19, you can select which code to
evaluate with the following conditional:
(if (string=
(int-to-string 18)
(substring (emacs-version) 10 12))
;; evaluate version 18 code
(progn
... )
;; else evaluate version 19 code
...
File: emacs-lisp-intro.info, Node: Keymaps, Next: X11 Colors, Prev: Simple Extension, Up: Emacs Initialization
Keymaps
=======
Emacs uses "keymaps" to record which keys call which commands.
Specific modes, such as C mode or Text mode, have their own keymaps;
the mode-specific keymaps override the global map that is shared by all
buffers.
The `global-set-key' function binds, or rebinds, the global keymap.
For example, the following binds the key `C-c C-l' to the function
`line-to-top-of-window':
(global-set-key "\C-c\C-l" 'line-to-top-of-window))
Mode-specific keymaps are bound using the `define-key' function,
which takes a specific keymap as an argument, as well as the key and
the command. For example, my `.emacs' file contains the following
expression to bind the `texinfo-insert-@group' command to `C-c C-c g':
(define-key texinfo-mode-map "\C-c\C-cg"
'texinfo-insert-@group)
The `texinfo-insert-@group' function itself is a little extension to
Texinfo mode that inserts `@group' into a Texinfo file. I use this
command all the time and prefer to type the three strokes `C-c C-c g'
rather than the six strokes `@ g r o u p'. (`@group' and its matching
`@end group' are commands that keep all enclosed text together on one
page; many multi-line examples in this book are surrounded by `@group
... @end group'.)
Here is the `texinfo-insert-@group' function definition:
(defun texinfo-insert-@group ()
"Insert the string @group in a Texinfo buffer."
(interactive)
(beginning-of-line)
(insert "@group\n"))
(Of course, I could have used Abbrev mode to save typing, rather than
write a function to insert a word; but I prefer key strokes consistent
with other Texinfo mode key bindings.)
You will see numerous `define-key' expressions in `loaddefs.el' as
well as in the various mode libraries, such as `c-mode.el' and
`lisp-mode.el'.
*Note Customizing Key Bindings: (emacs)Key Bindings, and *Note
Keymaps: (elisp)Keymaps, for more information about keymaps.
File: emacs-lisp-intro.info, Node: X11 Colors, Next: V19 Miscellaneous, Prev: Keymaps, Up: Emacs Initialization
X11 Colors
==========
You can specify colors when you use Emacs version 19 with the MIT X
Windowing system. (All the previous examples should work with both
Emacs version 18 and Emacs version 19; this works only with Emacs
version 19.)
I hate the default colors and specify my own.
Most of my specifications are in various X initialization files. I
wrote notes to myself in my `.emacs' file to remind myself what I did:
;; I use TWM for window manager;
;; my ~/.xsession file specifies:
; xsetroot -solid navyblue -fg white
Actually, the root of the X window is not part of Emacs at all, but I
like the reminder anyhow.
;; My ~/.Xresources file specifies:
; XTerm*Background: sky blue
; XTerm*Foreground: white
; emacs*geometry: =80x40+100+0
; emacs*background: blue
; emacs*foreground: grey97
; emacs*cursorColor: white
; emacs*pointerColor: white
Here are the expressions in my `.emacs' file that set values:
;;; Set highlighting colors for isearch and drag
(set-face-foreground 'highlight "white" )
(set-face-background 'highlight "slate blue")
(set-face-background 'region "slate blue")
(set-face-background
'secondary-selection "turquoise")
;; Set calendar highlighting colors
(setq calendar-load-hook
'(lambda ()
(set-face-foreground 'diary-face "skyblue")
(set-face-background 'holiday-face "slate blue")
(set-face-foreground 'holiday-face "white")))
The various shades of blue soothe my eye and prevent me from seeing
the screen flicker.
File: emacs-lisp-intro.info, Node: V19 Miscellaneous, Next: Mode Line, Prev: X11 Colors, Up: Emacs Initialization
V19 Miscellaneous
=================
Here are a few miscellaneous settings for version 19 Emacs:
- Automatically resize the minibuffer as needed:
(resize-minibuffer-mode 1)
(setq resize-minibuffer-mode t)
- Turn on highlighting for search strings:
(setq search-highlight t)
- Set every frame to show a menu bar and to come forward when you
move the mouse onto it.
(setq default-frame-alist
'((menu-bar-lines . 1)
(auto-lower . t)
(auto-raise . t)))
- Set the shape and color of the mouse cursor:
; Cursor shapes are defined in
; `/usr/include/X11/cursorfont.h';
; for example, the `target' cursor is number 128;
; the `top_left_arrow' cursor is number 132.
(let ((mpointer (x-get-resource "*mpointer"
"*emacs*mpointer")))
;; If you have not set your mouse pointer
;; then sent it, otherwise leave as is:
(if (eq mpointer nil)
(setq mpointer "132")) ; top_left_arrow
(setq x-pointer-shape (string-to-int mpointer))
(set-mouse-color "white"))
File: emacs-lisp-intro.info, Node: Mode Line, Prev: V19 Miscellaneous, Up: Emacs Initialization
A Modified Mode Line
====================
Finally, a feature I really like: a modified mode line.
Since I sometimes work over a network, I replaced the `Emacs: ' that
is normally written on the left hand side of the mode line by the name
of the system--otherwise, I forget which machine I am using. In
addition, I list the default directory lest I lose track of where I am,
and I specify the line point is on, with `Line' spelled out. My
`.emacs' file looks like this:
(setq mode-line-system-identification
(substring (system-name) 0
(string-match "\\..+" (system-name))))
(setq default-mode-line-format
(list ""
'mode-line-modified
"<"
'mode-line-system-identification
"> "
"%14b"
" "
'default-directory
" "
"%[("
'mode-name
'minor-mode-alist
"%n"
'mode-line-process
")%]--"
"Line %l--"
'(-3 . "%P")
"-%-"))
;; Start with new default.
(setq mode-line-format default-mode-line-format)
I set the *default* mode line format so as to permit various modes,
such as Info, to override it. Many elements in the list are
self-explanatory: `mode-line-modified' is a variable the tells whether
the buffer has been modified, `mode-name' tells the name of the mode,
and so on.
The `"%14b"' displays the current buffer name (using the
`buffer-name' function with which we are familiar); the `14' specifies
the maximum number of characters that will be displayed. When a name
has fewer characters, whitespace is added to fill out to this number.
`%[' and `%]' cause a pair of square brackets to appear for each
recursive editing level. `%n' says `Narrow' when narrowing is in
effect. `%P' tells you the percentage of the buffer that is above the
bottom of the window, or `Top', `Bottom', or `All'. (A lower case `p'
tell you the percentage above the *top* of the window.) `%-' inserts
enough dashes to fill out the line.
In and after Emacs version 19.29, you can use `frame-title-format'
to set the title of an Emacs frame. This variable has the same
structure as `mode-line-format'.
Mode line formats are described in *Note Mode Line Format:
(elisp)Mode Line Format.
Remember, "You don't have to like Emacs to like it" -- your own
Emacs can have different colors, different commands, and different keys
than a default Emacs.
On the other hand, if you want to bring up a plain `out of the box'
Emacs, with no customization, type:
emacs -q
This will start an Emacs that does *not* load your `~/.emacs'
initialization file. A plain, default Emacs. Nothing more.
File: emacs-lisp-intro.info, Node: Debugging, Next: Conclusion, Prev: Emacs Initialization, Up: Top
Debugging
*********
GNU Emacs has two debuggers, `debug' and `edebug'. The first is
built into the internals of Emacs and is always with you; the second is
an extension to Emacs that has become part of the standard distribution
in version 19.
Both debuggers are described extensively in *Note Debugging Lisp
Programs: (elisp)Debugging. In this chapter, I will walk through a
short example of each.
* Menu:
* debug:: How to use the built-in debugger.
* debug-on-entry:: Start debugging when you call a function.
* debug-on-quit:: Start debugging when you quit with `C-g'.
* edebug:: How to use Edebug, a source level debugger.
* Debugging Exercises::
File: emacs-lisp-intro.info, Node: debug, Next: debug-on-entry, Prev: Debugging, Up: Debugging
`debug'
=======
Suppose you have written a function definition that is intended to
return the sum of the numbers 1 through a given number. (This is the
`triangle' function discussed earlier. *Note Example with Decrementing
Counter: Decrementing Example, for a discussion.)
However, your function definition has a bug. You have mistyped `1='
for `1-'. Here is the broken definition:
(defun triangle-bugged (number)
"Return sum of numbers 1 through NUMBER inclusive."
(let ((total 0))
(while (> number 0)
(setq total (+ total number))
(setq number (1= number))) ; Error here.
total))
If you are reading this in Info, you can evaluate this definition in
the normal fashion. You will see `triangle-bugged' appear in the echo
area.
Now evaluate the `triangle-bugged' function with an argument of 4:
(triangle-bugged 4)
You will produce an error message that says:
Symbol's function definition is void: 1=
In practice, for a bug as simple as this, this error message will tell
you what you need to know to correct the definition. However, suppose
you are not quite certain what is going on?
You can turn on debugging by setting the value of `debug-on-error'
to `t':
(setq debug-on-error t)
This causes Emacs to enter the debugger next time it encounters an
error.
You can turn off `debug-on-error' by setting it to `nil':
(setq debug-on-error nil)
Set `debug-on-error' to `t' and evaluate the following:
(triangle-bugged 4)
This time, Emacs will create a buffer called `*Backtrace*' that looks
like this:
---------- Buffer: *Backtrace* ----------
Signalling: (void-function 1=)
(1= number))
(setq number (1= number)))
(while (> number 0) (setq total (+ total number))
(setq number (1= number))))
(let ((total 0)) (while (> number 0) (setq total ...)
(setq number ...)) total))
triangle-bugged(4)
eval((triangle-bugged 4))
eval-last-sexp(nil)
* call-interactively(eval-last-sexp)
---------- Buffer: *Backtrace* ----------
(I have reformatted this example slightly; the debugger does not fold
long lines.)
You read the `*Backtrace*' buffer from the bottom up; it tells you
what Emacs did that led to the error. In this case, what Emacs did was
make an interactive call to `C-x C-e' (`eval-last-sexp'), which led to
the evaluation of the `triangle-bugged' expression. Each line above
tells you what the Lisp interpreter evaluated next.
The third line from the top of the buffer is
(setq number (1= number))
Emacs tried to evaluate this expression; in order to do so, it tried to
evaluate the inner expression shown on the second line from the top:
(1= number)
This is where the error occurred; as the top line says:
Signalling: (void-function 1=)
You can correct the mistake, re-evaluate the function definition, and
then run your test again.
If you are reading this in Info, you can now turn off
`debug-on-error' by setting it to `nil':
(setq debug-on-error nil)
File: emacs-lisp-intro.info, Node: debug-on-entry, Next: debug-on-quit, Prev: debug, Up: Debugging
`debug-on-entry'
================
A second way to start `debug' on a function is to enter the debugger
when you call the function. You can do this by calling
`debug-on-entry'.
Type:
M-x debug-on-entry RET triangle-bugged RET
Now, evaluate the following:
(triangle-bugged 5)
Emacs will create a `*Backtrace*' buffer and tell you that it is
beginning to evaluate the `triangle-bugged' function:
---------- Buffer: *Backtrace* ----------
Entering:
* triangle-bugged(5)
eval((triangle-bugged 5))
eval-last-sexp(nil)
* call-interactively(eval-last-sexp)
---------- Buffer: *Backtrace* ----------
In the `*Backtrace*' buffer, type `d'. Emacs will evaluate the
first expression in `triangle-bugged'; the buffer will look like this:
---------- Buffer: *Backtrace* ----------
Beginning evaluation of function call form:
* (let ((total 0)) (while (> number 0) (setq total ...)
(setq number ...)) total))
triangle-bugged(5)
* eval((triangle-bugged 5))
eval-last-sexp(nil)
* call-interactively(eval-last-sexp)
---------- Buffer: *Backtrace* ----------
Now, type `d' again, eight times, slowly. Each time you type `d',
Emacs will evaluate another expression in the function definition.
Eventually, the buffer will look like this:
---------- Buffer: *Backtrace* ----------
Beginning evaluation of function call form:
* (setq number (1= number)))
* (while (> number 0) (setq total (+ total number))
(setq number (1= number))))
* (let ((total 0)) (while (> number 0)
(setq total ...) (setq number ...)) total))
triangle-bugged(5)
* eval((triangle-bugged 5))
eval-last-sexp(nil)
* call-interactively(eval-last-sexp)
---------- Buffer: *Backtrace* ----------
Finally, after you type `d' two more times, Emacs will reach the error,
and the top two lines of the `*Backtrace*' buffer will look like this:
---------- Buffer: *Backtrace* ----------
Signalling: (void-function 1=)
* (1= number))
...
---------- Buffer: *Backtrace* ----------
By typing `d', you were able to step through the function.
You can quit a `*Backtrace*' buffer by typing `q'; this quits the
trace, but does not cancel `debug-on-entry'.
To cancel the effect of `debug-on-entry', call
`cancel-debug-on-entry' and the name of the function, like this:
M-x cancel-debug-on-entry RET triangle-debugged RET
(If you are reading this in Info, cancel `debug-on-entry' now.)
File: emacs-lisp-intro.info, Node: debug-on-quit, Next: edebug, Prev: debug-on-entry, Up: Debugging
`debug-on-quit' and `(debug)'
=============================
In addition to setting `debug-on-error' or calling `debug-on-entry',
there are two other ways to start `debug'.
You can start `debug' whenever you type `C-g' (`keyboard-quit') by
setting the variable `debug-on-quit' to `t'. This is useful for
debugging infinite loops.
Or, you can insert a line that says `(debug)' into your code where
you want the debugger to start, like this:
(defun triangle-bugged (number)
"Return sum of numbers 1 through NUMBER inclusive."
(let ((total 0))
(while (> number 0)
(setq total (+ total number))
(debug) ; Start debugger.
(setq number (1= number))) ; Error here.
total))
The `debug' function is described in detail in *Note The Lisp
Debugger: (elisp)Debugger.
File: emacs-lisp-intro.info, Node: edebug, Next: Debugging Exercises, Prev: debug-on-quit, Up: Debugging
The `edebug' Source Level Debugger
==================================
Edebug normally displays the source of the code you are debugging,
with an arrow at the left that shows which line you are currently
executing.
You can walk through the execution of a function, line by line, or
run quickly until reaching a "breakpoint" where execution stops.
Edebug is described in *Note Edebug: (elisp)edebug.
Here is a bugged function definition for `triangle-recursively'.
*Note Recursion in place of a counter: Recursive triangle function, for
a review of it. This example is presented without indentation to the
left of the `defun', as explained below.
(defun triangle-recursively-bugged (number)
"Return sum of numbers 1 through NUMBER inclusive.
Uses recursion."
(if (= number 1)
1
(+ number
(triangle-recursively-bugged
(1= number))))) ; Error here.
Normally, you would install this definition by positioning your cursor
after the function's closing parenthesis and typing `C-x C-e'
(`eval-last-sexp') or else by positioning your cursor within the
definition and typing `C-M-x' (`eval-defun'). (By default, the
`eval-defun' command works only in Emacs Lisp mode or in Lisp
Interactive mode.)
However, to prepare this function definition for Edebug, you must
first "instrument" the code using a different command. In Emacs
version 19, you can do this by positioning your cursor within the
definition and typing the following:
M-x edebug-defun RET
This will cause Emacs to load Edebug automatically if it is not already
loaded, and properly instrument the function. (After loading Edebug,
you can use its standard keybindings, such as `C-u C-M-x' (`eval-defun'
with a prefix argument) for `edebug-defun'.)
In Emacs version 18, you need to load Edebug yourself; you can do
this by putting the appropriate `load' command in your `.emacs' file.
If you are reading this in Info, you can instrument the
`triangle-recursively-bugged' function shown above. `edebug-defun'
fails to locate the bounds of a definition whose `defun' line is
indented; so the example is presented without the usual spaces to the
left of the `defun'.
After instrumenting the function, place your cursor after the
following expression and type `C-x C-e' (`eval-last-sexp'):
(triangle-recursively-bugged 3)
You will be jumped back to the source for `triangle-recursively-bugged'
and the cursor positioned at the beginning of the `if' line of the
function. Also, you will see an arrow at the left hand side of that
line that looks like this: `=>'. The arrow marks the line where the
function is executing.
=>-!-(if (= number 1)
In the example, the location of point is displayed as `-!-' (in a
printed book, it is displayed with a five pointed star).
If you now press <SPC>, point will move to the next expression to be
executed; the line will look like this:
=>(if -!-(= number 1)
As you continue to press <SPC>, point will move from expression to
expression. At the same time, whenever an expression returns a value,
that value will be displayed in the echo area. For example, after you
move point past `number', you will see the following:
Result: 3 = C-c
This means the value of `number' is 3, which is ASCII <CTL-C> (the
third letter of the alphabet).
You can continue moving through the code until you reach the line
with the error. Before evaluation, that line looks like this:
=> -!-(1= number))))) ; Error here.
When you press <SPC> once again, you will produce an error message that
says:
Symbol's function definition is void: 1=
This is the bug.
Press `q' to quit Edebug.
To remove instrumentation from a function definition, simply
re-evaluate it with a command that does not instrument it. For
example, you could place your cursor after the definition's closing
parenthesis and type `C-x C-e'.
Edebug does a great deal more than walk with you through a function.
You can set it so it races through on its own, stopping only at an
error or at specified stopping points; you can cause it to display the
changing values of various expressions; you can find out how many times
a function is called, and more.
Edebug is described in *Note Edebug: (elisp)edebug.
File: emacs-lisp-intro.info, Node: Debugging Exercises, Prev: edebug, Up: Debugging
Debugging Exercises
===================
* Install the `count-words-region' function and then cause it to
enter the built-in debugger when you call it. Run the command on a
region containing two words. You will need to press `d' a
remarkable number of times. On your system, is a `hook' called
after the command finishes? (For information on hooks, see *Note
Command Loop Overview: (elisp)Command Overview.)
* Copy `count-words-region' into the `*scratch*' buffer, remove
white space before the `defun' line if necessary, instrument the
function for Edebug, and walk through its execution. The function
does not need to have a bug, although you can introduce one if you
wish. If the function lacks a bug, the walk-through completes
without problems.
* While running Edebug, type `?' to see a list of all the Edebug
commands. (The `global-edebug-prefix' is usually `C-x X', i.e.
`<CTL>-x' followed by an upper case `X'; use this prefix for
commands made outside of the Edebug debugging buffer.)
* In the Edebug debugging buffer, use the `p'
(`edebug-bounce-point') command to see where in the region the
`count-words-region' is working.
* Move point to some spot further down function and then type the
`h' (`edebug-goto-here') command to jump to that location.
* Use the `t' (`edebug-trace-mode') command to cause Edebug to walk
through the function on its own; use an upper case `T' for
`edebug-Trace-fast-mode'.
* Set a breakpoint, then run Edebug in Trace mode until it reaches
the stopping point.
File: emacs-lisp-intro.info, Node: Conclusion, Next: the-the, Prev: Debugging, Up: Top
Conclusion
**********
We have now reached the end of this Introduction. You have now
learned enough about programming in Emacs Lisp to set values, to write
simple `.emacs' files for yourself and your friends, and write simple
customizations and extensions to Emacs.
This is a place to stop. Or, if you wish, you can now go onward, and
teach yourself.
You have learned some of the basic nuts and bolts of programming.
But only some. There are a great many more brackets and hinges that are
easy to use that we have not touched.
A path you can follow right now lies among the sources to GNU Emacs
and in *Note The GNU Emacs Lisp Reference Manual: (elisp)Top.
The Emacs Lisp sources are an adventure. When you read the sources
and come across a function or expression that is unfamiliar, you need to
figure out or find out what it does.
Go to the Reference Manual. It is a thorough, complete, and fairly
easy-to-read description of Emacs Lisp. It is written not only for
experts, but for people who know what you know. (The `Reference
Manual' comes with the standard GNU Emacs distribution. Like this
introduction, it comes as a Texinfo source file, so you can read it
on-line and as a typeset, printed book.)
Go to the other on-line help that is part of GNU Emacs: the on-line
documentation for all functions, and `find-tags', the program that
takes you to sources.
Here is an example of how I explore the sources. Because of its
name, `simple.el' is the file I looked at first, a long time ago. As
it happens some of the functions in `simple.el' are complicated, or at
least look complicated at first sight. The first function, for
example, looks complicated. This is the `open-line' function.
You may want to walk through this function slowly, as we did with the
`forward-sentence' function. (*Note forward-sentence::.) Or you may
want to skip that function and look at another, such as `split-line'.
You don't need to read all the functions. According to
`count-words-in-defun', the `split-line' function contains 27 words and
symbols.
Even though it is short, `split-line' contains four expressions we
have not studied: `skip-chars-forward', `indent-to', `insert', and
`?\n'.
Consider the `insert' function. (It is mentioned in passing in
*Note Regexp Review::.) In Emacs, you can find out more about `insert'
by typing `C-h f' (`describe-function') and the name of the function.
This gives you the function documentation. You can look at its source
using `find-tag', which is bound to `M-.' (this is not so helpful in
this case; the function is a primitive written in C rather than Lisp).
Finally, you can find out what the Reference Manual has to say by
visiting the manual in Info, and typing `i' (`Info-index') and the name
of the function, or by looking up `insert' in the index to a printed
copy of the manual.
Similarly, you can find out what is meant by `?\n'. You can try
using `Info-index' with `?\n'. It turns out that this action won't
help; but don't give up. If you search the index for `\n' without the
`?', you will be taken directly to the relevant section of the manual.
(*Note Character Type: (elisp)Character Type. `?\n' stands for the
newline character.)
You may be able to guess what is done by `skip-chars-forward' and
`indent-to'; or you can look them up, too. (Incidentally, the
`describe-function' function itself is in `help.el'; it is one of those
long, but decipherable functions. Its definition illustrates how to
customize the `interactive' expression without using the standard
character codes; and it shows how to create a temporary buffer.)
Other interesting source files include `paragraphs.el',
`loaddefs.el', and `loadup.el'. The `paragraphs.el' file includes
short, easily understood functions as well as longer ones. The
`loaddefs.el' file contains the many standard autoloads and many
keymaps. I have never looked at it all; only at parts. `loadup.el' is
the file that loads the standard parts of Emacs; it tells you a great
deal about how Emacs is built. (*Note Building Emacs: (elisp)Building
Emacs, for more about building.)
As I said, you have learned some nuts and bolts; however, and very
importantly, we have hardly touched major aspects of programming; I
have said nothing about how to sort information, except to use the
predefined `sort' function; I have said nothing about how to store
information, except to use variables and lists; I have said nothing
about how to write programs that write programs. These are topics for
another, and different kind of book, a different kind of learning.
What you have done is learn enough for much practical work with GNU
Emacs. What you have done is get started. This is the end of a
beginning.
File: emacs-lisp-intro.info, Node: the-the, Next: Kill Ring, Prev: Conclusion, Up: Top
The `the-the' Function
**********************
Sometimes when you you write text, you duplicate words--as with "you
you" near the beginning of this sentence. I find that most frequently,
I duplicate "the'; hence, I call the function for detecting duplicated
words, `the-the'.
As a first step, you could use the following regular expression to
search for duplicates:
\\(\\w+[ \t\n]+\\)\\1
This regexp matches one or more word-constituent characters followed by
one or more spaces, tabs, or newlines. However, it does not detect
duplicated words on different lines, since the ending of the first
word, the end of the line, is different from the ending of the second
word, a space. (For more information about regular expressions, see
*Note Regular Expression Searches: Regexp Search, as well as *Note
Syntax of Regular Expressions: (emacs)Regexps, and *Note Regular
Expressions: (elisp)Regular Expressions.)
You might try searching just for duplicated word-constituent
characters but that does not work since the pattern detects doubles
such as the two occurrences of `th' in `with the'.
Another possible regular expression is for word-constituent
characters that are followed by non-word-constituent characters. Here,
`\\w+' matches one or more word-constituent characters and `\\W*'
matches zero or more non-word-constituent characters.
\\(\\(\\w+\\)\\W*\\)\\1
Again, not useful.
Here is the pattern that I use. It is not perfect, but good enough.
`\\b' matches the empty string, provided it is at the beginning or end
of a word; `[^@ \n\t]+' matches one or more occurrences of any
characters that are *not* an @-sign, space, newline, or tab.
\\b\\([^@ \n\t]+\\)[ \n\t]+\\1\\b
One can write more complicated expressions, but I found that this
expression is good enough, so I use it.
Here is the `the-the' function, as I include it in my `.emacs' file,
along with a handy global key binding:
(defun the-the ()
"Search forward for for a duplicated word."
(interactive)
(message "Searching for for duplicated words ...")
(push-mark)
;; This regexp is not perfect
;; but is fairly good over all:
(if (re-search-forward
"\\b\\([^@ \n\t]+\\)[ \n\t]+\\1\\b" nil 'move)
(message "Found duplicated word.")
(message "End of buffer")))
;; Bind `the-the' to C-c \
(global-set-key "\C-c\\" 'the-the)
Here is test text:
one two two three four five
five six seven
You can substitute the other regular expressions shown above in the
function definition and try each of them on this list.
File: emacs-lisp-intro.info, Node: Kill Ring, Next: Full Graph, Prev: the-the, Up: Top
Handling the Kill Ring
**********************
The kill ring is a list that is transformed into a ring by the
workings of the `rotate-yank-pointer' function. The `yank' and
`yank-pop' commands use the `rotate-yank-pointer' function. This
appendix describes the `rotate-yank-pointer' function as well as both
the `yank' and the `yank-pop' commands.
* Menu:
* rotate-yank-pointer:: Move a pointer along a list and around.
* yank:: Paste a copy of a clipped element.
* yank-pop:: Insert first element pointed to.