[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

bug#25505: 24.5; doc of `define-minor-mode': incorrect for :keymap

From: Drew Adams
Subject: bug#25505: 24.5; doc of `define-minor-mode': incorrect for :keymap
Date: Mon, 23 Jan 2017 09:12:00 -0800 (PST)

Consider this code.  Evaluate the defvar, and then try to evaluate
each of the define-minor-mode sexps, in turn.  The only difference
among the mode-defining sexps is whether the :group and :keymap
values are quoted or unquoted symbols.

(defvar foo-map  (let ((map  (make-sparse-keymap)))
                   (define-key map "q" 'forward-char)

(define-minor-mode foo-mode "..."
  :global t :group 'convenience :init-value nil :keymap 'foo-map)

Debugger entered--Lisp error: (error "Invalid keymap foo-map")
  signal(error ("Invalid keymap foo-map"))
  error("Invalid keymap %S" foo-map)

(define-minor-mode foo-mode "..."
  :global t :group convenience :init-value nil :keymap foo-map)

Debugger entered--Lisp error: (void-variable convenience)
  (custom-declare-variable (quote foo-mode) (quote nil) "Non-nil if Foo mode is 
enabled.\nSee the `foo-mode' command\nfor a description of this minor mode." 
:set (function custom-set-minor-mode) :initialize (quote 
custom-initialize-default) :group convenience :type (quote boolean))

(define-minor-mode foo-mode "..."
  :global t :group convenience :init-value nil :keymap 'foo-map)

Same error as previous.

(define-minor-mode foo-mode "..."
  :global t :group 'convenience :init-value nil :keymap foo-map)

Whew!  Success, finally.  But it does not correspond to the doc.
And the behavior is not consistent.


How does Emacs's own Lisp code deal with this?  In different ways.

Here is allout.el, for example.  It DOES use a quoted map-variable
(and it jumps through a few hoops).

(defvar allout-mode-map 'allout-mode-map
  "Keybindings place-holder for (allout) outline minor mode.
Do NOT set the value of this variable.  Instead, customize
`allout-command-prefix', `allout-prefixed-keybindings', and

(defvar allout-mode-map-value nil
  "Keymap for allout outline minor mode.
Do NOT set the value of this variable.  Instead, customize
`allout-command-prefix', `allout-prefixed-keybindings', and

;;;_    = make allout-mode-map-value an alias for allout-mode-map:
;; this needs to be revised when the value is changed, sigh.
(defalias 'allout-mode-map allout-mode-map-value)

(defun allout-institute-keymap (map)
  "Associate allout-mode bindings with allout as a minor mode."
  ;; Architecture:
  ;; allout-mode-map var is a keymap by virtue of being a defalias for
  ;; allout-mode-map-value, which has the actual keymap value.
  ;; allout-mode-map's symbol value is just 'allout-mode-map, so it can be
  ;; used in minor-mode-map-alist to indirect to the actual
  ;; allout-mode-map-var value, which can be adjusted and reassigned.
  ;; allout-mode-map-value for keymap reference in various places:
  (setq allout-mode-map-value map)
  ;; the function value keymap of allout-mode-map is used in
  ;; minor-mode-map-alist - update it:
  (fset allout-mode-map allout-mode-map-value))

(define-minor-mode allout-mode "..."
  :lighter " Allout" :keymap 'allout-mode-map

Next up: autoarg-mode.  This uses an UNquoted map variable.

(defvar autoarg-mode-map
  (let ((map (make-sparse-keymap)))
    (define-key map " " 'autoarg-terminate)
  "Keymap for Autoarg mode.")

(define-minor-mode autoarg-mode "..."
  nil " Aarg" autoarg-mode-map :global t :group 'keyboard)

Those are only the first two grep hits for `define-minor-mode'.

Isn't this more than a doc bug?  Why should the :group value be
evaluated but not the :keymap value?

At any rate, none of the current behavior in this regard is
documented.  Users need to experiment to find out what the
real story is.

Am I missing something?  `define-minor-mode' has been around
since at least Emacs 22.  Has this behavior inconsistency and
missing doc never been noticed before?

reply via email to

[Prev in Thread] Current Thread [Next in Thread]