unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
* bug#67034: 30.0.50; Make `derived-mode-p` take a single arg
@ 2023-11-10  3:58 Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2023-11-10 12:18 ` Daniel Mendler
  2023-11-16 22:28 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
  0 siblings, 2 replies; 9+ messages in thread
From: Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2023-11-10  3:58 UTC (permalink / raw)
  To: 67034

Package: Emacs
Version: 30.0.50


Looking at uses of `derived-mode-p`, I can't find a single use case
where it wouldn't be preferable for it to take a single argument
instead of `&rest`: all the calls are either passing a single
argument anyway, or passing a fixed list of modes.

So making `derived-mode-p` take a single arg (which we'd allow to be
either a mode or a list of modes) would not make any real difference to
the callers (it would even be more convenient since it could often avoid
the use of `apply`), and in return we'd save allocating the
`&rest` list.

Same for `provided-mode-derived-p`.

And yes, I plead guilty for the `&rest` of `derived-mode-p`.
Seemed like a good idea at the time :-(

Draft patch below.


        Stefan


diff --git a/lisp/subr.el b/lisp/subr.el
index d4173b4daba..cd6407ef4b2 100644
--- a/lisp/subr.el
+++ b/lisp/subr.el
@@ -2678,11 +2678,17 @@ while-let
 
 ;; PUBLIC: find if the current mode derives from another.
 
-(defun provided-mode-derived-p (mode &rest modes)
+(defun provided-mode-derived-p (mode &optional parent &rest modes)
   "Non-nil if MODE is derived from one of MODES.
 Uses the `derived-mode-parent' property of the symbol to trace backwards.
 If you just want to check `major-mode', use `derived-mode-p'."
-  (declare (side-effect-free t))
+  (declare (side-effect-free t)
+           (advertised-calling-convention (mode parent) "30.1"))
+  (setq modes (if (not (listp parent))
+                  (cons parent modes)
+                ;; New calling convention can't use MODES at the same time.
+                (cl-assert (null modes))
+                parent))
   (while
       (and
        (not (memq mode modes))
@@ -2693,11 +2699,19 @@ provided-mode-derived-p
                          (and (symbolp alias) alias)))))))
   mode)
 
-(defun derived-mode-p (&rest modes)
-  "Non-nil if the current major mode is derived from one of MODES.
-Uses the `derived-mode-parent' property of the symbol to trace backwards."
-  (declare (side-effect-free t))
-  (apply #'provided-mode-derived-p major-mode modes))
+(defun derived-mode-p (&optional mode &rest modes)
+  "Non-nil if the current major mode is derived from MODE.
+MODE can also be a list of modes, in which case we check if major mode
+is derived from one of them.
+It also supports an obsolete `&rest MODES' calling convention."
+  (declare (side-effect-free t)
+           (advertised-calling-convention (mode) "30.1"))
+  (provided-mode-derived-p major-mode
+                           (if (not (listp mode)) (cons mode modes)
+                             ;; New calling convention can't use MODES
+                             ;; at the same time.
+                             (cl-assert (null modes))
+                             mode)))
 
 (defvar-local major-mode--suspended nil)
 (put 'major-mode--suspended 'permanent-local t)






^ permalink raw reply related	[flat|nested] 9+ messages in thread

* bug#67034: 30.0.50; Make `derived-mode-p` take a single arg
  2023-11-10  3:58 bug#67034: 30.0.50; Make `derived-mode-p` take a single arg Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2023-11-10 12:18 ` Daniel Mendler
  2023-11-11  0:04   ` Dmitry Gutov
  2023-11-16 22:38   ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2023-11-16 22:28 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
  1 sibling, 2 replies; 9+ messages in thread
From: Daniel Mendler @ 2023-11-10 12:18 UTC (permalink / raw)
  To: 67034

This change would affect many packages. I grepped through my elpa
directory and found multiple uses of derived-mode-p and
provided-mode-derived-p with multiple arguments as shortcuts:

(derived-mode-p 'mode1 'mode2) instead of (or (derived-mode-p 'mode1)
(derived-mode-p 'mode2)

There are also multiple call sites with apply, but these would be
arguably nicer if derived-mode-p takes a list argument as proposed.
Still, do the benefits of this change outweigh the required changes?





^ permalink raw reply	[flat|nested] 9+ messages in thread

* bug#67034: 30.0.50; Make `derived-mode-p` take a single arg
  2023-11-10 12:18 ` Daniel Mendler
@ 2023-11-11  0:04   ` Dmitry Gutov
  2023-11-11  9:08     ` Daniel Mendler
  2023-11-16 22:38   ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
  1 sibling, 1 reply; 9+ messages in thread
From: Dmitry Gutov @ 2023-11-11  0:04 UTC (permalink / raw)
  To: Daniel Mendler, 67034

On 10/11/2023 14:18, Daniel Mendler wrote:
> There are also multiple call sites with apply, but these would be
> arguably nicer if derived-mode-p takes a list argument as proposed.
> Still, do the benefits of this change outweigh the required changes?

I've also found some call sites with multiple arguments (one of them 
being sml-mode 6.12) and also uses with (apply #'derived-mode-p 
some-user-option-list-of-modes). But those are indeed in the minority.

I wonder if this extra allocation of &rest makes any difference in any 
benchmark, though.





^ permalink raw reply	[flat|nested] 9+ messages in thread

* bug#67034: 30.0.50; Make `derived-mode-p` take a single arg
  2023-11-11  0:04   ` Dmitry Gutov
@ 2023-11-11  9:08     ` Daniel Mendler
  0 siblings, 0 replies; 9+ messages in thread
From: Daniel Mendler @ 2023-11-11  9:08 UTC (permalink / raw)
  To: Dmitry Gutov, 67034

On 11/11/23 01:04, Dmitry Gutov wrote:
> I wonder if this extra allocation of &rest makes any difference in any 
> benchmark, though.

derived-mode-p is usually not called in some kind of hot loop, but
rather during initialization/setup. So it shouldn't matter? I am
generally a bit wary of backward incompatible calling convention changes.





^ permalink raw reply	[flat|nested] 9+ messages in thread

* bug#67034: 30.0.50; Make `derived-mode-p` take a single arg
  2023-11-10  3:58 bug#67034: 30.0.50; Make `derived-mode-p` take a single arg Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2023-11-10 12:18 ` Daniel Mendler
@ 2023-11-16 22:28 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2023-11-17  8:24   ` Eli Zaretskii
  1 sibling, 1 reply; 9+ messages in thread
From: Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2023-11-16 22:28 UTC (permalink / raw)
  To: 67034

[-- Attachment #1: Type: text/plain, Size: 69 bytes --]

> Draft patch below.

More realistic patches below.


        Stefan

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-derived-mode-p-Take-MODES-as-a-single-argument.patch --]
[-- Type: text/x-diff, Size: 3666 bytes --]

From 6ccf21f1e3137012d0335fac05dfc476cc9ebec2 Mon Sep 17 00:00:00 2001
From: Stefan Monnier <monnier@iro.umontreal.ca>
Date: Thu, 16 Nov 2023 17:21:18 -0500
Subject: [PATCH 1/2] (derived-mode-p): Take MODES as a single argument

Looking at uses of `derived-mode-p` and `provide-mode-derived-p`,
I can't find a single use case where it wouldn't be preferable for
it to take a single argument instead of `&rest`: all the calls are
either passing a single argument anyway, or passing a fixed list of modes.
The use of `&rest` just makes the code less efficient and sometimes
more clunky (because of the need for `apply`).
So let's change that (while preserving backward compatibility, of course).

* doc/lispref/modes.texi (Derived Modes): Adjust accordingly.

* lisp/subr.el (provided-mode-derived-p, derived-mode-p): Take the
`modes` as a single argument.
---
 doc/lispref/modes.texi |  6 +++++-
 lisp/subr.el           | 26 +++++++++++++++++++-------
 2 files changed, 24 insertions(+), 8 deletions(-)

diff --git a/doc/lispref/modes.texi b/doc/lispref/modes.texi
index 130bc10cd59..1d60c3a01e0 100644
--- a/doc/lispref/modes.texi
+++ b/doc/lispref/modes.texi
@@ -932,9 +932,13 @@ Derived Modes
 @code{define-derived-mode} does that automatically.
 @end defmac
 
-@defun derived-mode-p &rest modes
+@defun derived-mode-p modes
 This function returns non-@code{nil} if the current major mode is
 derived from any of the major modes given by the symbols @var{modes}.
+Instead of a list, @var{modes} can also be a single symbol.
+
+Furthermore, we still support a deprecated calling convention where the
+@var{modes} were passed as separate arguments.
 @end defun
 
 The graph of major modes is accessed with the following lower-level
diff --git a/lisp/subr.el b/lisp/subr.el
index dcf49509177..dd01d79b1d0 100644
--- a/lisp/subr.el
+++ b/lisp/subr.el
@@ -2782,19 +2782,31 @@ derived-mode-all-parents
             (cons mode (remq mode all-parents))
           (put mode 'derived-mode--all-parents (cons mode all-parents))))))))
 
-(defun provided-mode-derived-p (mode &rest modes)
+(defun provided-mode-derived-p (mode &optional modes &rest old-modes)
   "Non-nil if MODE is derived from one of MODES.
-If you just want to check `major-mode', use `derived-mode-p'."
-  (declare (side-effect-free t))
+MODES can also be a single mode instead of a list.
+If you just want to check `major-mode', use `derived-mode-p'.
+We also still support the deprecated calling convention:
+\(provided-mode-derived-p MODE &rest MODES)."
+  (declare (side-effect-free t)
+           (advertised-calling-convention (mode modes) "30.1"))
+  (cond
+   (old-modes (setq modes (cons modes old-modes)))
+   ((not (listp modes)) (setq modes (list modes))))
   (let ((ps (derived-mode-all-parents mode)))
     (while (and modes (not (memq (car modes) ps)))
       (setq modes (cdr modes)))
     (car modes)))
 
-(defun derived-mode-p (&rest modes)
-  "Non-nil if the current major mode is derived from one of MODES."
-  (declare (side-effect-free t))
-  (apply #'provided-mode-derived-p major-mode modes))
+(defun derived-mode-p (&optional modes &rest old-modes)
+ "Non-nil if the current major mode is derived from one of MODES.
+MODES can also be a single mode instead of a list.
+We also still support the deprecated calling convention:
+\(derived-mode-p &rest MODES)."
+ (declare (side-effect-free t)
+          (advertised-calling-convention (modes) "30.1"))
+ (provided-mode-derived-p major-mode (if old-modes (cons modes old-modes)
+                                       modes)))
 
 (defun derived-mode-set-parent (mode parent)
   "Declare PARENT to be the parent of MODE."
-- 
2.42.0


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: 0002-Adjust-affected-callers-of-derived-mode-p-to-use-the.patch --]
[-- Type: text/x-diff, Size: 17363 bytes --]

From 705f1c15469985cb6387663c85c4d29fc66729b9 Mon Sep 17 00:00:00 2001
From: Stefan Monnier <monnier@iro.umontreal.ca>
Date: Mon, 13 Nov 2023 19:09:17 -0500
Subject: [PATCH 2/2] Adjust affected callers of derived-mode-p` to use the new
 convention

* lisp/align.el (align-rules-list): Prefer `derived-mode-p` over
`provided-mode-derived-p`.
(align--rule-should-run):
* lisp/window.el (display-buffer-reuse-mode-window):
* lisp/whitespace.el (whitespace-enable-predicate):
* lisp/transient.el (transient--do-suffix-p):
* lisp/so-long.el (so-long--set-auto-mode):
* lisp/simple.el (command-completion-with-modes-p):
* lisp/progmodes/tcl.el (tcl-current-word):
* lisp/progmodes/idlwave.el (idlwave-fix-keywords):
* lisp/progmodes/gdb-mi.el (gdb, gdb-locals-mode-map)
(gdb-registers-mode-map, gdb-function-buffer-p):
* lisp/progmodes/c-ts-mode.el (c-ts-mode--indent-style-setter)
(c-ts-mode-set-style):
* lisp/progmodes/bug-reference.el (bug-reference--try-setup-gnus-article):
* lisp/help-fns.el (help-fns--list-local-commands):
* lisp/emulation/viper.el (viper-mode)
(viper-this-major-mode-requires-vi-state):
* lisp/emacs-lisp/easy-mmode.el (easy-mmode--globalized-predicate-p):
* lisp/dired.el (dired-hide-details-mode, dired-click-to-select-mode):
* lisp/calendar/todo-mode.el (todo-reset-nondiary-marker)
(todo-reset-done-string, todo-reset-comment-string):
* lisp/vc/vc.el (vc-deduce-backend): Use new calling convention for
`derived-mode-p` and `provided-mode-derived-p`.
---
 lisp/align.el                   |  5 ++---
 lisp/calendar/todo-mode.el      |  6 +++---
 lisp/dired.el                   |  4 ++--
 lisp/emacs-lisp/easy-mmode.el   |  2 +-
 lisp/emulation/viper.el         | 10 +++++-----
 lisp/help-fns.el                |  2 +-
 lisp/progmodes/bug-reference.el |  8 ++++----
 lisp/progmodes/c-ts-mode.el     |  4 ++--
 lisp/progmodes/gdb-mi.el        | 15 +++++++++------
 lisp/progmodes/idlwave.el       |  4 ++--
 lisp/progmodes/tcl.el           |  4 ++--
 lisp/simple.el                  |  4 +---
 lisp/so-long.el                 |  2 +-
 lisp/transient.el               |  5 +++--
 lisp/vc/vc.el                   |  2 +-
 lisp/whitespace.el              |  4 ++--
 lisp/window.el                  |  6 ++----
 17 files changed, 43 insertions(+), 44 deletions(-)

diff --git a/lisp/align.el b/lisp/align.el
index 9fa78525ecb..4daa20ddd2a 100644
--- a/lisp/align.el
+++ b/lisp/align.el
@@ -555,8 +555,7 @@ align-rules-list
      (repeat   . t)
      (run-if   . ,(lambda ()
                     (and (not (eq '- current-prefix-arg))
-                         (not (apply #'provided-mode-derived-p
-                                     major-mode align-tex-modes))))))
+                         (not (derived-mode-p align-tex-modes))))))
 
     ;; With a negative prefix argument, lists of dollar figures will
     ;; be aligned.
@@ -1286,7 +1285,7 @@ align--rule-should-run
 This is decided by the `modes' and `run-if' keys in the alist
 RULE.  Their meaning is documented in `align-rules-list' (which see)."
   (let-alist rule
-    (not (or (and .modes (not (apply #'derived-mode-p (eval .modes))))
+    (not (or (and .modes (not (derived-mode-p (eval .modes))))
              (and .run-if (not (funcall .run-if)))))))
 
 (defun align-region (beg end separate rules exclude-rules
diff --git a/lisp/calendar/todo-mode.el b/lisp/calendar/todo-mode.el
index 4f6a964eb4d..ab9d629d9fc 100644
--- a/lisp/calendar/todo-mode.el
+++ b/lisp/calendar/todo-mode.el
@@ -6350,7 +6350,7 @@ todo-reset-nondiary-marker
 		      (replace-match (nth 1 value) t t nil 2))
 		  (forward-line)))
 	      (if buf
-		  (when (derived-mode-p 'todo-mode 'todo-archive-mode)
+		  (when (derived-mode-p '(todo-mode todo-archive-mode))
 		    (todo-category-select))
 		(save-buffer)
 		(kill-buffer)))))))))
@@ -6394,7 +6394,7 @@ todo-reset-done-string
 		    (replace-match value t t nil 1)
 		  (forward-line)))
 	      (if buf
-		  (when (derived-mode-p 'todo-mode 'todo-archive-mode)
+		  (when (derived-mode-p '(todo-mode todo-archive-mode))
 		    (todo-category-select))
 		(save-buffer)
 		(kill-buffer)))))))))
@@ -6420,7 +6420,7 @@ todo-reset-comment-string
 		    (replace-match value t t nil 1)
 		  (forward-line)))
 	      (if buf
-		  (when (derived-mode-p 'todo-mode 'todo-archive-mode)
+		  (when (derived-mode-p '(todo-mode todo-archive-mode))
 		    (todo-category-select))
 		(save-buffer)
 		(kill-buffer)))))))))
diff --git a/lisp/dired.el b/lisp/dired.el
index 8919d2c223f..3f488afaa3c 100644
--- a/lisp/dired.el
+++ b/lisp/dired.el
@@ -3074,7 +3074,7 @@ dired-hide-details-mode
 See options: `dired-hide-details-hide-symlink-targets' and
 `dired-hide-details-hide-information-lines'."
   :group 'dired
-  (unless (derived-mode-p 'dired-mode 'wdired-mode)
+  (unless (derived-mode-p '(dired-mode wdired-mode))
     (error "Not a Dired buffer"))
   (dired-hide-details-update-invisibility-spec)
   (if dired-hide-details-mode
@@ -5096,7 +5096,7 @@ dired-click-to-select-mode
 completes."
   :group 'dired
   :lighter " Click-To-Select"
-  (unless (derived-mode-p 'dired-mode 'wdired-mode)
+  (unless (derived-mode-p '(dired-mode wdired-mode))
     (error "Not a Dired buffer"))
   (if dired-click-to-select-mode
       (setq-local tool-bar-map
diff --git a/lisp/emacs-lisp/easy-mmode.el b/lisp/emacs-lisp/easy-mmode.el
index 529f6e90e88..c9e7b3a4dfe 100644
--- a/lisp/emacs-lisp/easy-mmode.el
+++ b/lisp/emacs-lisp/easy-mmode.el
@@ -661,7 +661,7 @@ easy-mmode--globalized-predicate-p
           (throw 'found nil))
          ((and (consp elem)
                (eq (car elem) 'not))
-          (when (apply #'derived-mode-p (cdr elem))
+          (when (derived-mode-p (cdr elem))
             (throw 'found nil)))
          ((symbolp elem)
           (when (derived-mode-p elem)
diff --git a/lisp/emulation/viper.el b/lisp/emulation/viper.el
index 96da914275b..767ad57c471 100644
--- a/lisp/emulation/viper.el
+++ b/lisp/emulation/viper.el
@@ -593,8 +593,8 @@ viper-mode
 		    ))
 	      (viper-set-expert-level 'dont-change-unless)))
 
-	(or (apply #'derived-mode-p viper-emacs-state-mode-list) ; don't switch to Vi
-	    (apply #'derived-mode-p viper-insert-state-mode-list) ; don't switch
+	(or (derived-mode-p viper-emacs-state-mode-list) ; don't switch to Vi
+	    (derived-mode-p viper-insert-state-mode-list) ; don't switch
 	    (viper-change-state-to-vi))
 	))
 
@@ -607,9 +607,9 @@ viper-mode
 ;; that are not listed in viper-vi-state-mode-list
 (defun viper-this-major-mode-requires-vi-state (mode)
   (let ((major-mode mode))
-    (cond ((apply #'derived-mode-p viper-vi-state-mode-list) t)
-          ((apply #'derived-mode-p viper-emacs-state-mode-list) nil)
-          ((apply #'derived-mode-p viper-insert-state-mode-list) nil)
+    (cond ((derived-mode-p viper-vi-state-mode-list) t)
+          ((derived-mode-p viper-emacs-state-mode-list) nil)
+          ((derived-mode-p viper-insert-state-mode-list) nil)
           (t (and (eq (key-binding "a") 'self-insert-command)
                   (eq (key-binding " ") 'self-insert-command))))))
 
diff --git a/lisp/help-fns.el b/lisp/help-fns.el
index e723d97cfc2..a8c60946121 100644
--- a/lisp/help-fns.el
+++ b/lisp/help-fns.el
@@ -2240,7 +2240,7 @@ help-fns--list-local-commands
                   (not (get sym 'byte-obsolete-info))
                   ;; Ignore everything bound.
                   (not (where-is-internal sym nil t))
-                  (apply #'derived-mode-p (command-modes sym)))
+                  (derived-mode-p (command-modes sym)))
          (push sym functions))))
     (with-temp-buffer
       (when functions
diff --git a/lisp/progmodes/bug-reference.el b/lisp/progmodes/bug-reference.el
index 3f6e1e68e5b..0afed5276f5 100644
--- a/lisp/progmodes/bug-reference.el
+++ b/lisp/progmodes/bug-reference.el
@@ -467,10 +467,10 @@ bug-reference-mode
 (defun bug-reference--try-setup-gnus-article ()
   (when (and bug-reference-mode ;; Only if enabled in article buffers.
              (derived-mode-p
-              'gnus-article-mode
-              ;; Apparently, gnus-article-prepare-hook is run in the
-              ;; summary buffer...
-              'gnus-summary-mode)
+              '(gnus-article-mode
+                ;; Apparently, `gnus-article-prepare-hook' is run in the
+                ;; summary buffer...
+                gnus-summary-mode))
              gnus-article-buffer
              gnus-original-article-buffer
              (buffer-live-p (get-buffer gnus-article-buffer))
diff --git a/lisp/progmodes/c-ts-mode.el b/lisp/progmodes/c-ts-mode.el
index 70717a90caa..a56ce26fc79 100644
--- a/lisp/progmodes/c-ts-mode.el
+++ b/lisp/progmodes/c-ts-mode.el
@@ -135,7 +135,7 @@ c-ts-mode--indent-style-setter
               res)
       (let ((buffer (car buffers)))
         (with-current-buffer buffer
-          (if (derived-mode-p 'c-ts-mode 'c++-ts-mode)
+          (if (derived-mode-p '(c-ts-mode c++-ts-mode))
               (loop (append res (list buffer)) (cdr buffers))
             (loop res (cdr buffers))))))))
 
@@ -193,7 +193,7 @@ c-ts-mode-set-style
 To set the default indent style globally, use
 `c-ts-mode-set-global-style'."
   (interactive (list (c-ts-mode--prompt-for-style)))
-  (if (not (derived-mode-p 'c-ts-mode 'c++-ts-mode))
+  (if (not (derived-mode-p '(c-ts-mode c++-ts-mode)))
       (user-error "The current buffer is not in `c-ts-mode' nor `c++-ts-mode'")
     (setq-local c-ts-mode-indent-style style)
     (setq treesit-simple-indent-rules
diff --git a/lisp/progmodes/gdb-mi.el b/lisp/progmodes/gdb-mi.el
index 3afdc59a67e..7ae4bcea1e1 100644
--- a/lisp/progmodes/gdb-mi.el
+++ b/lisp/progmodes/gdb-mi.el
@@ -1006,9 +1006,10 @@ gdb
   (gud-def gud-pp
 	   (gud-call
 	    (concat
-	     "pp " (if (eq (buffer-local-value
-			    'major-mode (window-buffer)) 'speedbar-mode)
-		       (gdb-find-watch-expression) "%e")) arg)
+	     "pp " (if (eq (buffer-local-value 'major-mode (window-buffer))
+			   'speedbar-mode)
+		       (gdb-find-watch-expression) "%e"))
+	    arg)
 	   nil   "Print the Emacs s-expression.")
 
   (define-key gud-minor-mode-map [left-margin mouse-1]
@@ -4586,7 +4587,8 @@ gdb-locals-mode-map
                            (gdb-set-window-buffer
                             (gdb-get-buffer-create
                              'gdb-registers-buffer
-                             gdb-thread-number) t)))
+                             gdb-thread-number)
+                            t)))
     map))
 
 (define-derived-mode gdb-locals-mode gdb-parent-mode "Locals"
@@ -4706,7 +4708,8 @@ gdb-registers-mode-map
                            (gdb-set-window-buffer
                             (gdb-get-buffer-create
                              'gdb-locals-buffer
-                             gdb-thread-number) t)))
+                             gdb-thread-number)
+                            t)))
     (define-key map "f" #'gdb-registers-toggle-filter)
     map))
 
@@ -5106,7 +5109,7 @@ gdb-function-buffer-p
 not including main command buffer (the one where you type GDB
 commands) or source buffers (that display program source code)."
   (with-current-buffer buffer
-    (derived-mode-p 'gdb-parent-mode 'gdb-inferior-io-mode)))
+    (derived-mode-p '(gdb-parent-mode gdb-inferior-io-mode))))
 
 (defun gdb--buffer-type (buffer)
   "Return the type of BUFFER if it is a function buffer.
diff --git a/lisp/progmodes/idlwave.el b/lisp/progmodes/idlwave.el
index d9eccacc48b..f60cc9372eb 100644
--- a/lisp/progmodes/idlwave.el
+++ b/lisp/progmodes/idlwave.el
@@ -6892,7 +6892,7 @@ idlwave-one-key-select
     ;; Display prompt and wait for quick reply
     (message "%s[%s]" prompt
              (mapconcat (lambda(x) (char-to-string (car x)))
-                        keys-alist ""))
+                        keys-alist))
     (if (sit-for delay)
         ;; No quick reply: Show help
         (save-window-excursion
@@ -7958,7 +7958,7 @@ idlwave-fix-keywords
     ;; If this is the OBJ_NEW function, try to figure out the class and use
     ;; the keywords from the corresponding INIT method.
     (if (and (equal (upcase name) "OBJ_NEW")
-	     (derived-mode-p 'idlwave-mode 'idlwave-shell-mode))
+	     (derived-mode-p '(idlwave-mode idlwave-shell-mode)))
 	(let* ((bos (save-excursion (idlwave-beginning-of-statement) (point)))
 	       (string (buffer-substring bos (point)))
 	       (case-fold-search t)
diff --git a/lisp/progmodes/tcl.el b/lisp/progmodes/tcl.el
index ba0cbc8b066..b983c671cd9 100644
--- a/lisp/progmodes/tcl.el
+++ b/lisp/progmodes/tcl.el
@@ -1340,7 +1340,7 @@ tcl-current-word
 If FLAG is nil, just uses `current-word'.
 Otherwise scans backward for most likely Tcl command word."
   (if (and flag
-	   (derived-mode-p 'tcl-mode 'inferior-tcl-mode))
+	   (derived-mode-p '(tcl-mode inferior-tcl-mode)))
       (condition-case nil
 	  (save-excursion
 	    ;; Look backward for first word actually in alist.
@@ -1575,7 +1575,7 @@ tcl-quote
 	       (if (memq char '(?\[ ?\] ?{ ?} ?\\ ?\" ?$ ?\s ?\;))
 		   (concat "\\" (char-to-string char))
 		 (char-to-string char)))
-	     string ""))
+	     string))
 
 \f
 
diff --git a/lisp/simple.el b/lisp/simple.el
index de6eed3fe8f..2e2d73e9bf4 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -2427,9 +2427,7 @@ command-completion-with-modes-p
   "Say whether MODES are in action in BUFFER.
 This is the case if either the major mode is derived from one of MODES,
 or (if one of MODES is a minor mode), if it is switched on in BUFFER."
-  (or (apply #'provided-mode-derived-p
-             (buffer-local-value 'major-mode buffer)
-             modes)
+  (or (provided-mode-derived-p (buffer-local-value 'major-mode buffer) modes)
       ;; It's a minor mode.
       (seq-intersection modes
                         (buffer-local-value 'local-minor-modes buffer)
diff --git a/lisp/so-long.el b/lisp/so-long.el
index e5f7b81e717..d91002e873a 100644
--- a/lisp/so-long.el
+++ b/lisp/so-long.el
@@ -1716,7 +1716,7 @@ so-long--set-auto-mode
        (not so-long--inhibited)
        (not so-long--calling)
        (or (eq so-long-target-modes t)
-           (apply #'derived-mode-p so-long-target-modes))
+           (derived-mode-p so-long-target-modes))
        (setq so-long-detected-p (funcall so-long-predicate))
        ;; `so-long' should be called; but only if and when the buffer is
        ;; displayed in a window.  Long lines in invisible buffers are generally
diff --git a/lisp/transient.el b/lisp/transient.el
index 52c21871548..dd2b4e0db0b 100644
--- a/lisp/transient.el
+++ b/lisp/transient.el
@@ -1959,10 +1959,11 @@ transient--do-suffix-p
    (if-not-mode    (not (if (atom if-not-mode)
                             (eq major-mode if-not-mode)
                           (memq major-mode if-not-mode))))
-   (if-derived          (if (atom if-derived)
+   (if-derived          (if (or (atom if-derived) (>= emacs-major-version 30))
                             (derived-mode-p if-derived)
                           (apply #'derived-mode-p if-derived)))
-   (if-not-derived (not (if (atom if-not-derived)
+   (if-not-derived (not (if (or (atom if-not-derived)
+                                (>= emacs-major-version 30))
                             (derived-mode-p if-not-derived)
                           (apply #'derived-mode-p if-not-derived))))
    (t default)))
diff --git a/lisp/vc/vc.el b/lisp/vc/vc.el
index d768af678c3..1bd9ecb2193 100644
--- a/lisp/vc/vc.el
+++ b/lisp/vc/vc.el
@@ -1084,7 +1084,7 @@ vc-deduce-backend
 	((derived-mode-p 'log-edit-mode) log-edit-vc-backend)
 	((derived-mode-p 'diff-mode)     diff-vc-backend)
 	((or (null vc-deduce-backend-nonvc-modes)
-	     (apply #'derived-mode-p vc-deduce-backend-nonvc-modes))
+	     (derived-mode-p vc-deduce-backend-nonvc-modes))
 	 (ignore-errors (vc-responsible-backend default-directory)))
 	(vc-mode (vc-backend buffer-file-name))))
 
diff --git a/lisp/whitespace.el b/lisp/whitespace.el
index 86fc179396e..f4095c99089 100644
--- a/lisp/whitespace.el
+++ b/lisp/whitespace.el
@@ -1026,8 +1026,8 @@ whitespace-enable-predicate
           ((eq whitespace-global-modes t))
           ((listp whitespace-global-modes)
            (if (eq (car-safe whitespace-global-modes) 'not)
-               (not (apply #'derived-mode-p (cdr whitespace-global-modes)))
-             (apply #'derived-mode-p whitespace-global-modes)))
+               (not (derived-mode-p (cdr whitespace-global-modes)))
+             (derived-mode-p whitespace-global-modes)))
           (t nil))
          ;; ...we have a display (not running a batch job)
          (not noninteractive)
diff --git a/lisp/window.el b/lisp/window.el
index 06d5cfc0077..0c5ccf167dc 100644
--- a/lisp/window.el
+++ b/lisp/window.el
@@ -8054,10 +8054,8 @@ display-buffer-reuse-mode-window
       (dolist (window windows)
         (let ((mode?
                (with-current-buffer (window-buffer window)
-                 (cond ((memq major-mode allowed-modes)
-                        'same)
-                       ((apply #'derived-mode-p allowed-modes)
-                        'derived)))))
+                 (cond ((memq major-mode allowed-modes) 'same)
+                       ((derived-mode-p allowed-modes)  'derived)))))
           (when (and mode?
                      (not (and inhibit-same-window-p
                                (eq window curwin))))
-- 
2.42.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* bug#67034: 30.0.50; Make `derived-mode-p` take a single arg
  2023-11-10 12:18 ` Daniel Mendler
  2023-11-11  0:04   ` Dmitry Gutov
@ 2023-11-16 22:38   ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
  1 sibling, 0 replies; 9+ messages in thread
From: Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2023-11-16 22:38 UTC (permalink / raw)
  To: Daniel Mendler; +Cc: 67034

> This change would affect many packages. I grepped through my elpa
> directory and found multiple uses of derived-mode-p and
> provided-mode-derived-p with multiple arguments as shortcuts:
>
> (derived-mode-p 'mode1 'mode2) instead of (or (derived-mode-p 'mode1)
> (derived-mode-p 'mode2)

With the new convention the code would be

    (derived-mode-p '(mode1 mode2))

which seems just as good.

> There are also multiple call sites with apply, but these would be
> arguably nicer if derived-mode-p takes a list argument as proposed.

Exactly.

> Still, do the benefits of this change outweigh the required changes?

I think they do, especially since we preserve backward compatibility, so
the change can be done progressively.

> I wonder if this extra allocation of &rest makes any difference in any
> benchmark, though.

I hope not, tho I've seen several situations where the cost of
apply+&rest dominates execution time (mostly because of the time
spent in the GC collecting the allocated cons cells), so it's within the
realm of possible.

Note that the recent introduction of `derived-mode-all-parents` should
already have made `derived-mode-p` faster (tho it wasn't the purpose).


        Stefan






^ permalink raw reply	[flat|nested] 9+ messages in thread

* bug#67034: 30.0.50; Make `derived-mode-p` take a single arg
  2023-11-16 22:28 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2023-11-17  8:24   ` Eli Zaretskii
  2023-11-17 21:18     ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
  0 siblings, 1 reply; 9+ messages in thread
From: Eli Zaretskii @ 2023-11-17  8:24 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: 67034

> Date: Thu, 16 Nov 2023 17:28:24 -0500
> From:  Stefan Monnier via "Bug reports for GNU Emacs,
>  the Swiss army knife of text editors" <bug-gnu-emacs@gnu.org>
> 
> -@defun derived-mode-p &rest modes
> +@defun derived-mode-p modes
>  This function returns non-@code{nil} if the current major mode is
>  derived from any of the major modes given by the symbols @var{modes}.
> +Instead of a list, @var{modes} can also be a single symbol.

If MODES is supposed to be a list, then why does the first sentence
say "given by the symbols MODES"?  It should probably say "given by
the list of symbols in MODES" instead, right?

And the last sentence would be a tad less confusing if it said

  Instead of a list, @var{modes} can also be a single mode symbol.

> -(defun provided-mode-derived-p (mode &rest modes)
> +(defun provided-mode-derived-p (mode &optional modes &rest old-modes)
>    "Non-nil if MODE is derived from one of MODES.

This should IMO say

  Non-nil if MODE is derived from a mode that is a member of the list MODES.

> +(defun derived-mode-p (&optional modes &rest old-modes)
> + "Non-nil if the current major mode is derived from one of MODES.

Likewise here.

Thanks.





^ permalink raw reply	[flat|nested] 9+ messages in thread

* bug#67034: 30.0.50; Make `derived-mode-p` take a single arg
  2023-11-17  8:24   ` Eli Zaretskii
@ 2023-11-17 21:18     ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2023-11-23 17:00       ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
  0 siblings, 1 reply; 9+ messages in thread
From: Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2023-11-17 21:18 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: 67034

[-- Attachment #1: Type: text/plain, Size: 1411 bytes --]

>> -@defun derived-mode-p &rest modes
>> +@defun derived-mode-p modes
>>  This function returns non-@code{nil} if the current major mode is
>>  derived from any of the major modes given by the symbols @var{modes}.
>> +Instead of a list, @var{modes} can also be a single symbol.
>
> If MODES is supposed to be a list, then why does the first sentence
> say "given by the symbols MODES"?

Oh, right, in the current text, the `&rest modes` makes it clear that
`modes` is a list, whereas with my change we need to spell it out
more clearly.

> And the last sentence would be a tad less confusing if it said
>
>   Instead of a list, @var{modes} can also be a single mode symbol.

Done.

>> -(defun provided-mode-derived-p (mode &rest modes)
>> +(defun provided-mode-derived-p (mode &optional modes &rest old-modes)
>>    "Non-nil if MODE is derived from one of MODES.
>
> This should IMO say
>
>   Non-nil if MODE is derived from a mode that is a member of the list MODES.

Changed (tho it now goes over the 72 columns 🙁).

>> +(defun derived-mode-p (&optional modes &rest old-modes)
>> + "Non-nil if the current major mode is derived from one of MODES.
> Likewise here.

I'm having trouble making this change fit into the 80 columns limit, so
I left this first line unchanged and reworked the second line to clarify
that MODES should be a list of symbols.


        Stefan

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-derived-mode-p-Take-MODES-as-a-single-argument.patch --]
[-- Type: text/x-diff, Size: 3865 bytes --]

From f51c65125176a271c9b1f57d67456bede1bc8e80 Mon Sep 17 00:00:00 2001
From: Stefan Monnier <monnier@iro.umontreal.ca>
Date: Thu, 16 Nov 2023 17:21:18 -0500
Subject: [PATCH 1/2] (derived-mode-p): Take MODES as a single argument

Looking at uses of `derived-mode-p` and `provide-mode-derived-p`,
I can't find a single use case where it wouldn't be preferable for
it to take a single argument instead of `&rest`: all the calls are
either passing a single argument anyway, or passing a fixed list of modes.
The use of `&rest` just makes the code less efficient and sometimes
more clunky (because of the need for `apply`).
So let's change that (while preserving backward compatibility, of course).

* doc/lispref/modes.texi (Derived Modes): Adjust accordingly.

* lisp/subr.el (provided-mode-derived-p, derived-mode-p): Take the
`modes` as a single argument.
---
 doc/lispref/modes.texi |  9 +++++++--
 lisp/subr.el           | 28 ++++++++++++++++++++--------
 2 files changed, 27 insertions(+), 10 deletions(-)

diff --git a/doc/lispref/modes.texi b/doc/lispref/modes.texi
index 130bc10cd59..a0fc3463a06 100644
--- a/doc/lispref/modes.texi
+++ b/doc/lispref/modes.texi
@@ -932,9 +932,14 @@ Derived Modes
 @code{define-derived-mode} does that automatically.
 @end defmac
 
-@defun derived-mode-p &rest modes
+@defun derived-mode-p modes
 This function returns non-@code{nil} if the current major mode is
-derived from any of the major modes given by the symbols @var{modes}.
+derived from any of the major modes given by the list of symbols
+in @var{modes}.
+Instead of a list, @var{modes} can also be a single mode symbol.
+
+Furthermore, we still support a deprecated calling convention where the
+@var{modes} were passed as separate arguments.
 @end defun
 
 The graph of major modes is accessed with the following lower-level
diff --git a/lisp/subr.el b/lisp/subr.el
index dcf49509177..304b71e6168 100644
--- a/lisp/subr.el
+++ b/lisp/subr.el
@@ -2782,19 +2782,31 @@ derived-mode-all-parents
             (cons mode (remq mode all-parents))
           (put mode 'derived-mode--all-parents (cons mode all-parents))))))))
 
-(defun provided-mode-derived-p (mode &rest modes)
-  "Non-nil if MODE is derived from one of MODES.
-If you just want to check `major-mode', use `derived-mode-p'."
-  (declare (side-effect-free t))
+(defun provided-mode-derived-p (mode &optional modes &rest old-modes)
+  "Non-nil if MODE is derived from a mode that is a member of the list MODES.
+MODES can also be a single mode instead of a list.
+If you just want to check `major-mode', use `derived-mode-p'.
+We also still support the deprecated calling convention:
+\(provided-mode-derived-p MODE &rest MODES)."
+  (declare (side-effect-free t)
+           (advertised-calling-convention (mode modes) "30.1"))
+  (cond
+   (old-modes (setq modes (cons modes old-modes)))
+   ((not (listp modes)) (setq modes (list modes))))
   (let ((ps (derived-mode-all-parents mode)))
     (while (and modes (not (memq (car modes) ps)))
       (setq modes (cdr modes)))
     (car modes)))
 
-(defun derived-mode-p (&rest modes)
-  "Non-nil if the current major mode is derived from one of MODES."
-  (declare (side-effect-free t))
-  (apply #'provided-mode-derived-p major-mode modes))
+(defun derived-mode-p (&optional modes &rest old-modes)
+ "Non-nil if the current major mode is derived from one of MODES.
+MODES should be a list of symbols or a single mode symbol instead of a list.
+We also still support the deprecated calling convention:
+\(derived-mode-p &rest MODES)."
+ (declare (side-effect-free t)
+          (advertised-calling-convention (modes) "30.1"))
+ (provided-mode-derived-p major-mode (if old-modes (cons modes old-modes)
+                                       modes)))
 
 (defun derived-mode-set-parent (mode parent)
   "Declare PARENT to be the parent of MODE."
-- 
2.42.0


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: 0002-Adjust-affected-callers-of-derived-mode-p-to-use-the.patch --]
[-- Type: text/x-diff, Size: 17363 bytes --]

From 1cb5471be64cea47738a4cbe30eda8d32f6bd3b6 Mon Sep 17 00:00:00 2001
From: Stefan Monnier <monnier@iro.umontreal.ca>
Date: Mon, 13 Nov 2023 19:09:17 -0500
Subject: [PATCH 2/2] Adjust affected callers of derived-mode-p` to use the new
 convention

* lisp/align.el (align-rules-list): Prefer `derived-mode-p` over
`provided-mode-derived-p`.
(align--rule-should-run):
* lisp/window.el (display-buffer-reuse-mode-window):
* lisp/whitespace.el (whitespace-enable-predicate):
* lisp/transient.el (transient--do-suffix-p):
* lisp/so-long.el (so-long--set-auto-mode):
* lisp/simple.el (command-completion-with-modes-p):
* lisp/progmodes/tcl.el (tcl-current-word):
* lisp/progmodes/idlwave.el (idlwave-fix-keywords):
* lisp/progmodes/gdb-mi.el (gdb, gdb-locals-mode-map)
(gdb-registers-mode-map, gdb-function-buffer-p):
* lisp/progmodes/c-ts-mode.el (c-ts-mode--indent-style-setter)
(c-ts-mode-set-style):
* lisp/progmodes/bug-reference.el (bug-reference--try-setup-gnus-article):
* lisp/help-fns.el (help-fns--list-local-commands):
* lisp/emulation/viper.el (viper-mode)
(viper-this-major-mode-requires-vi-state):
* lisp/emacs-lisp/easy-mmode.el (easy-mmode--globalized-predicate-p):
* lisp/dired.el (dired-hide-details-mode, dired-click-to-select-mode):
* lisp/calendar/todo-mode.el (todo-reset-nondiary-marker)
(todo-reset-done-string, todo-reset-comment-string):
* lisp/vc/vc.el (vc-deduce-backend): Use new calling convention for
`derived-mode-p` and `provided-mode-derived-p`.
---
 lisp/align.el                   |  5 ++---
 lisp/calendar/todo-mode.el      |  6 +++---
 lisp/dired.el                   |  4 ++--
 lisp/emacs-lisp/easy-mmode.el   |  2 +-
 lisp/emulation/viper.el         | 10 +++++-----
 lisp/help-fns.el                |  2 +-
 lisp/progmodes/bug-reference.el |  8 ++++----
 lisp/progmodes/c-ts-mode.el     |  4 ++--
 lisp/progmodes/gdb-mi.el        | 15 +++++++++------
 lisp/progmodes/idlwave.el       |  4 ++--
 lisp/progmodes/tcl.el           |  4 ++--
 lisp/simple.el                  |  4 +---
 lisp/so-long.el                 |  2 +-
 lisp/transient.el               |  5 +++--
 lisp/vc/vc.el                   |  2 +-
 lisp/whitespace.el              |  4 ++--
 lisp/window.el                  |  6 ++----
 17 files changed, 43 insertions(+), 44 deletions(-)

diff --git a/lisp/align.el b/lisp/align.el
index 9fa78525ecb..4daa20ddd2a 100644
--- a/lisp/align.el
+++ b/lisp/align.el
@@ -555,8 +555,7 @@ align-rules-list
      (repeat   . t)
      (run-if   . ,(lambda ()
                     (and (not (eq '- current-prefix-arg))
-                         (not (apply #'provided-mode-derived-p
-                                     major-mode align-tex-modes))))))
+                         (not (derived-mode-p align-tex-modes))))))
 
     ;; With a negative prefix argument, lists of dollar figures will
     ;; be aligned.
@@ -1286,7 +1285,7 @@ align--rule-should-run
 This is decided by the `modes' and `run-if' keys in the alist
 RULE.  Their meaning is documented in `align-rules-list' (which see)."
   (let-alist rule
-    (not (or (and .modes (not (apply #'derived-mode-p (eval .modes))))
+    (not (or (and .modes (not (derived-mode-p (eval .modes))))
              (and .run-if (not (funcall .run-if)))))))
 
 (defun align-region (beg end separate rules exclude-rules
diff --git a/lisp/calendar/todo-mode.el b/lisp/calendar/todo-mode.el
index 4f6a964eb4d..ab9d629d9fc 100644
--- a/lisp/calendar/todo-mode.el
+++ b/lisp/calendar/todo-mode.el
@@ -6350,7 +6350,7 @@ todo-reset-nondiary-marker
 		      (replace-match (nth 1 value) t t nil 2))
 		  (forward-line)))
 	      (if buf
-		  (when (derived-mode-p 'todo-mode 'todo-archive-mode)
+		  (when (derived-mode-p '(todo-mode todo-archive-mode))
 		    (todo-category-select))
 		(save-buffer)
 		(kill-buffer)))))))))
@@ -6394,7 +6394,7 @@ todo-reset-done-string
 		    (replace-match value t t nil 1)
 		  (forward-line)))
 	      (if buf
-		  (when (derived-mode-p 'todo-mode 'todo-archive-mode)
+		  (when (derived-mode-p '(todo-mode todo-archive-mode))
 		    (todo-category-select))
 		(save-buffer)
 		(kill-buffer)))))))))
@@ -6420,7 +6420,7 @@ todo-reset-comment-string
 		    (replace-match value t t nil 1)
 		  (forward-line)))
 	      (if buf
-		  (when (derived-mode-p 'todo-mode 'todo-archive-mode)
+		  (when (derived-mode-p '(todo-mode todo-archive-mode))
 		    (todo-category-select))
 		(save-buffer)
 		(kill-buffer)))))))))
diff --git a/lisp/dired.el b/lisp/dired.el
index 8919d2c223f..3f488afaa3c 100644
--- a/lisp/dired.el
+++ b/lisp/dired.el
@@ -3074,7 +3074,7 @@ dired-hide-details-mode
 See options: `dired-hide-details-hide-symlink-targets' and
 `dired-hide-details-hide-information-lines'."
   :group 'dired
-  (unless (derived-mode-p 'dired-mode 'wdired-mode)
+  (unless (derived-mode-p '(dired-mode wdired-mode))
     (error "Not a Dired buffer"))
   (dired-hide-details-update-invisibility-spec)
   (if dired-hide-details-mode
@@ -5096,7 +5096,7 @@ dired-click-to-select-mode
 completes."
   :group 'dired
   :lighter " Click-To-Select"
-  (unless (derived-mode-p 'dired-mode 'wdired-mode)
+  (unless (derived-mode-p '(dired-mode wdired-mode))
     (error "Not a Dired buffer"))
   (if dired-click-to-select-mode
       (setq-local tool-bar-map
diff --git a/lisp/emacs-lisp/easy-mmode.el b/lisp/emacs-lisp/easy-mmode.el
index 529f6e90e88..c9e7b3a4dfe 100644
--- a/lisp/emacs-lisp/easy-mmode.el
+++ b/lisp/emacs-lisp/easy-mmode.el
@@ -661,7 +661,7 @@ easy-mmode--globalized-predicate-p
           (throw 'found nil))
          ((and (consp elem)
                (eq (car elem) 'not))
-          (when (apply #'derived-mode-p (cdr elem))
+          (when (derived-mode-p (cdr elem))
             (throw 'found nil)))
          ((symbolp elem)
           (when (derived-mode-p elem)
diff --git a/lisp/emulation/viper.el b/lisp/emulation/viper.el
index 96da914275b..767ad57c471 100644
--- a/lisp/emulation/viper.el
+++ b/lisp/emulation/viper.el
@@ -593,8 +593,8 @@ viper-mode
 		    ))
 	      (viper-set-expert-level 'dont-change-unless)))
 
-	(or (apply #'derived-mode-p viper-emacs-state-mode-list) ; don't switch to Vi
-	    (apply #'derived-mode-p viper-insert-state-mode-list) ; don't switch
+	(or (derived-mode-p viper-emacs-state-mode-list) ; don't switch to Vi
+	    (derived-mode-p viper-insert-state-mode-list) ; don't switch
 	    (viper-change-state-to-vi))
 	))
 
@@ -607,9 +607,9 @@ viper-mode
 ;; that are not listed in viper-vi-state-mode-list
 (defun viper-this-major-mode-requires-vi-state (mode)
   (let ((major-mode mode))
-    (cond ((apply #'derived-mode-p viper-vi-state-mode-list) t)
-          ((apply #'derived-mode-p viper-emacs-state-mode-list) nil)
-          ((apply #'derived-mode-p viper-insert-state-mode-list) nil)
+    (cond ((derived-mode-p viper-vi-state-mode-list) t)
+          ((derived-mode-p viper-emacs-state-mode-list) nil)
+          ((derived-mode-p viper-insert-state-mode-list) nil)
           (t (and (eq (key-binding "a") 'self-insert-command)
                   (eq (key-binding " ") 'self-insert-command))))))
 
diff --git a/lisp/help-fns.el b/lisp/help-fns.el
index e723d97cfc2..a8c60946121 100644
--- a/lisp/help-fns.el
+++ b/lisp/help-fns.el
@@ -2240,7 +2240,7 @@ help-fns--list-local-commands
                   (not (get sym 'byte-obsolete-info))
                   ;; Ignore everything bound.
                   (not (where-is-internal sym nil t))
-                  (apply #'derived-mode-p (command-modes sym)))
+                  (derived-mode-p (command-modes sym)))
          (push sym functions))))
     (with-temp-buffer
       (when functions
diff --git a/lisp/progmodes/bug-reference.el b/lisp/progmodes/bug-reference.el
index 3f6e1e68e5b..0afed5276f5 100644
--- a/lisp/progmodes/bug-reference.el
+++ b/lisp/progmodes/bug-reference.el
@@ -467,10 +467,10 @@ bug-reference-mode
 (defun bug-reference--try-setup-gnus-article ()
   (when (and bug-reference-mode ;; Only if enabled in article buffers.
              (derived-mode-p
-              'gnus-article-mode
-              ;; Apparently, gnus-article-prepare-hook is run in the
-              ;; summary buffer...
-              'gnus-summary-mode)
+              '(gnus-article-mode
+                ;; Apparently, `gnus-article-prepare-hook' is run in the
+                ;; summary buffer...
+                gnus-summary-mode))
              gnus-article-buffer
              gnus-original-article-buffer
              (buffer-live-p (get-buffer gnus-article-buffer))
diff --git a/lisp/progmodes/c-ts-mode.el b/lisp/progmodes/c-ts-mode.el
index 70717a90caa..a56ce26fc79 100644
--- a/lisp/progmodes/c-ts-mode.el
+++ b/lisp/progmodes/c-ts-mode.el
@@ -135,7 +135,7 @@ c-ts-mode--indent-style-setter
               res)
       (let ((buffer (car buffers)))
         (with-current-buffer buffer
-          (if (derived-mode-p 'c-ts-mode 'c++-ts-mode)
+          (if (derived-mode-p '(c-ts-mode c++-ts-mode))
               (loop (append res (list buffer)) (cdr buffers))
             (loop res (cdr buffers))))))))
 
@@ -193,7 +193,7 @@ c-ts-mode-set-style
 To set the default indent style globally, use
 `c-ts-mode-set-global-style'."
   (interactive (list (c-ts-mode--prompt-for-style)))
-  (if (not (derived-mode-p 'c-ts-mode 'c++-ts-mode))
+  (if (not (derived-mode-p '(c-ts-mode c++-ts-mode)))
       (user-error "The current buffer is not in `c-ts-mode' nor `c++-ts-mode'")
     (setq-local c-ts-mode-indent-style style)
     (setq treesit-simple-indent-rules
diff --git a/lisp/progmodes/gdb-mi.el b/lisp/progmodes/gdb-mi.el
index 3afdc59a67e..7ae4bcea1e1 100644
--- a/lisp/progmodes/gdb-mi.el
+++ b/lisp/progmodes/gdb-mi.el
@@ -1006,9 +1006,10 @@ gdb
   (gud-def gud-pp
 	   (gud-call
 	    (concat
-	     "pp " (if (eq (buffer-local-value
-			    'major-mode (window-buffer)) 'speedbar-mode)
-		       (gdb-find-watch-expression) "%e")) arg)
+	     "pp " (if (eq (buffer-local-value 'major-mode (window-buffer))
+			   'speedbar-mode)
+		       (gdb-find-watch-expression) "%e"))
+	    arg)
 	   nil   "Print the Emacs s-expression.")
 
   (define-key gud-minor-mode-map [left-margin mouse-1]
@@ -4586,7 +4587,8 @@ gdb-locals-mode-map
                            (gdb-set-window-buffer
                             (gdb-get-buffer-create
                              'gdb-registers-buffer
-                             gdb-thread-number) t)))
+                             gdb-thread-number)
+                            t)))
     map))
 
 (define-derived-mode gdb-locals-mode gdb-parent-mode "Locals"
@@ -4706,7 +4708,8 @@ gdb-registers-mode-map
                            (gdb-set-window-buffer
                             (gdb-get-buffer-create
                              'gdb-locals-buffer
-                             gdb-thread-number) t)))
+                             gdb-thread-number)
+                            t)))
     (define-key map "f" #'gdb-registers-toggle-filter)
     map))
 
@@ -5106,7 +5109,7 @@ gdb-function-buffer-p
 not including main command buffer (the one where you type GDB
 commands) or source buffers (that display program source code)."
   (with-current-buffer buffer
-    (derived-mode-p 'gdb-parent-mode 'gdb-inferior-io-mode)))
+    (derived-mode-p '(gdb-parent-mode gdb-inferior-io-mode))))
 
 (defun gdb--buffer-type (buffer)
   "Return the type of BUFFER if it is a function buffer.
diff --git a/lisp/progmodes/idlwave.el b/lisp/progmodes/idlwave.el
index d9eccacc48b..f60cc9372eb 100644
--- a/lisp/progmodes/idlwave.el
+++ b/lisp/progmodes/idlwave.el
@@ -6892,7 +6892,7 @@ idlwave-one-key-select
     ;; Display prompt and wait for quick reply
     (message "%s[%s]" prompt
              (mapconcat (lambda(x) (char-to-string (car x)))
-                        keys-alist ""))
+                        keys-alist))
     (if (sit-for delay)
         ;; No quick reply: Show help
         (save-window-excursion
@@ -7958,7 +7958,7 @@ idlwave-fix-keywords
     ;; If this is the OBJ_NEW function, try to figure out the class and use
     ;; the keywords from the corresponding INIT method.
     (if (and (equal (upcase name) "OBJ_NEW")
-	     (derived-mode-p 'idlwave-mode 'idlwave-shell-mode))
+	     (derived-mode-p '(idlwave-mode idlwave-shell-mode)))
 	(let* ((bos (save-excursion (idlwave-beginning-of-statement) (point)))
 	       (string (buffer-substring bos (point)))
 	       (case-fold-search t)
diff --git a/lisp/progmodes/tcl.el b/lisp/progmodes/tcl.el
index ba0cbc8b066..b983c671cd9 100644
--- a/lisp/progmodes/tcl.el
+++ b/lisp/progmodes/tcl.el
@@ -1340,7 +1340,7 @@ tcl-current-word
 If FLAG is nil, just uses `current-word'.
 Otherwise scans backward for most likely Tcl command word."
   (if (and flag
-	   (derived-mode-p 'tcl-mode 'inferior-tcl-mode))
+	   (derived-mode-p '(tcl-mode inferior-tcl-mode)))
       (condition-case nil
 	  (save-excursion
 	    ;; Look backward for first word actually in alist.
@@ -1575,7 +1575,7 @@ tcl-quote
 	       (if (memq char '(?\[ ?\] ?{ ?} ?\\ ?\" ?$ ?\s ?\;))
 		   (concat "\\" (char-to-string char))
 		 (char-to-string char)))
-	     string ""))
+	     string))
 
 \f
 
diff --git a/lisp/simple.el b/lisp/simple.el
index de6eed3fe8f..2e2d73e9bf4 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -2427,9 +2427,7 @@ command-completion-with-modes-p
   "Say whether MODES are in action in BUFFER.
 This is the case if either the major mode is derived from one of MODES,
 or (if one of MODES is a minor mode), if it is switched on in BUFFER."
-  (or (apply #'provided-mode-derived-p
-             (buffer-local-value 'major-mode buffer)
-             modes)
+  (or (provided-mode-derived-p (buffer-local-value 'major-mode buffer) modes)
       ;; It's a minor mode.
       (seq-intersection modes
                         (buffer-local-value 'local-minor-modes buffer)
diff --git a/lisp/so-long.el b/lisp/so-long.el
index e5f7b81e717..d91002e873a 100644
--- a/lisp/so-long.el
+++ b/lisp/so-long.el
@@ -1716,7 +1716,7 @@ so-long--set-auto-mode
        (not so-long--inhibited)
        (not so-long--calling)
        (or (eq so-long-target-modes t)
-           (apply #'derived-mode-p so-long-target-modes))
+           (derived-mode-p so-long-target-modes))
        (setq so-long-detected-p (funcall so-long-predicate))
        ;; `so-long' should be called; but only if and when the buffer is
        ;; displayed in a window.  Long lines in invisible buffers are generally
diff --git a/lisp/transient.el b/lisp/transient.el
index 52c21871548..dd2b4e0db0b 100644
--- a/lisp/transient.el
+++ b/lisp/transient.el
@@ -1959,10 +1959,11 @@ transient--do-suffix-p
    (if-not-mode    (not (if (atom if-not-mode)
                             (eq major-mode if-not-mode)
                           (memq major-mode if-not-mode))))
-   (if-derived          (if (atom if-derived)
+   (if-derived          (if (or (atom if-derived) (>= emacs-major-version 30))
                             (derived-mode-p if-derived)
                           (apply #'derived-mode-p if-derived)))
-   (if-not-derived (not (if (atom if-not-derived)
+   (if-not-derived (not (if (or (atom if-not-derived)
+                                (>= emacs-major-version 30))
                             (derived-mode-p if-not-derived)
                           (apply #'derived-mode-p if-not-derived))))
    (t default)))
diff --git a/lisp/vc/vc.el b/lisp/vc/vc.el
index d768af678c3..1bd9ecb2193 100644
--- a/lisp/vc/vc.el
+++ b/lisp/vc/vc.el
@@ -1084,7 +1084,7 @@ vc-deduce-backend
 	((derived-mode-p 'log-edit-mode) log-edit-vc-backend)
 	((derived-mode-p 'diff-mode)     diff-vc-backend)
 	((or (null vc-deduce-backend-nonvc-modes)
-	     (apply #'derived-mode-p vc-deduce-backend-nonvc-modes))
+	     (derived-mode-p vc-deduce-backend-nonvc-modes))
 	 (ignore-errors (vc-responsible-backend default-directory)))
 	(vc-mode (vc-backend buffer-file-name))))
 
diff --git a/lisp/whitespace.el b/lisp/whitespace.el
index 86fc179396e..f4095c99089 100644
--- a/lisp/whitespace.el
+++ b/lisp/whitespace.el
@@ -1026,8 +1026,8 @@ whitespace-enable-predicate
           ((eq whitespace-global-modes t))
           ((listp whitespace-global-modes)
            (if (eq (car-safe whitespace-global-modes) 'not)
-               (not (apply #'derived-mode-p (cdr whitespace-global-modes)))
-             (apply #'derived-mode-p whitespace-global-modes)))
+               (not (derived-mode-p (cdr whitespace-global-modes)))
+             (derived-mode-p whitespace-global-modes)))
           (t nil))
          ;; ...we have a display (not running a batch job)
          (not noninteractive)
diff --git a/lisp/window.el b/lisp/window.el
index 06d5cfc0077..0c5ccf167dc 100644
--- a/lisp/window.el
+++ b/lisp/window.el
@@ -8054,10 +8054,8 @@ display-buffer-reuse-mode-window
       (dolist (window windows)
         (let ((mode?
                (with-current-buffer (window-buffer window)
-                 (cond ((memq major-mode allowed-modes)
-                        'same)
-                       ((apply #'derived-mode-p allowed-modes)
-                        'derived)))))
+                 (cond ((memq major-mode allowed-modes) 'same)
+                       ((derived-mode-p allowed-modes)  'derived)))))
           (when (and mode?
                      (not (and inhibit-same-window-p
                                (eq window curwin))))
-- 
2.42.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* bug#67034: 30.0.50; Make `derived-mode-p` take a single arg
  2023-11-17 21:18     ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2023-11-23 17:00       ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
  0 siblings, 0 replies; 9+ messages in thread
From: Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2023-11-23 17:00 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: 67034-done

Pushed, thanks,


        Stefan






^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2023-11-23 17:00 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-11-10  3:58 bug#67034: 30.0.50; Make `derived-mode-p` take a single arg Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-11-10 12:18 ` Daniel Mendler
2023-11-11  0:04   ` Dmitry Gutov
2023-11-11  9:08     ` Daniel Mendler
2023-11-16 22:38   ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-11-16 22:28 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-11-17  8:24   ` Eli Zaretskii
2023-11-17 21:18     ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-11-23 17:00       ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).