[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)
map)
"...")
(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
`allout-unprefixed-keybindings'.")
(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
`allout-unprefixed-keybindings'.")
;;;_ = 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)
map)
"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?