mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-01-03 18:41:25 -08:00
(define-minor-mode): Warn about use of pre-Emacs-21 style args
* lisp/emacs-lisp/easy-mmode.el (define-minor-mode): Use `advertised-calling-convention` to avoid promoting the old style arguments. Emit a wanring when old-style arguments are used. Massage the docstring accordingly. * doc/lispref/modes.texi (Defining Minor Modes): Document the keyword arguments rather than the old-style positional arguments.
This commit is contained in:
parent
07671edbf0
commit
6bec60ad31
3 changed files with 129 additions and 139 deletions
|
|
@ -1660,7 +1660,7 @@ reserved for users. @xref{Key Binding Conventions}.
|
|||
The macro @code{define-minor-mode} offers a convenient way of
|
||||
implementing a mode in one self-contained definition.
|
||||
|
||||
@defmac define-minor-mode mode doc [init-value [lighter [keymap]]] keyword-args@dots{} body@dots{}
|
||||
@defmac define-minor-mode mode doc keyword-args@dots{} body@dots{}
|
||||
This macro defines a new minor mode whose name is @var{mode} (a
|
||||
symbol). It defines a command named @var{mode} to toggle the minor
|
||||
mode, with @var{doc} as its documentation string.
|
||||
|
|
@ -1675,14 +1675,36 @@ If @var{doc} is @code{nil}, the macro supplies a default documentation string
|
|||
explaining the above.
|
||||
|
||||
By default, it also defines a variable named @var{mode}, which is set to
|
||||
@code{t} or @code{nil} by enabling or disabling the mode. The variable
|
||||
is initialized to @var{init-value}. Except in unusual circumstances
|
||||
(see below), this value must be @code{nil}.
|
||||
@code{t} or @code{nil} by enabling or disabling the mode.
|
||||
|
||||
The @var{keyword-args} consist of keywords followed by
|
||||
corresponding values. A few keywords have special meanings:
|
||||
|
||||
@table @code
|
||||
@item :global @var{global}
|
||||
If non-@code{nil}, this specifies that the minor mode should be global
|
||||
rather than buffer-local. It defaults to @code{nil}.
|
||||
|
||||
One of the effects of making a minor mode global is that the
|
||||
@var{mode} variable becomes a customization variable. Toggling it
|
||||
through the Customize interface turns the mode on and off, and its
|
||||
value can be saved for future Emacs sessions (@pxref{Saving
|
||||
Customizations,,, emacs, The GNU Emacs Manual}. For the saved
|
||||
variable to work, you should ensure that the minor mode function
|
||||
is available each time Emacs starts; usually this is done by
|
||||
marking the @code{define-minor-mode} form as autoloaded.
|
||||
|
||||
@item :init-value @var{init-value}
|
||||
This is the value to which the @var{mode} variable is initialized.
|
||||
Except in unusual circumstances (see below), this value must be
|
||||
@code{nil}.
|
||||
|
||||
@item :lighter @var{lighter}
|
||||
The string @var{lighter} says what to display in the mode line
|
||||
when the mode is enabled; if it is @code{nil}, the mode is not displayed
|
||||
in the mode line.
|
||||
|
||||
@item :keymap @var{keymap}
|
||||
The optional argument @var{keymap} specifies the keymap for the minor
|
||||
mode. If non-@code{nil}, it should be a variable name (whose value is
|
||||
a keymap), a keymap, or an alist of the form
|
||||
|
|
@ -1697,42 +1719,6 @@ suitable for passing to @code{define-key} (@pxref{Changing Key
|
|||
Bindings}). If @var{keymap} is a keymap or an alist, this also
|
||||
defines the variable @code{@var{mode}-map}.
|
||||
|
||||
The above three arguments @var{init-value}, @var{lighter}, and
|
||||
@var{keymap} can be (partially) omitted when @var{keyword-args} are
|
||||
used. The @var{keyword-args} consist of keywords followed by
|
||||
corresponding values. A few keywords have special meanings:
|
||||
|
||||
@table @code
|
||||
@item :group @var{group}
|
||||
Custom group name to use in all generated @code{defcustom} forms.
|
||||
Defaults to @var{mode} without the possible trailing @samp{-mode}.
|
||||
@strong{Warning:} don't use this default group name unless you have
|
||||
written a @code{defgroup} to define that group properly. @xref{Group
|
||||
Definitions}.
|
||||
|
||||
@item :global @var{global}
|
||||
If non-@code{nil}, this specifies that the minor mode should be global
|
||||
rather than buffer-local. It defaults to @code{nil}.
|
||||
|
||||
One of the effects of making a minor mode global is that the
|
||||
@var{mode} variable becomes a customization variable. Toggling it
|
||||
through the Customize interface turns the mode on and off, and its
|
||||
value can be saved for future Emacs sessions (@pxref{Saving
|
||||
Customizations,,, emacs, The GNU Emacs Manual}. For the saved
|
||||
variable to work, you should ensure that the @code{define-minor-mode}
|
||||
form is evaluated each time Emacs starts; for packages that are not
|
||||
part of Emacs, the easiest way to do this is to specify a
|
||||
@code{:require} keyword.
|
||||
|
||||
@item :init-value @var{init-value}
|
||||
This is equivalent to specifying @var{init-value} positionally.
|
||||
|
||||
@item :lighter @var{lighter}
|
||||
This is equivalent to specifying @var{lighter} positionally.
|
||||
|
||||
@item :keymap @var{keymap}
|
||||
This is equivalent to specifying @var{keymap} positionally.
|
||||
|
||||
@item :variable @var{place}
|
||||
This replaces the default variable @var{mode}, used to store the state
|
||||
of the mode. If you specify this, the @var{mode} variable is not
|
||||
|
|
|
|||
5
etc/NEWS
5
etc/NEWS
|
|
@ -2363,6 +2363,11 @@ This is to keep the same behavior as Eshell.
|
|||
|
||||
* Incompatible Lisp Changes in Emacs 28.1
|
||||
|
||||
+++
|
||||
** The use of positional arguments in 'define-minor-mode' is obsolete.
|
||||
These were actually rendered obsolete in Emacs-21 but were never
|
||||
marked as such.
|
||||
|
||||
** 'facemenu-color-alist' is now obsolete, and is not used.
|
||||
|
||||
** 'facemenu.el' is no longer preloaded.
|
||||
|
|
|
|||
|
|
@ -139,39 +139,31 @@ documenting what its argument does. If the word \"ARG\" does not
|
|||
appear in DOC, a paragraph is added to DOC explaining
|
||||
usage of the mode argument.
|
||||
|
||||
Optional INIT-VALUE is the initial value of the mode's variable.
|
||||
Note that the minor mode function won't be called by setting
|
||||
this option, so the value *reflects* the minor mode's natural
|
||||
initial state, rather than *setting* it.
|
||||
In the vast majority of cases it should be nil.
|
||||
Optional LIGHTER is displayed in the mode line when the mode is on.
|
||||
Optional KEYMAP is the default keymap bound to the mode keymap.
|
||||
If non-nil, it should be a variable name (whose value is a keymap),
|
||||
or an expression that returns either a keymap or a list of
|
||||
(KEY . BINDING) pairs where KEY and BINDING are suitable for
|
||||
`define-key'. If you supply a KEYMAP argument that is not a
|
||||
symbol, this macro defines the variable MODE-map and gives it
|
||||
the value that KEYMAP specifies.
|
||||
|
||||
BODY contains code to execute each time the mode is enabled or disabled.
|
||||
It is executed after toggling the mode, and before running MODE-hook.
|
||||
Before the actual body code, you can write keyword arguments, i.e.
|
||||
alternating keywords and values. If you provide BODY, then you must
|
||||
provide (even if just nil) INIT-VALUE, LIGHTER, and KEYMAP, or provide
|
||||
at least one keyword argument, or both; otherwise, BODY would be
|
||||
misinterpreted as the first omitted argument. The following special
|
||||
provide at least one keyword argument. The following special
|
||||
keywords are supported (other keywords are passed to `defcustom' if
|
||||
the minor mode is global):
|
||||
|
||||
:group GROUP Custom group name to use in all generated `defcustom' forms.
|
||||
:global GLOBAL If non-nil specifies that the minor mode is not meant to be
|
||||
buffer-local, so don't make the variable MODE buffer-local.
|
||||
By default, the mode is buffer-local.
|
||||
:init-value VAL Same as the INIT-VALUE argument.
|
||||
:init-value VAL the initial value of the mode's variable.
|
||||
Note that the minor mode function won't be called by setting
|
||||
this option, so the value *reflects* the minor mode's natural
|
||||
initial state, rather than *setting* it.
|
||||
In the vast majority of cases it should be nil.
|
||||
Not used if you also specify :variable.
|
||||
:lighter SPEC Same as the LIGHTER argument.
|
||||
:keymap MAP Same as the KEYMAP argument.
|
||||
:require SYM Same as in `defcustom'.
|
||||
:lighter SPEC Text displayed in the mode line when the mode is on.
|
||||
:keymap MAP Keymap bound to the mode keymap. Defaults to `MODE-map'.
|
||||
If non-nil, it should be a variable name (whose value is
|
||||
a keymap), or an expression that returns either a keymap or
|
||||
a list of (KEY . BINDING) pairs where KEY and BINDING are
|
||||
suitable for `define-key'. If you supply a KEYMAP argument
|
||||
that is not a symbol, this macro defines the variable MODE-map
|
||||
and gives it the value that KEYMAP specifies.
|
||||
:interactive VAL Whether this mode should be a command or not. The default
|
||||
is to make it one; use nil to avoid that. If VAL is a list,
|
||||
it's interpreted as a list of major modes this minor mode
|
||||
|
|
@ -185,15 +177,18 @@ BODY contains code to execute each time the mode is enabled or disabled.
|
|||
sets it. If you specify a :variable, this function does
|
||||
not define a MODE variable (nor any of the terms used
|
||||
in :variable).
|
||||
|
||||
:after-hook A single lisp form which is evaluated after the mode hooks
|
||||
have been run. It should not be quoted.
|
||||
|
||||
For example, you could write
|
||||
(define-minor-mode foo-mode \"If enabled, foo on you!\"
|
||||
:lighter \" Foo\" :require \\='foo :global t :group \\='hassle :version \"27.5\"
|
||||
...BODY CODE...)"
|
||||
...BODY CODE...)
|
||||
|
||||
For backward compatibility with the Emacs<21 calling convention,
|
||||
BODY can also start with the triplet INIT-VALUE LIGHTER KEYMAP."
|
||||
(declare (doc-string 2)
|
||||
(advertised-calling-convention (mode doc &rest body) "28.1")
|
||||
(debug (&define name string-or-null-p
|
||||
[&optional [¬ keywordp] sexp
|
||||
&optional [¬ keywordp] sexp
|
||||
|
|
@ -201,6 +196,31 @@ For example, you could write
|
|||
[&rest [keywordp sexp]]
|
||||
def-body)))
|
||||
|
||||
(let* ((last-message (make-symbol "last-message"))
|
||||
(mode-name (symbol-name mode))
|
||||
(pretty-name nil)
|
||||
(globalp nil)
|
||||
(set nil)
|
||||
(initialize nil)
|
||||
(type nil)
|
||||
(extra-args nil)
|
||||
(extra-keywords nil)
|
||||
(variable nil) ;The PLACE where the state is stored.
|
||||
(setter `(setq ,mode)) ;The beginning of the exp to set the mode var.
|
||||
(getter mode) ;The exp to get the mode value.
|
||||
(modefun mode) ;The minor mode function name we're defining.
|
||||
(after-hook nil)
|
||||
(hook (intern (concat mode-name "-hook")))
|
||||
(hook-on (intern (concat mode-name "-on-hook")))
|
||||
(hook-off (intern (concat mode-name "-off-hook")))
|
||||
(interactive t)
|
||||
(warnwrap (if (keywordp init-value) #'identity
|
||||
(lambda (exp)
|
||||
(macroexp-warn-and-return
|
||||
"Use keywords rather than deprecated positional arguments to `define-minor-mode'"
|
||||
exp))))
|
||||
keyw keymap-sym tmp)
|
||||
|
||||
;; Allow skipping the first three args.
|
||||
(cond
|
||||
((keywordp init-value)
|
||||
|
|
@ -211,28 +231,6 @@ For example, you could write
|
|||
(setq body `(,lighter ,keymap ,@body) lighter nil keymap nil))
|
||||
((keywordp keymap) (push keymap body) (setq keymap nil)))
|
||||
|
||||
(let* ((last-message (make-symbol "last-message"))
|
||||
(mode-name (symbol-name mode))
|
||||
(pretty-name (easy-mmode-pretty-mode-name mode lighter))
|
||||
(globalp nil)
|
||||
(set nil)
|
||||
(initialize nil)
|
||||
(group nil)
|
||||
(type nil)
|
||||
(extra-args nil)
|
||||
(extra-keywords nil)
|
||||
(variable nil) ;The PLACE where the state is stored.
|
||||
(setter `(setq ,mode)) ;The beginning of the exp to set the mode var.
|
||||
(getter mode) ;The exp to get the mode value.
|
||||
(modefun mode) ;The minor mode function name we're defining.
|
||||
(require t)
|
||||
(after-hook nil)
|
||||
(hook (intern (concat mode-name "-hook")))
|
||||
(hook-on (intern (concat mode-name "-on-hook")))
|
||||
(hook-off (intern (concat mode-name "-off-hook")))
|
||||
(interactive t)
|
||||
keyw keymap-sym tmp)
|
||||
|
||||
;; Check keys.
|
||||
(while (keywordp (setq keyw (car body)))
|
||||
(setq body (cdr body))
|
||||
|
|
@ -246,9 +244,7 @@ For example, you could write
|
|||
(:extra-args (setq extra-args (pop body)))
|
||||
(:set (setq set (list :set (pop body))))
|
||||
(:initialize (setq initialize (list :initialize (pop body))))
|
||||
(:group (setq group (nconc group (list :group (pop body)))))
|
||||
(:type (setq type (list :type (pop body))))
|
||||
(:require (setq require (pop body)))
|
||||
(:keymap (setq keymap (pop body)))
|
||||
(:interactive (setq interactive (pop body)))
|
||||
(:variable (setq variable (pop body))
|
||||
|
|
@ -264,6 +260,7 @@ For example, you could write
|
|||
(:after-hook (setq after-hook (pop body)))
|
||||
(_ (push keyw extra-keywords) (push (pop body) extra-keywords))))
|
||||
|
||||
(setq pretty-name (easy-mmode-pretty-mode-name mode lighter))
|
||||
(setq keymap-sym (if (and keymap (symbolp keymap)) keymap
|
||||
(intern (concat mode-name "-map"))))
|
||||
|
||||
|
|
@ -301,13 +298,13 @@ or call the function `%s'."))))
|
|||
,(format base-doc-string pretty-name mode mode)
|
||||
,@set
|
||||
,@initialize
|
||||
,@group
|
||||
,@type
|
||||
,@(unless (eq require t) `(:require ,require))
|
||||
,@(nreverse extra-keywords)))))
|
||||
|
||||
;; The actual function.
|
||||
(defun ,modefun (&optional arg ,@extra-args)
|
||||
,(funcall
|
||||
warnwrap
|
||||
`(defun ,modefun (&optional arg ,@extra-args)
|
||||
,(easy-mmode--mode-docstring doc pretty-name keymap-sym)
|
||||
,(when interactive
|
||||
;; Use `toggle' rather than (if ,mode 0 1) so that using
|
||||
|
|
@ -318,7 +315,8 @@ or call the function `%s'."))))
|
|||
(prefix-numeric-value current-prefix-arg)
|
||||
'toggle))
|
||||
,@interactive)
|
||||
'(interactive (list (if current-prefix-arg
|
||||
'(interactive
|
||||
(list (if current-prefix-arg
|
||||
(prefix-numeric-value current-prefix-arg)
|
||||
'toggle)))))
|
||||
(let ((,last-message (current-message)))
|
||||
|
|
@ -343,7 +341,8 @@ or call the function `%s'."))))
|
|||
(push ',modefun global-minor-modes))))
|
||||
;; Ditto check.
|
||||
`((when (boundp 'local-minor-modes)
|
||||
(setq local-minor-modes (delq ',modefun local-minor-modes))
|
||||
(setq local-minor-modes
|
||||
(delq ',modefun local-minor-modes))
|
||||
(when ,getter
|
||||
(push ',modefun local-minor-modes)))))
|
||||
,@body
|
||||
|
|
@ -364,7 +363,7 @@ or call the function `%s'."))))
|
|||
,@(when after-hook `(,after-hook)))
|
||||
(force-mode-line-update)
|
||||
;; Return the new setting.
|
||||
,getter)
|
||||
,getter))
|
||||
|
||||
;; Autoloading a define-minor-mode autoloads everything
|
||||
;; up-to-here.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue