Function: defvar-keymap

defvar-keymap is a macro defined in keymap.el.gz.

Signature

(defvar-keymap VARIABLE-NAME &key DOC FULL PARENT SUPPRESS NAME PREFIX KEYMAP REPEAT &rest [KEY DEFINITION]...)

Documentation

Define VARIABLE-NAME as a variable with a keymap definition.

See define-keymap for an explanation of the keywords and KEY/DEFINITION.

In addition to the keywords accepted by define-keymap, this macro also accepts a :doc keyword, which (if present) is used as the variable documentation string.

The :prefix keyword can take an additional value, t, which is an abbreviation for using VARIABLE-NAME as the prefix command name.

The :repeat keyword can also be specified; it controls the repeat-mode(var)/repeat-mode(fun) behavior of the bindings in the keymap. When it is non-nil, all commands in the map will have the repeat-map symbol property.

More control is available over which commands are repeatable; the value can also be a property list with properties :enter,
:exit and :hints, for example:

     :repeat (:enter (commands ...) :exit (commands ...)
              :continue (commands ...)
              :hints ((command . "hint") ...))

:enter specifies the list of additional commands that only
enter repeat-mode(var)/repeat-mode(fun). When the list is empty, then only the commands defined in the map enter repeat-mode(var)/repeat-mode(fun). Specifying a list of commands is useful when there are commands that have the repeat-map symbol property, but don't exist in this specific map.

:exit is a list of commands that exit repeat-mode(var)/repeat-mode(fun). When the
list is empty, no commands in the map exit repeat-mode(var)/repeat-mode(fun). Specifying a list of commands is useful when those commands exist in this specific map, but should not have the repeat-map symbol property.

:continue specifies the list of commands that should not
enter repeat-mode(var)/repeat-mode(fun). These command should only continue the already activated repeating sequence.

:hints is a list of cons pairs where car is a command and
cdr is a string that is displayed alongside of the repeatable key in the echo area.

Other relevant functions are documented in the keymaps group.

View in manual

Probably introduced at or before Emacs version 29.1.

Shortdoc

;; keymaps
(defvar-keymap my-keymap "C-c C-c" #'quit-buffer)

Source Code

;; Defined in /usr/src/emacs/lisp/keymap.el.gz
(defmacro defvar-keymap (variable-name &rest defs)
  "Define VARIABLE-NAME as a variable with a keymap definition.
See `define-keymap' for an explanation of the keywords and KEY/DEFINITION.

In addition to the keywords accepted by `define-keymap', this
macro also accepts a `:doc' keyword, which (if present) is used
as the variable documentation string.

The `:prefix' keyword can take an additional value, t, which is an
abbreviation for using VARIABLE-NAME as the prefix command name.

The `:repeat' keyword can also be specified; it controls the
`repeat-mode' behavior of the bindings in the keymap.  When it is
non-nil, all commands in the map will have the `repeat-map'
symbol property.

More control is available over which commands are repeatable; the
value can also be a property list with properties `:enter',
`:exit' and `:hints', for example:

     :repeat (:enter (commands ...) :exit (commands ...)
              :continue (commands ...)
              :hints ((command . \"hint\") ...))

`:enter' specifies the list of additional commands that only
enter `repeat-mode'.  When the list is empty, then only the
commands defined in the map enter `repeat-mode'.  Specifying a
list of commands is useful when there are commands that have the
`repeat-map' symbol property, but don't exist in this specific
map.

`:exit' is a list of commands that exit `repeat-mode'.  When the
list is empty, no commands in the map exit `repeat-mode'.
Specifying a list of commands is useful when those commands exist
in this specific map, but should not have the `repeat-map' symbol
property.

`:continue' specifies the list of commands that should not
enter `repeat-mode'.  These command should only continue the
already activated repeating sequence.

`:hints' is a list of cons pairs where car is a command and
cdr is a string that is displayed alongside of the repeatable key
in the echo area.

\(fn VARIABLE-NAME &key DOC FULL PARENT SUPPRESS NAME PREFIX KEYMAP REPEAT &rest [KEY DEFINITION]...)"
  (declare (indent 1))
  (let ((opts nil)
        doc repeat props)
    (while (and defs
                (keywordp (car defs))
                (not (eq (car defs) :menu)))
      (let ((keyword (pop defs)))
        (unless defs
          (error "Uneven number of keywords"))
        (cond
         ((eq keyword :doc)
          (setq doc (pop defs)))
         ((eq keyword :repeat)
          (setq repeat (pop defs)))
         ((and (eq keyword :prefix) (eq (car defs) t))
          (setq defs (cdr defs))
          (push keyword opts)
          (push `',variable-name opts))
         (t
          (push keyword opts)
          (push (pop defs) opts)))))
    (unless (zerop (% (length defs) 2))
      (error "Uneven number of key/definition pairs: %s" defs))

    (let ((defs defs)
          key seen-keys)
      (while defs
        (setq key (pop defs))
        (pop defs)
        (when (not (eq key :menu))
          (if (member key seen-keys)
              (error "Duplicate definition for key '%s' in keymap '%s'"
                     key variable-name)
            (push key seen-keys)))))

    (when repeat
      (let ((defs defs)
            def)
        (dolist (def (plist-get repeat :enter))
          (push `(put ',def 'repeat-map ',variable-name) props))
        (dolist (def (plist-get repeat :continue))
          (push `(let ((val (get ',def 'repeat-continue)))
                   (when (listp val)
                     (put ',def 'repeat-continue
                          (cons ',variable-name val))))
                props))
        (while defs
          (pop defs)
          (setq def (pop defs))
          (when (and (memq (car def) '(function quote))
                     (not (memq (cadr def) (plist-get repeat :exit))))
            (push `(put ,def 'repeat-map ',variable-name) props)))
        (dolist (def (plist-get repeat :hints))
          (push `(put ',(car def) 'repeat-hint ',(cdr def)) props))))

    (let ((defvar-form
           `(defvar ,variable-name
              (define-keymap ,@(nreverse opts) ,@defs)
              ,@(and doc (list doc)))))
      (if props
          `(progn
             ,defvar-form
             ,@(nreverse props))
        defvar-form))))