Function: derived-mode-all-parents
derived-mode-all-parents is a byte-compiled function defined in
subr.el.gz.
Signature
(derived-mode-all-parents MODE)
Documentation
Return all the parents of MODE, starting with MODE.
This includes the parents set by define-derived-mode and additional
ones set by derived-mode-add-parents.
The returned list is not fresh, don't modify it.
Probably introduced at or before Emacs version 30.1.
Aliases
mode-local-equivalent-mode-p (obsolete since 30.1)
Source Code
;; Defined in /usr/src/emacs/lisp/subr.el.gz
(defun derived-mode-all-parents (mode &optional known-children)
"Return all the parents of MODE, starting with MODE.
This includes the parents set by `define-derived-mode' and additional
ones set by `derived-mode-add-parents'.
The returned list is not fresh, don't modify it.
\n(fn MODE)" ;`known-children' is for internal use only.
;; Can't use `with-memoization' :-(
(let ((ps (get mode 'derived-mode--all-parents)))
(cond
(ps ps)
((memq mode known-children)
;; These things happen, better not get all worked up about it.
;;(error "Cycle in the major mode hierarchy: %S" mode)
;; But do try to return something meaningful.
(memq mode (reverse known-children)))
(t
;; The mode hierarchy (or DAG, actually), is very static, but we
;; need to react to changes because `parent' may not be defined
;; yet (e.g. it's still just an autoload), so the recursive call
;; to `derived-mode-all-parents' may return an
;; invalid/incomplete result which we'll need to update when the
;; mode actually gets loaded.
(let* ((new-children (cons mode known-children))
(get-all-parents
(lambda (parent)
;; Can't use `cl-lib' here (nor `gv') :-(
;;(cl-assert (not (equal parent mode)))
;;(cl-pushnew mode (get parent 'derived-mode--followers))
(let ((followers (get parent 'derived-mode--followers)))
(unless (memq mode followers)
(put parent 'derived-mode--followers
(cons mode followers))))
(derived-mode-all-parents parent new-children)))
(parent (or (get mode 'derived-mode-parent)
;; If MODE is an alias, then follow the alias.
(let ((alias (symbol-function mode)))
(and (symbolp alias) alias))))
(extras (get mode 'derived-mode-extra-parents))
(all-parents
(merge-ordered-lists
(cons (if (and parent (not (memq parent extras)))
(funcall get-all-parents parent))
(mapcar get-all-parents extras)))))
;; Cache the result unless it was affected by `known-children'
;; because of a cycle.
(if (and (memq mode all-parents) known-children)
(cons mode (remq mode all-parents))
(put mode 'derived-mode--all-parents (cons mode all-parents))))))))