When defining and initializing a variable that holds a complicated
value (such as a keymap with bindings in it), it's best to put the
entire computation of the value into the defvar, like this:
(defvar my-mode-map
(let ((map (make-sparse-keymap)))
(define-key map "\C-c\C-a" 'my-command)
...
map)
docstring)
This method has several benefits. First, if the user quits while
loading the file, the variable is either still uninitialized or
initialized properly, never in-between. If it is still uninitialized,
reloading the file will initialize it properly. Second, reloading the
file once the variable is initialized will not alter it; that is
important if the user has run hooks to alter part of the contents (such
as, to rebind keys). Third, evaluating the defvar form with
C-M-x will reinitialize the map completely.
Putting so much code in the defvar form has one disadvantage:
it puts the documentation string far away from the line which names the
variable. Here's a safe way to avoid that:
(defvar my-mode-map nil
docstring)
(if my-mode-map
nil
(let ((map (make-sparse-keymap)))
(define-key my-mode-map "\C-c\C-a" 'my-command)
...
(setq my-mode-map map)))
This has all the same advantages as putting the initialization inside
the defvar, except that you must type C-M-x twice, once on
each form, if you do want to reinitialize the variable.
But be careful not to write the code like this:
(defvar my-mode-map nil
docstring)
(if my-mode-map
nil
(setq my-mode-map (make-sparse-keymap))
(define-key my-mode-map "\C-c\C-a" 'my-command)
...)
This code sets the variable, then alters it, but it does so in more than
one step. If the user quits just after the setq, that leaves the
variable neither correctly initialized nor void nor nil. Once
that happens, reloading the file will not initialize the variable; it
will remain incomplete.
Go to the first, previous, next, last section, table of contents.