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, and describes conventions Emacs Lisp programmers should follow.
You can automatically check some of the conventions described below
by running the command M-x checkdoc RET when visiting a
Lisp file. It cannot check all of the conventions, and not all the
warnings it gives necessarily correspond to problems, but it is worth
examining them all. Alternatively, use the command M-x
checkdoc-current-buffer RET to check the conventions in the
current buffer, or checkdoc-file when you want to check a file
in batch mode, e.g., with a command run by M-x compile RET.
Here are conventions that you should follow when writing Emacs Lisp code intended for widespread use:
This convention is mandatory for any file that includes custom definitions. If fixing such a file to follow this convention requires an incompatible change, go ahead and make the incompatible change; don’t postpone it.
Occasionally, for a command name intended for users to use, it is more convenient if some words come before the package’s name prefix. For example, it is our convention to have commands that list objects named as ‘list-something’, e.g., a package called ‘frob’ could have a command ‘list-frobs’, when its other global symbols begin with ‘frob-’. Also, constructs that define functions, variables, etc., may work better if they start with ‘define-’, so it’s okay to put the name prefix later on in the name. Outside of these well-established cases, however, err on the side of prepending your name prefix.
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@gnu.org’ 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 can use two or three alternative common prefixes, so long as they make sense.
lexical-binding in new code, and
converting existing Emacs Lisp code to enable lexical-binding
if it doesn’t already. See Selecting Lisp Dialect.
provide at the end of each separate Lisp file.
See Features.
require to make sure they are loaded.
See Features.
(eval-when-compile (require 'bar))
This tells Emacs to load bar just before byte-compiling
foo, so that the macro definition is available during
compilation. Using eval-when-compile avoids loading bar
when the compiled version of foo is used. It should be
called before the first use of the macro in the file. See Macros and Byte Compilation.
require that library at the top-level and be done
with it. But if your file contains several independent features, and
only one or two require the extra library, then consider putting
require statements inside the relevant functions rather than at
the top-level. Or use autoload statements to load the extra
library when needed. This way people who don’t use those aspects of
your file do not need to load the extra library.
cl-lib library
rather than the old cl library. The latter library is
deprecated and will be removed in a future version of Emacs.
framep and frame-live-p. We recommend to
avoid using this -p suffix in boolean variable names, unless
the variable is bound to a predicate function; instead, use a
-flag suffix or names like is-foo.
unload-feature will undo the changes usually done by
loading a feature (like adding functions to hooks). However, if
loading feature does something unusual and more complex, you can
define a function named feature-unload-function, and make
it undo any such special changes. unload-feature will then
automatically run this function if it exists. See Unloading.
(defalias 'gnus-point-at-bol
(if (fboundp 'point-at-bol)
'point-at-bol
'line-beginning-position))
eval-after-load and with-eval-after-load in
libraries and packages (see Hooks for Loading). This feature is
meant for personal customizations; using it in a Lisp program is
unclean, because it modifies the behavior of another Lisp file in a
way that’s not visible in that file. This is an obstacle for
debugging, much like advising a function in the other package.
definition-name or find-function-type-alist on the name.
See Finding Definitions.
path in its name, preferring file,
file-name, or directory instead, since Emacs follows the
GNU convention to use the term path only for search paths,
which are lists of directory names.
follow-link
condition, so that the link obeys mouse-1-click-follows-link.
See Defining Clickable Text. See Buttons, for an easy method of
implementing such clickable links.
Changing all the Emacs major modes to respect this convention was a lot of work; abandoning this convention would make that work go to waste, and inconvenience users. Please comply with it.
The reason for this rule is that a non-prefix binding for ESC in any context prevents recognition of escape sequences as function keys in that context.
For a state that accepts ordinary Emacs commands, or more generally any kind of state in which ESC followed by a function key or arrow key is potentially meaningful, then you must not define ESC ESC, since that would preclude recognizing an escape sequence after ESC. In these states, you should define ESC ESC ESC as the way to escape. Otherwise, define ESC ESC instead.
Following these conventions will make your program fit better into Emacs when it runs.
next-line or previous-line in programs; nearly
always, forward-line is more convenient as well as more
predictable and robust. See Motion by Text Lines.
In particular, don’t use any of these functions:
beginning-of-buffer, end-of-buffer
replace-string, replace-regexp
insert-file, insert-buffer
If you just want to move point, or replace a certain string, or insert a file or buffer’s contents, without any of the other features intended for interactive users, you can replace these functions with one or two lines of simple Lisp code.
Vectors are advantageous for tables that are substantial in size and are accessed in random order (not searched front to back), provided there is no need to insert or delete elements (only lists allow that).
message function, not princ. See The Echo Area.
error
(or signal). The function error does not return.
See How to Signal an Error.
Don’t use message, throw, sleep-for, or
beep to report errors.
It is occasionally useful to tell the user where an error originated,
even if debug-on-error is nil. In such cases, a
lower-case Lisp symbol can be prepended to the error message. For
example, the error message “Invalid input” could be extended to say
“some-function: Invalid input”.
yes-or-no-p or
y-or-n-p should start with a capital letter and end with
‘?’.
Enter the answer (default 42):
interactive, if you use a Lisp expression to produce a list
of arguments, don’t try to provide the correct default values for
region or position arguments. Instead, provide nil for those
arguments if they were not specified, and have the function body
compute the default value when the argument is nil. For
instance, write this:
(defun foo (pos) (interactive (list (if specified specified-pos))) (unless pos (setq pos default-pos)) ...)
rather than this:
(defun foo (pos)
(interactive
(list (if specified specified-pos
default-pos)))
...)
This is so that repetition of the command will recompute these defaults based on the current circumstances.
You do not need to take such precautions when you use interactive specs ‘d’, ‘m’ and ‘r’, because they make special arrangements to recompute the argument values on repetition of the command.
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
can 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 Functions that Operate on Arrays):
(get 'aref 'byte-compile)
⇒ byte-compile-two-args
Note that in this case (and many others), you must first load the
bytecomp library, which defines the byte-compile property.
defvar definitions for these variables, like this:
(defvar foo)
Such a definition has no effect except to tell the compiler
not to warn about uses of the variable foo in this file.
declare-function
statement (see Telling the Compiler that a Function is Defined).
require (see require) for
that package to avoid compilation warnings for them, like this:
(require 'foo)
If you need only macros from some file, you can require it only at compile time (see Evaluation During Compilation). For instance,
(eval-when-compile (require 'foo))
with-no-warnings. See Compiler Errors.
Here are some tips and conventions for the writing of documentation strings. You can check many of these conventions by running the command M-x checkdoc-minor-mode.
apropos.
You can fill the text if that looks good. Emacs Lisp mode fills
documentation strings to the width specified by
emacs-lisp-docstring-fill-column. However, you can sometimes
make a documentation string much more readable by adjusting its line
breaks with care. Use blank lines between sections if the
documentation string is long.
For a function, the first line should briefly answer the question, “What does this function do?” For a variable, the first line should briefly answer the question, “What does this value mean?” Prefer to answer these questions in a way that will make sense to users and callers of the function or the variable. In particular, do not tell what the function does by enumerating the actions of its code; instead, describe the role of these actions and the function’s contract.
Don’t limit the documentation string to one line; use as many lines as you need to explain the details of how to use the function or variable. Please use complete sentences for the rest of the text too.
eval refers to its first argument as ‘FORM’, because the
actual argument name is form:
Evaluate FORM and return its value.
Also write metasyntactic variables in capital letters, such as when you show the decomposition of a list or vector into subunits, some of which may vary. ‘KEY’ and ‘VALUE’ in the following example illustrate this practice:
The argument TABLE should be an alist whose elements have the form (KEY . VALUE). Here, KEY is ...
foo, write “foo”, not
“Foo” (which is a different symbol).
This might appear to contradict the policy of writing function argument values, but there is no real contradiction; the argument value is not the same thing as the symbol that the function uses to hold the value.
If this puts a lower-case letter at the beginning of a sentence and that annoys you, rewrite the sentence so that the symbol is not at the start of it.
t and nil without surrounding
punctuation. For example:
CODE can be `lambda', nil, or t.
Note that when Emacs displays these doc strings, Emacs will usually display ‘`’ (grave accent) as ‘‘’ (left single quotation mark) and ‘'’ (apostrophe) as ‘’’ (right single quotation mark), if the display supports displaying these characters. See Substituting Key Bindings in Documentation. (Some previous versions of this section recommended using the non-ASCII single quotation marks directly in doc strings, but this is now discouraged, since that leads to broken help string displays on terminals that don’t support displaying those characters.)
Help mode automatically creates a hyperlink when a documentation string uses a single-quoted symbol name, if the symbol has either a function or a variable definition. You do not need to do anything special to make use of this feature. However, when a symbol has both a function definition and a variable definition, and you want to refer to just one of them, you can specify which one by writing one of the words ‘variable’, ‘option’, ‘function’, or ‘command’, immediately before the symbol name. (Case makes no difference in recognizing these indicator words.) For example, if you write
This function sets the variable `buffer-file-name'.
then the hyperlink will refer only to the variable documentation of
buffer-file-name, and not to its function documentation.
If a symbol has a function definition and/or a variable definition, but those are irrelevant to the use of the symbol that you are documenting, you can write the words ‘symbol’ or ‘program’ before the symbol name to prevent making any hyperlink. For example,
If the argument KIND-OF-RESULT is the symbol `list', this function returns a list of all the objects that satisfy the criterion.
does not make a hyperlink to the documentation, irrelevant here, of the
function list.
Alternatively, you could precede the symbol with ‘\\+’ to prevent marking it as a hyperlink. Example:
If the value of KIND-OF-RESULT is \\+`list', this function returns a list of all the objects that satisfy the criterion.
Normally, no hyperlink is made for a variable without variable documentation. You can force a hyperlink for such variables by preceding them with one of the words ‘variable’ or ‘option’.
Hyperlinks for faces are only made if the face name is preceded or followed by the word ‘face’. In that case, only the face documentation will be shown, even if the symbol is also defined as a variable or as a function.
To make a hyperlink to Info documentation, write the single-quoted name of the Info node (or anchor), preceded by ‘info node’, ‘Info node’, ‘info anchor’ or ‘Info anchor’. The Info file name defaults to ‘emacs’. For example,
See Info node `Font Lock' and Info node `(elisp)Font Lock Basics'.
To make a hyperlink to a man page, write the single-quoted name of the man page, preceded by ‘Man page’, ‘man page’, or ‘man page for’. For example,
See the man page `chmod(1)' for details.
The Info documentation is always preferable to man pages, so be sure
to link to an Info manual where available. For example,
chmod is documented in the GNU Coreutils manual, so it is
better to link to that instead of the man page.
To link to a customization group, write the single-quoted name of the group, preceded by ‘customization group’ (the first character in each word is case-insensitive). For example,
See the customization group `whitespace' for details.
Finally, to create a hyperlink to URLs, write the single-quoted URL, preceded by ‘URL’. For example,
The GNU project website has more information (see URL `https://www.gnu.org/').
forward-char.
(This is normally ‘C-f’, but it may be some other character if the
user has moved key bindings.) See Substituting Key Bindings in Documentation.
Each use of ‘\\[…]’ slows the display of the documentation string by a tiny amount. If you use a lot of them, these tiny slowdowns will add up, and might become tangible, especially on slow systems. So our recommendation is not to over-use them; e.g., try to avoid using more than one reference to the same command in the same doc string.
dired-find-file is:
In Dired, visit the file or directory named on this line.
defcustom. See Defining Global Variables.
nil values are equivalent and indicate explicitly what
nil and non-nil mean.
The argument FOO can be either a number \(a buffer position) or a string (a file name).
This avoids a bug in Emacs versions older than 27.1, where the ‘(’ was treated as the start of a defun (see Defuns in The GNU Emacs Manual). If you do not anticipate anyone editing your code with older Emacs versions, there is no need for this work-around.
Documentation groups, available since Emacs 28, are useful to document functions of Lisp packages based on various groupings (see Documentation Groups). This section gives some tips on how you can define documentation groups in your Lisp package in a way such that users of different Emacs versions can equally well use these groups.
;;; well-doc.el --- a well-documented package -*- lexical-binding: t; -*- ... package header and contents ...
;; Explicitly require shortdoc for Emacs 28, which does not have an
;; autoload for macro `define-short-documentation-group'. And for
;; Emacs 30, so that we can redefine `shortdoc--check' later.
(require 'shortdoc nil t)
(eval-when-compile
;; Default macro `define-short-documentation-group' for Emacs 27
;; and older, which do not have the shortdoc feature at all.
(unless (fboundp 'define-short-documentation-group)
(defmacro define-short-documentation-group (&rest _)))
;; Disable too rigid shortdoc checks for Emacs 30, which let it
;; error out on newer shortdoc keywords.
(when (eq emacs-major-version 30)
(fset 'shortdoc--check #'ignore)))
(define-short-documentation-group well-doc ...) ;;; well-doc.el ends here
If you do not intend to support some of the Emacs versions mentioned
above, you can safely omit the corresponding forms from the template.
If you intend to support only Emacs 31 and newer, you do not need any
of the above and can just use define-short-documentation-group.
:super-pretty-print, available
in some future Emacs version, like this in your Lisp package
well-doc.el:
(define-short-documentation-group well-doc (well-doc-foo :eval (well-doc-foo) :super-pretty-print t))
That future Emacs version will then supposedly super-pretty-print the
example for function well-doc-foo. Older Emacs versions will
silently ignore keyword :super-pretty-print and show the example
according to their regular display rules.
We recommend these conventions for comments:
Comments that start with a single semicolon, ‘;’, should all be aligned to the same column on the right of the source code. Such comments usually explain how the code on that line does its job. For example:
(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.
Comments that start with two semicolons, ‘;;’, should be aligned to the same level of indentation as the code. Such comments usually describe the purpose of the following lines or the state of the program at that point. For example:
(prog1 (setq auto-fill-function
...
...
;; Update mode line.
(force-mode-line-update)))
We also normally use two semicolons for comments outside functions.
;; This Lisp code is run in Emacs when it is to operate as ;; a server for other processes.
If a function has no documentation string, it should instead have 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. It is much better to convert such comments to documentation strings, though.
Comments that start with three (or more) semicolons, ‘;;;’, should start at the left margin. We use them for comments that should be considered a heading by Outline minor mode. By default, comments starting with at least three semicolons (followed by a single space and a non-whitespace character) are considered section headings, comments starting with two or fewer are not.
(Historically, triple-semicolon comments have also been used for commenting out lines within a function, but this use is discouraged in favor of using just two semicolons. This also applies when commenting out entire functions; when doing that use two semicolons as well.)
Three semicolons are used for top-level sections, four for sub-sections, five for sub-sub-sections and so on.
Typically libraries have at least four top-level sections. For example when the bodies of all of these sections are hidden:
;;; backquote.el --- implement the ` Lisp construct... ;;; Commentary:... ;;; Code:... ;;; backquote.el ends here
(In a sense the last line is not a section heading as it must never be followed by any text; after all it marks the end of the file.)
For longer libraries it is advisable to split the code into multiple sections. This can be done by splitting the ‘Code:’ section into multiple sub-sections. Even though that was the only recommended approach for a long time, many people have chosen to use multiple top-level code sections instead. You may chose either style.
Using multiple top-level code sections has the advantage that it avoids introducing an additional nesting level but it also means that the section named ‘Code’ does not contain all the code, which is awkward. To avoid that, you should put no code at all inside that section; that way it can be considered a separator instead of a section heading.
Finally, we recommend that you don’t end headings with a colon or any other punctuation for that matter. For historic reasons the ‘Code:’ and ‘Commentary:’ headings end with a colon, but we recommend that you don’t do the same for other headings anyway.
Generally speaking, the M-; (comment-dwim) command
automatically starts a comment of the appropriate type; or indents an
existing comment to the right place, depending on the number of
semicolons.
See Manipulating Comments in The GNU Emacs Manual.
Emacs has conventions for using special comments in Lisp libraries to divide them into sections and give information such as who wrote them. Using a standard format for these items makes it easier for tools (and people) to extract the relevant information. This section explains these conventions, starting with an example:
;;; foo.el --- Support for the Foo programming language -*- lexical-binding: t; -*- ;; Copyright (C) 2010-2026 Your Name
;; Author: Your Name <yourname@example.com> ;; Maintainer: Someone Else <someone@example.com> ;; Created: 14 Jul 2010
;; Keywords: languages ;; URL: https://example.com/foo ;; This file is not part of GNU Emacs. ;; This file is free software... ... ;; along with this file. If not, see <https://www.gnu.org/licenses/>.
The very first line should have this format:
;;; filename --- description -*- lexical-binding: t; -*-
The description should be contained in one line. If the file needs to
set more variables in the ‘-*-’ specification, add it after
lexical-binding. If this would make the first line too long, use
a Local Variables section at the end of the file.
The copyright notice usually lists your name (if you wrote the file). If you have an employer who claims copyright on your work, you might need to list them instead. Do not say that the copyright holder is the Free Software Foundation (or that the file is part of GNU Emacs) unless your file has been accepted into the Emacs distribution or GNU ELPA. For more information on the form of copyright and license notices, see the guide on the GNU website.
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:
This header states the name and email address of at least the principal
author of the library. If there are multiple authors, list them on
continuation lines led by ;; and a tab or at least two spaces.
We recommend including a contact email address, of the form
‘<…>’. For example:
;; Author: Your Name <yourname@example.com> ;; Someone Else <someone@example.com> ;; Another Person <another@example.com>
This header has the same format as the Author header. It lists the person(s) who currently maintain(s) the file (respond to bug reports, etc.).
If there is no Maintainer header, the person(s) in the Author header is/are presumed to be the maintainer(s). Some files in Emacs use ‘emacs-devel@gnu.org’ for the maintainer, which means the author is no longer responsible for the file, and that it is maintained as part of Emacs.
This optional line gives the original creation date of the file, and is for historical interest only.
If you wish to record version numbers for the individual Lisp program, put them in this line. Lisp files distributed with Emacs generally do not have a ‘Version’ header, since the version number of Emacs itself serves the same purpose. If you are distributing a collection of multiple files, we recommend not writing the version in every file, but only the main one.
This line lists keywords for the finder-by-keyword help command.
Please use that command to see a list of the meaningful keywords. The
command M-x checkdoc-package-keywords RET will find and display
any keywords that are not in finder-known-keywords. If you set
the variable checkdoc-package-keywords-flag non-nil,
checkdoc commands will include the keyword verification in its checks.
This field is how people will find your package when they’re looking for things by topic. To separate the keywords, you can use spaces, commas, or both.
The name of this field is unfortunate, since people often assume it is the place to write arbitrary keywords that describe their package, rather than just the relevant Finder keywords.
This line states the website of the library. ‘Homepage’ is a deprecated alternative to ‘URL’.
If ‘Version’ is not suitable for use by the package manager, then
a package can define ‘Package-Version’; it will be used instead.
This is handy if ‘Version’ is an RCS id or something else that
cannot be parsed by version-to-list. See Packaging Basics.
If this exists, it names packages on which the current package depends for proper operation. See Packaging Basics. This is used by the package manager both at download time (to ensure that a complete set of packages is downloaded) and at activation time (to ensure that a package is only activated if all its dependencies have been).
Its format is a list of lists on a single line. The car of
each sub-list is the name of a package, as a symbol. The cadr
of each sub-list is the minimum acceptable version number, as a string
that can be parsed by version-to-list. An entry that lacks a
version (i.e., an entry which is just a symbol, or a sub-list of one
element) is equivalent to entry with version "0". For instance:
;; Package-Requires: ((gnus "1.0") (bubbles "2.7.2") cl-lib (seq))
Packages that don’t need to support Emacs versions older than Emacs 27 can have the ‘Package-Requires’ header split across multiple lines, like this:
;; Package-Requires: ((emacs "27.1") ;; (compat "29.1.4.1"))
Note that with this format, you still need to start the list on the same line as ‘Package-Requires’.
The package code automatically defines a package named ‘emacs’ with the version number of the currently running Emacs. This can be used to require a minimal version of Emacs for a package.
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. These should be separated from anything else by blank lines. Here is a table of them:
This begins introductory comments that explain how the library works. It should come right after the copying permissions, and is terminated by one of the comment lines described below: ‘Change Log’, ‘History’ or ‘Code’. This text is used by the Finder package, so it should make sense in that context.
This begins an optional log of changes to the file over time. Don’t put too much information in this section—it is better to keep the detailed logs in a version control system (as Emacs does) or in a separate ChangeLog file. ‘History’ is an alternative to ‘Change Log’.
This begins the actual code of the program.
This is the footer line; it appears at the very end of the file. Its purpose is to enable people to detect truncated versions of the file from the lack of a footer line.
The benefits of a Common Lisp-style package system are considered not to outweigh the costs.
We do use these occasionally, but try not to overdo it.