diff --git a/doc/lispref/modes.texi b/doc/lispref/modes.texi index 8670807cbdf..13090a13d71 100644 --- a/doc/lispref/modes.texi +++ b/doc/lispref/modes.texi @@ -932,9 +932,14 @@ Do not write an @code{interactive} spec in the definition; @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/etc/NEWS b/etc/NEWS index 8794239c148..c0f76ed052b 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1228,8 +1228,15 @@ values. Mostly used internally to do a kind of topological sort of inheritance hierarchies. -** New API to control the graph of major modes. -While 'define-derived-mode' still only support single inheritance, +** New API for 'derived-mode-p' and control of the graph of major modes. + +*** 'derived-mode-p' now takes the list of modes as a single argument. +The same holds for `provided-mode-derived-p`. +The old calling convention where multiple modes are passed as +separate arguments is deprecated. + +*** New functions to access the graph of major modes. +While 'define-derived-mode' still only supports single inheritance, modes can declare additional parents (for tests like 'derived-mode-p') with `derived-mode-add-parents`. Accessing the 'derived-mode-parent' property directly is now 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 @@ The returned list is not fresh, don't modify it. (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."