Function: define-key
define-key is a function defined in keymap.c.
Signature
(define-key KEYMAP KEY DEF &optional REMOVE)
Documentation
In KEYMAP, define key sequence KEY as DEF.
This is a legacy function; see keymap-set for the recommended
function to use instead.
KEYMAP is a keymap.
KEY is a string or a vector of symbols and characters, representing a
sequence of keystrokes and events. Non-ASCII characters with codes
above 127 (such as ISO Latin-1) can be represented by vectors.
Two types of vector have special meanings:
[remap COMMAND] remaps any key binding for COMMAND.
[t] creates a default definition, which applies to any event with no
other definition in KEYMAP.
DEF is anything that can be a key's definition:
nil (means key is undefined in this keymap),
a command (a Lisp function suitable for interactive calling),
a string (treated as a keyboard macro),
a keymap (to define a prefix key),
a symbol (when the key is looked up, the symbol will stand for its
function definition, which should at that time be one of the above,
or another symbol whose function definition is used, etc.),
a cons (STRING . DEFN), meaning that DEFN is the definition
(DEFN should be a valid definition in its own right) and
STRING is the menu item name (which is used only if the containing
keymap has been created with a menu name, see make-keymap),
or a cons (MAP . CHAR), meaning use definition of CHAR in keymap MAP,
or an extended menu item definition.
(See info node (elisp)Extended Menu Items.)
If REMOVE is non-nil, the definition will be removed. This is almost the same as setting the definition to nil, but makes a difference if the KEYMAP has a parent, and KEY is shadowing the same binding in the parent. With REMOVE, subsequent lookups will return the binding in the parent, and with a nil DEF, the lookups will return nil.
If KEYMAP is a sparse keymap with a binding for KEY, the existing binding is altered. If there is no binding for KEY, the new pair binding KEY to DEF is added at the front of KEYMAP.
Probably introduced at or before Emacs version 13.
Aliases
bindings--define-key (obsolete since 31.1)
Source Code
// Defined in /usr/src/emacs/src/keymap.c
{
bool metized = false;
keymap = get_keymap (keymap, 1, 1);
ptrdiff_t length = CHECK_VECTOR_OR_STRING (key);
if (length == 0)
return Qnil;
int meta_bit = (VECTORP (key) || (STRINGP (key) && STRING_MULTIBYTE (key))
? meta_modifier : 0x80);
if (VECTORP (def) && ASIZE (def) > 0 && CONSP (AREF (def, 0)))
{ /* DEF is apparently an XEmacs-style keyboard macro. */
Lisp_Object tmp = make_nil_vector (ASIZE (def));
ptrdiff_t i = ASIZE (def);
while (--i >= 0)
{
Lisp_Object defi = AREF (def, i);
if (CONSP (defi) && lucid_event_type_list_p (defi))
defi = Fevent_convert_list (defi);
ASET (tmp, i, defi);
}
def = tmp;
}
key = possibly_translate_key_sequence (key, &length);
ptrdiff_t idx = 0;
while (1)
{
Lisp_Object c = Faref (key, make_fixnum (idx));
if (CONSP (c))
{
/* C may be a Lucid style event type list or a cons (FROM .
TO) specifying a range of characters. */
if (lucid_event_type_list_p (c))
c = Fevent_convert_list (c);
else if (CHARACTERP (XCAR (c)))
CHECK_CHARACTER_CDR (c);
}
if (SYMBOLP (c))
silly_event_symbol_error (c);
if (FIXNUMP (c)
&& (XFIXNUM (c) & meta_bit)
&& !metized)
{
c = meta_prefix_char;
metized = true;
}
else
{
if (FIXNUMP (c))
XSETINT (c, XFIXNUM (c) & ~meta_bit);
metized = false;
idx++;
}
if (!FIXNUMP (c) && !SYMBOLP (c)
&& (!CONSP (c)
/* If C is a range, it must be a leaf. */
|| (FIXNUMP (XCAR (c)) && idx != length)))
message_with_string ("Key sequence contains invalid event %s", c, 1);
if (idx == length)
return store_in_keymap (keymap, c, def, !NILP (remove));
Lisp_Object cmd = access_keymap (keymap, c, 0, 1, 1);
/* If this key is undefined, make it a prefix. */
if (NILP (cmd))
cmd = define_as_prefix (keymap, c);
keymap = get_keymap (cmd, 0, 1);
if (!CONSP (keymap))
{
const char *trailing_esc = ((EQ (c, meta_prefix_char) && metized)
? (idx == 0 ? "ESC" : " ESC")
: "");
/* We must use Fkey_description rather than just passing key to
error; key might be a vector, not a string. */
error ("Key sequence %s starts with non-prefix key %s%s",
SDATA (Fkey_description (key, Qnil)),
SDATA (Fkey_description (Fsubstring (key, make_fixnum (0),
make_fixnum (idx)),
Qnil)),
trailing_esc);
}
}
}