Subject: Re: bug#67034: 30.0.50; Make `derived-mode-p` take a single arg

From: Stefan Monnier <[email-masked]>
Date: Fri, 17 Nov 2023 16:18:39 -0500

>> -@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
>From f51c65125176a271c9b1f57d67456bede1bc8e80 Mon Sep 17 00:00:00 2001
From: Stefan Monnier <[email-masked]>
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

>From 1cb5471be64cea47738a4cbe30eda8d32f6bd3b6 Mon Sep 17 00:00:00 2001
From: Stefan Monnier <[email-masked]>
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))
 
 
 
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