According to Chapter 2 : "Lisp Data Types", of the Emacs Lisp manual:
Each object belongs to one and only one primitive type. These types
include integer, float, cons, symbol, string, vector, hash-table,
subr, and byte-code function, plus several special types, such as
buffer, that are related to editing.
and from Chapter 2.3.6 : "Cons Cell and List Types" :
A cons cell is an object that consists of two slots, called the CAR
slot and the CDR slot. Each slot can hold any Lisp object. We also say
that the CAR of this cons cell is whatever object its CAR slot
currently holds, and likewise for the CDR. A list is a series of cons
cells, linked together so that the CDR slot of each cons cell holds
either the next cons cell or the empty list. The empty list is
actually the symbol nil. Because cons cells are so central to Lisp, we
also have a word for an object which is not a cons cell. These objects
are called atoms.
And from Chapter 21.3 : "Format of Keymaps":
Each keymap is a list whose CAR is the symbol keymap. The remaining
elements of the list define the key bindings of the keymap. A symbol
whose function definition is a keymap is also a keymap. Use the
function keymapp (see below) to test whether an object is a keymap.
When I quote an object, I get an object of type symbol
, whereas a keymap is an object of primitive type cons
, type list
, and constructed type keymap
.
The define-key
function expects a first argument of type keymap
. This is checked by define-key
using the keymapp
predicate function. If the argument is not of type keymap
, it will throw an exception.
According to Chapter 8.1 : "Symbol Components" :
Each symbol has four components (or “cells”), each of which references
another object:
Print name
The symbol’s name.
Value
The symbol’s current value as a variable.
Function
The symbol’s function definition. It can also hold a symbol,
a keymap, or a keyboard macro.
Property list
The symbol’s property list.
The print name cell always holds a string, and cannot be changed. Each
of the other three cells can be set to any Lisp object.
According to Chapter 9.5 : "Eval" :
Eval
Most often, forms are evaluated automatically, by virtue of their
occurrence in a program being run. On rare occasions, you may need to
write code that evaluates a form that is computed at run time, such as
after reading a form from text being edited or getting one from a
property list. On these occasions, use the eval function. Often eval
is not needed and something else should be used instead. For example,
to get the value of a variable, while eval works, symbol-value is
preferable
When I do dolist
on a quoted
list of keymaps, I get a list of objects of type symbol
, whereas each symbol's value slot has a keymap object. Hence, my problem can be solved by passing each symbol's value to define-key
, instead of the symbol itself.
According to the comments by @Tobias and @npostavs, there are many ways to solve my problem. For example, we could solve this using either symbol-value
, eval
, or list
. Hence, the following three examples will all pass an object of type keymap
as first argument to lookup-key
:
(dolist (kmap '(global-map))
(message-box "%s" (lookup-key (symbol-value kmap) (kbd "C-h"))))
(dolist (kmap '(global-map))
(message-box "%s" (lookup-key (eval kmap) (kbd "C-h"))))
(dolist (kmap (list global-map))
(message-box "%s" (lookup-key kmap (kbd "C-h"))))
symbol-value
on the list variablemap
:(define-key (symbol-value map) key def)
. Still curious why I need to do that :)define-key
requires the keymap itself and not some symbol but you iterate over the symbols with yourdolist
.eval
would also do instead ofsymbol-value
.(dolist (map (list evil-normal-state-map evil-insert-state-map))...