This chapter describes no additional features of Emacs Lisp. Instead it gives advice on making effective use of the features described in the previous chapters.
Here are some tips for avoiding common errors in writing Lisp code intended for widespread use:
cadr.
Believe it or not, there is more than one plausible way to define
cadr. Play it safe; append your name prefix to produce a name
like foo-cadr or mylib-cadr instead.
If you write a function that you think ought to be added to Emacs under
a certain name, such as twiddle-files, don't call it by that name
in your program. Call it mylib-twiddle-files in your program,
and send mail to `bug-gnu-emacs@prep.ai.mit.edu' suggesting we add
it to Emacs. If and when we do, we can change the name easily enough.
If one prefix is insufficient, your package may use two or three
alternative common prefixes, so long as they make sense.
Separate the prefix from the rest of the symbol name with a hyphen,
`-'. This will be consistent with Emacs itself and with most Emacs
Lisp programs.
provide in each separate
library program, at least if there is more than one entry point to the
program.
require to make sure they are loaded.
(eval-when-compile (require 'bar))(And bar should contain
(provide 'bar), to make the
require work.) This will cause bar to be loaded when you
byte-compile foo. Otherwise, you risk compiling foo without
the necessary macro loaded, and that would produce compiled code that
won't work right. See section Macros and Byte Compilation.
Using eval-when-compile avoids loading bar when
the compiled version of foo is used.
run-hooks, just as the existing major modes do. See section Hooks.
framep and frame-live-p.
whatever-mode which turns the feature on or
off, and make it autoload (see section Autoload). Design the package so
that simply loading it has no visible effect--that should not enable
the feature. Users will request the feature by invoking the command.
next-line or previous-line in programs; nearly
always, forward-line is more convenient as well as more
predictable and robust. See section Motion by Text Lines.
beginning-of-buffer, end-of-buffer
replace-string, replace-regexp
message function, not princ. See section The Echo Area.
error
(or signal). The function error does not return.
See section How to Signal an Error.
Do not use message, throw, sleep-for,
or beep to report errors.
edit-options command does: switch to another buffer and let the
user switch back at will. See section Recursive Editing.
indent-sexp) using the
default indentation parameters.
Here are ways of improving the execution speed of byte-compiled Lisp programs.
memq, member,
assq, or assoc is even faster than explicit iteration. It
may be worth rearranging a data structure so that one of these primitive
search functions can be used.
byte-compile
property. If the property is non-nil, then the function is
handled specially.
For example, the following input will show you that aref is
compiled specially (see section Functions that Operate on Arrays) while elt is not
(see section Sequences):
(get 'aref 'byte-compile)
=> byte-compile-two-args
(get 'elt 'byte-compile)
=> nil
Here are some tips for the writing of documentation strings.
nil values are equivalent and indicate explicitly what
nil and non-nil mean.
/ refers to its second argument as `DIVISOR', because the
actual argument name is divisor.
Also use all caps for meta-syntactic variables, such as when you show
the decomposition of a list or vector into subunits, some of which may
vary.
t and nil without single-quotes.
forward-char. (This is normally `C-f',
but it may be some other character if the user has moved key bindings.)
See section Substituting Key Bindings in Documentation.
We recommend these conventions for where to put comments and how to indent them:
indent-for-comment)
command automatically inserts such a `;' in the right place, or
aligns such a comment if it is already present.
This and following examples are taken from the Emacs sources.
(setq base-version-list ; there was a base
(assoc (substring fn 0 start-vn) ; version to which
file-version-assoc-list)) ; this looks like
; a subversion
(prog1 (setq auto-fill-function
...
...
;; update mode line
(force-mode-line-update)))
Every function that has no documentation string (because it is use only
internally within the package it belongs to), should have instead a
two-semicolon comment right before the function, explaining what the
function does and how to call it properly. Explain precisely what each
argument means and how the function interprets its possible values.
;;; This Lisp code is run in Emacs ;;; when it is to operate as a server ;;; for other processes.Another use for triple-semicolon comments is for commenting out lines within a function. We use triple-semicolons for this precisely so that they remain at the left margin.
(defun foo (a) ;;; This is no longer necessary. ;;; (force-mode-line-update) (message "Finished with %s" a))
;;;; The kill ring
The indentation commands of the Lisp modes in Emacs, such as M-;
(indent-for-comment) and TAB (lisp-indent-line)
automatically indent comments according to these conventions,
depending on the number of semicolons. See section `Manipulating Comments' in The GNU Emacs Manual.
Emacs 19 has conventions for using special comments in Lisp libraries to divide them into sections and give information such as who wrote them. This section explains these conventions. First, an example:
;;; lisp-mnt.el -- minor mode for Emacs Lisp maintainers ;; Copyright (C) 1992 Free Software Foundation, Inc. ;; Author: Eric S. Raymond <esr@snark.thyrsus.com> ;; Maintainer: Eric S. Raymond <esr@snark.thyrsus.com> ;; Created: 14 Jul 1992 ;; Version: 1.2 ;; Keywords: docs ;; This file is part of GNU Emacs. copying permissions...
The very first line should have this format:
;;; filename -- description
The description should be complete in one line.
After the copyright notice come several header comment lines, each beginning with `;; header-name:'. Here is a table of the conventional possibilities for header-name:
;; and a tab character, like this:
;; Author: Ashwin Ram <Ram-Ashwin@cs.yale.edu> ;; Dave Sill <de5@ornl.gov> ;; Dave Brennan <brennan@hal.com> ;; Eric Raymond <esr@snark.thyrsus.com>
finder-by-keyword help command.
This field is important; it's how people will find your package when
they're looking for things by topic area. To separate the keywords, you
can use spaces, commas, or both.
Just about every Lisp library ought to have the `Author' and `Keywords' header comment lines. Use the others if they are appropriate. You can also put in header lines with other header names--they have no standard meanings, so they can't do any harm.
We use additional stylized comments to subdivide the contents of the library file. Here is a table of them:
Go to the first, previous, next, last section, table of contents.