A variable in Emacs Lisp is a slot in a symbol. The same symbol can also name a function, because the value cell and the function cell are separate. What makes the language unusual is that a variable can be bound in two ways, lexically (by the text of the code) or dynamically (by the call stack), and a variable can also have a different value in each buffer. This page covers the forms that define and bind variables, the scope rules, buffer-local values, the Customize system and faces.
Names and constants
A variable name is any symbol (Lexical structure). Three kinds of symbol are constants and cannot be set or bound: nil, t, and keywords (symbols that start with :, which evaluate to themselves). An attempt to set one signals setting-constant. Evaluating a symbol that has no value signals void-variable.
| Function | Meaning |
|---|---|
boundp | non-nil if the symbol has a (global or dynamic) value |
symbol-value | the current dynamic or global value of a symbol (not a lexical one) |
set | sets the value of the symbol that its first argument evaluates to |
default-value, set-default | the value that is seen in buffers without a local binding |
makunbound | makes the variable void again (on an alias, Emacs 31 undoes the alias instead of acting on the target) |
special-variable-p | true if defvar or defconst declared it |
Defining variables
| Form | Effect |
|---|---|
(defvar SYM VALUE DOC) | declares SYM special (dynamic) and sets it to VALUE only if it is void; VALUE is not evaluated when SYM already has a value |
(defvar SYM) | no value: a local declaration that SYM is special for the rest of the file or enclosing form; it silences the compiler’s “free variable” warning |
(defconst SYM VALUE DOC) | always sets VALUE and declares SYM special; by convention the value should not change, but the language does not enforce it |
(defcustom SYM VALUE DOC :type … :group …) | a defvar that the Customize interface can edit (see below) |
(defvar-local SYM VALUE DOC) | a defvar that is also automatically buffer-local when set; from Emacs 31 the value may be omitted, which declares the variable special and buffer-local |
The documentation string follows the value. It is the text shown by describe-variable. A line that starts with * was the old marker for a user option and is no longer used; use defcustom. Conventions for documentation strings are on Strings and characters.
(defvar my-counter 0
"Number of greetings given so far.")
(defconst my-version "1.2"
"Version string of this library.")
(defvar-local my-buffer-note nil
"A note kept separately in each buffer.")
Lexical and dynamic binding
With dynamic binding a let changes the symbol’s value cell for as long as the body runs, so every function called from the body sees the new value. With lexical binding the binding is visible only to code written inside the let, and it is kept in the environment of any closure created there. A variable that was declared special (with defvar, defconst or defcustom) is always bound dynamically, even in a lexical file. That is why such names are written with the library prefix.
- Scope is the region of the text where a binding is visible. Extent is the period of time during which the binding exists. A lexical binding has lexical scope and indefinite extent (it lives as long as a closure refers to it). A dynamic binding has indefinite scope and dynamic extent (it ends when the
letexits). - A dynamic binding is undone by non-local exits as well, so a
throwor an error restores the old value.
The lexical-binding cookie
Whether a file uses lexical binding is decided by the variable lexical-binding when the file is read. A file sets it with a first-line cookie: ;;; foo.el --- Summary -*- lexical-binding: t; -*- (File structure). History, as stated in the NEWS files:
| Emacs | Change |
|---|---|
| up to 26 | dynamic binding unless the cookie says t |
| 27 | interactive evaluation (M-: and similar) uses lexical binding by default |
| 28 | a file’s lexical-binding cookie is always heeded, even when enable-local-variables is nil |
| 30 | the byte compiler warns when a file has no cookie |
| 31 | loading a file without the cookie shows a warning; (set-default-toplevel-value 'lexical-binding t) changes the default for places that do not set it; files loaded with -x or --script use lexical binding |
Dynamic binding is still the default for a file without a cookie in Emacs 31. Code written for the old dialect usually works in the new one, apart from variables that were used dynamically without a defvar, closures that relied on dynamic scope, and functions such as eval that take a LEXICAL argument. The manual’s section “Converting to Lexical Binding” recommends: turn on the compiler warnings, declare every dynamically used variable with a one-argument defvar or defvar with a value, and use (eval FORM t) to evaluate a form lexically.
Binding forms
| Form | Meaning |
|---|---|
let | evaluates all the value forms first, then binds in parallel |
let* | binds one after another; later forms see earlier bindings |
letrec | binds all names first, so the value forms can refer to each other (for mutually recursive local functions) |
dlet | binds the variables dynamically even in a lexical file (Emacs 28) |
named-let | a loop written as a local function that may call itself in tail position (Emacs 28) |
setq | sets variables in turn; with several pairs it returns the last value |
setq-default | sets the default (non-local) value |
setq-local | makes the variable buffer-local in the current buffer and sets it |
setopt | like setq but uses the option’s :set function and checks its type (Emacs 29); setopt-local and set-local are the buffer-local versions (Emacs 31) |
incf, decf | add or subtract 1 from a variable or a generalized place (Emacs 31) |
(defun make-adder (n)
(lambda (x) (+ x n))) ; a closure over N, with lexical-binding: t
(funcall (make-adder 3) 4) ; => 7
(named-let loop ((i 0) (acc nil))
(if (> i 3)
(nreverse acc)
(loop (1+ i) (cons i acc)))) ; => (0 1 2 3)
A closure is a function value that carries the lexical variables it refers to. With dynamic binding a lambda is only a list or a code object and carries nothing.
Buffer-local variables
A variable can have a value that belongs to one buffer. Reading it in that buffer gives the local value, otherwise the default value is used.
| Function or form | Meaning |
|---|---|
make-local-variable | makes the variable local in the current buffer only |
make-variable-buffer-local | the variable becomes local in every buffer in which it is set |
defvar-local | defvar plus the previous function |
local-variable-p, local-variable-if-set-p | tests whether the variable is (or would become) local in a buffer |
buffer-local-value, buffer-local-variables | reads a variable in another buffer; lists all local bindings of a buffer |
kill-local-variable, kill-all-local-variables | removes local values; the second keeps variables whose symbol has the permanent-local property |
default-value, setq-default | the value for buffers that have no local binding |
buffer-local-toplevel-value, set-buffer-local-toplevel-value | the value outside any let (Emacs 31) |
A let on a buffer-local variable binds the local value if there is one. A defcustom may carry :local t to make the variable automatically local (Emacs 27). Some variables are file-local or directory-local: Emacs sets them as buffer-local values when it visits a file, from the cookie, the Local Variables: list or .dir-locals.el (File structure). Connection-local variables work the same way for remote connections and processes: they are defined with connection-local-set-profile-variables and activated by criteria such as the host and user.
Aliases, obsolescence and watchers
(defvaralias NEW OLD DOC)makes NEW another name of OLD: both share one value.indirect-variablefollows the alias.(make-obsolete-variable OLD NEW WHEN)marks a variable obsolete; the compiler warns anddescribe-variablesays so. The WHEN argument is mandatory since Emacs 28.(add-variable-watcher SYM FUNC)calls(FUNC SYMBOL NEWVAL OPERATION WHERE)whenever the variable is set, let-bound or made void. OPERATION isset,let,unlet,makunboundordefvaralias; WHERE is the buffer for a local change.remove-variable-watcherandget-variable-watcherscomplete the set.
Generalized variables
A place is anything that holds a value: a variable, (car X), (nth N L), (aref V I), (gethash K H), (alist-get K A), (plist-get P K), (buffer-local-value S B) and others. setf stores into a place; push, pop, cl-incf, add-to-list (for variables only), cl-pushnew, setf and incf take places as well. New places are defined with gv-define-setter, gv-define-simple-setter or (declare (gv-setter …)) on a function. In Emacs 29 many seldom-used places were made obsolete, and make-obsolete-generalized-variable was added.
(let ((l (list 1 2 3)))
(setf (nth 1 l) 'two)
l) ; => (1 two 3)
Customize: defcustom, defgroup, defface
defcustom has the syntax (defcustom SYMBOL STANDARD DOC [KEYWORD VALUE]…). STANDARD is evaluated when the variable is first needed. defgroup declares a group with (defgroup SYMBOL MEMBERS DOC :group PARENT …).
| Keyword | Meaning |
|---|---|
:type | the type specification, below |
:group | the group that contains the option (the last defgroup in the file is the default) |
:options | for hooks, alists and hash tables: a list of the expected elements or keys |
:set, :get | function that stores the value when Customize sets it; function that reads it for display |
:initialize | how to give the option its first value: custom-initialize-default, -set, -reset, -changed, -delay |
:set-after | a list of options that must be set before this one |
:safe | a predicate that marks values as safe for file-local use |
:risky | non-nil marks the option as never safe in a file |
:link | adds a link ((url-link "https://…"), (info-link "(elisp)Node"), (emacs-commentary-link "lib")) |
:version | the Emacs version in which the option was added or changed (for Emacs itself) |
:package-version | the same for a package: '(mypkg . "1.2") |
:require | a feature to load when Customize sets the option |
:local | t or permanent: make the option buffer-local when set (Emacs 27) |
Type specifications
| Type | Value |
|---|---|
sexp | any Lisp object, entered as Lisp text |
integer, natnum, float, number | numbers; natnum is a non-negative integer |
string, regexp | text; a string that must be a valid regexp |
boolean | nil or t |
symbol, function, variable, face, hook | a symbol; a function name or lambda; a variable name; a face name; a list of functions |
file, directory | file names ((file :must-match t) is allowed) |
key-sequence, color, coding-system | a key string; a colour name or hex string; a coding-system symbol |
(const VALUE) | exactly one value |
(choice TYPE…) | a value of any of the listed types, shown as a menu |
(radio TYPE…) | like choice, shown as radio buttons |
(list TYPE…) | a list with one element of each type, in order |
(repeat TYPE) | a list of any length of that type |
(cons A B), (vector TYPE…) | a pair; a vector of fixed length |
(alist :key-type K :value-type V), (plist :key-type K :value-type V) | an association list; a property list |
(defgroup my-greet nil "Greeting options." :group 'convenience)
(defcustom my-greet-style 'formal
"How `my-greet' words its message."
:type '(choice (const :tag "Formal" formal)
(const :tag "Casual" casual))
:group 'my-greet
:package-version '(my-greet . "1.0")
:safe #'symbolp)
Faces
(defface NAME SPEC DOC [KEYWORD VALUE]…) defines a face. SPEC is a list of (DISPLAY ATTRIBUTES) clauses; DISPLAY is t or a list of conditions such as ((class color) (background dark)), and ATTRIBUTES is a plist such as (:foreground "red" :weight bold :inherit shadow). The first clause whose condition matches the frame is used. Keywords :group, :version and :package-version are as for options. From Emacs 31 a face that inherits from itself, directly or indirectly, signals an error.
Not described
Known, not yet covered
- Reference: the full list of face attributes and the display conditions of a face specification.
- Reference: the less common
defcustomtype keywords (:tag,:match,:validate,:inline) and the custom themes (deftheme,custom-theme-set-variables). - Reference: the exact criteria and profile functions of connection-local variables, and the rules for deciding when a file-local value is safe (File structure).
- Reference: the places defined by
cl-liband the fullgvmacro interface.
See also
- File structure – the cookie, file-local and directory-local variables
- Evaluation – how a symbol is evaluated and how forms are run
- Functions – lambda, closures and argument lists
- Byte-compilation – the warnings for free variables and a missing cookie
- Variables – the manual’s chapter on variables
- Customization Settings – the manual’s chapter on defcustom, groups and faces