Emacs Lisp Coding Conventions
Here are conventions that you should follow when writing Emacs Lisp code intended for widespread use:
Simply loading a package should not change Emacs’s editing behavior. Include a command or commands to enable and disable the feature, or to invoke it.
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.
You should choose a short word to distinguish your program from other Lisp programs. The names of all global symbols in your program, that is the names of variables, constants, and functions, should begin with that chosen prefix. Separate the prefix from the rest of the name with a hyphen, ‘
-’. This practice helps avoid name conflicts, since all global variables in Emacs Lisp share the same name space, and all functions share another name space[1]. Use two hyphens to separate prefix and name if the symbol is not meant to be used by other packages.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 itmylib-twiddle-filesin 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.
We recommend enabling
lexical-bindingin new code, and converting existing Emacs Lisp code to enablelexical-bindingif it doesn’t already. See Selecting Lisp Dialect.Put a call to
provideat the end of each separate Lisp file. See Features.If a file requires certain other Lisp programs to be loaded beforehand, then the comments at the beginning of the file should say so. Also, use
requireto make sure they are loaded. See Features.If a file
foouses a macro defined in another filebar, but does not use any functions or variables defined inbar, thenfooshould contain the following expression:emacs-lisp(eval-when-compile (require 'bar))This tells Emacs to load
barjust before byte-compilingfoo, so that the macro definition is available during compilation. Usingeval-when-compileavoids loadingbarwhen the compiled version offoois used. It should be called before the first use of the macro in the file. See Macros and Byte Compilation.Avoid loading additional libraries at run time unless they are really needed. If your file simply cannot work without some other library, then just
requirethat 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 puttingrequirestatements inside the relevant functions rather than at the top-level. Or useautoloadstatements 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.If you need Common Lisp extensions, use the
cl-liblibrary rather than the oldcllibrary. The latter library is deprecated and will be removed in a future version of Emacs.When defining a major mode, please follow the major mode conventions. See Major Mode Conventions.
When defining a minor mode, please follow the minor mode conventions. See Conventions for Writing Minor Modes.
If the purpose of a function is to tell you whether a certain condition is true or false, give the function a name that ends in ‘
p’ (which stands for “predicate”). If the name is one word, add just ‘p’; if the name is multiple words, add ‘-p’. Examples areframepandframe-live-p. We recommend to avoid using this-psuffix in boolean variable names, unless the variable is bound to a predicate function; instead, use a-flagsuffix or names likeis-foo.If the purpose of a variable is to store a single function, give it a name that ends in ‘
-function’. If the purpose of a variable is to store a list of functions (i.e., the variable is a hook), please follow the naming conventions for hooks. See Hooks.Using
unload-featurewill undo the changes usually done by loading a feature (like adding functions to hooks). However, if loadingfeaturedoes something unusual and more complex, you can define a function namedfeature-unload-function, and make it undo any such special changes.unload-featurewill then automatically run this function if it exists. See Unloading.It is a bad idea to define aliases for the Emacs primitives. Normally you should use the standard names instead. The case where an alias may be useful is where it facilitates backwards compatibility or portability.
If a package needs to define an alias or a new function for compatibility with some other version of Emacs, name it with the package prefix, not with the raw name with which it occurs in the other version. Here is an example from Gnus, which provides many examples of such compatibility issues.
emacs-lisp(defalias 'gnus-point-at-bol (if (fboundp 'point-at-bol) 'point-at-bol 'line-beginning-position))Redefining or advising an Emacs primitive is a bad idea. It may do the right thing for a particular program, but there is no telling what other programs might break as a result.
It is likewise a bad idea for one Lisp package to advise a function in another Lisp package (see Advising Emacs Lisp Functions).
Avoid using
eval-after-loadandwith-eval-after-loadin 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.If a file does replace any of the standard functions or library programs of Emacs, prominent comments at the beginning of the file should say which functions are replaced, and how the behavior of the replacements differs from that of the originals.
Constructs that define a function or variable should be macros, not functions, and their names should start with ‘
define-’. The macro should receive the name to be defined as the first argument. That will help various tools find the definition automatically. Avoid constructing the names in the macro itself, since that would confuse these tools.In some other systems there is a convention of choosing variable names that begin and end with ‘
*’. We don’t use that convention in Emacs Lisp, so please don’t use it in your programs. (Emacs uses such names only for special-purpose buffers.) People will find Emacs more coherent if all libraries use the same conventions.The default file coding system for Emacs Lisp source files is UTF-8 (see Text Representations). In the rare event that your program contains characters which are not in UTF-8, you should specify an appropriate coding system in the source file’s ‘
-*-’ line or local variables list. See Local Variables in Files in The GNU Emacs Manual.Indent the file using the default indentation parameters.
Don’t make a habit of putting close-parentheses on lines by themselves; Lisp programmers find this disconcerting.
Please put a copyright notice and copying permission notice on the file if you distribute copies. See Conventional Headers for Emacs Libraries.
For variables holding (or functions returning) a file or directory name, avoid using
pathin its name, preferringfile,file-name, ordirectoryinstead, since Emacs follows the GNU convention to use the term path only for search paths, which are lists of directory names.
The benefits of a Common Lisp-style package system are considered not to outweigh the costs. ↩︎