"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'."
- ;; If MODE is an alias, then look up the real mode function first.
(declare (side-effect-free t))
- (when-let ((alias (symbol-function mode)))
- (when (symbolp alias)
- (setq mode alias)))
(while
(and
(not (memq mode modes))
- (let* ((parent (get mode 'derived-mode-parent))
- (parentfn (symbol-function parent)))
- (setq mode (if (and parentfn (symbolp parentfn)) parentfn parent)))))
+ (let* ((parent (get mode 'derived-mode-parent)))
+ (setq mode (or parent
+ ;; If MODE is an alias, then follow the alias.
+ (let ((alias (symbol-function mode)))
+ (and (symbolp alias) alias)))))))
mode)
(defun derived-mode-p (&rest modes)
(defalias 'subr-tests--parent-mode
(if (fboundp 'prog-mode) 'prog-mode 'fundamental-mode))
+(define-derived-mode subr-tests--derived-mode-1 prog-mode "test")
+(define-derived-mode subr-tests--derived-mode-2 subr-tests--parent-mode "test")
(ert-deftest provided-mode-derived-p ()
;; base case: `derived-mode' directly derives `prog-mode'
- (should (progn
- (define-derived-mode derived-mode prog-mode "test")
- (provided-mode-derived-p 'derived-mode 'prog-mode)))
- ;; edge case: `derived-mode' derives an alias of `prog-mode'
- (should (progn
- (define-derived-mode derived-mode subr-tests--parent-mode "test")
- (provided-mode-derived-p 'derived-mode 'prog-mode))))
+ (should (provided-mode-derived-p 'subr-tests--derived-mode-1 'prog-mode))
+ ;; Edge cases: aliases along the derivation.
+ (should (provided-mode-derived-p 'subr-tests--parent-mode
+ 'subr-tests--parent-mode))
+ (should (provided-mode-derived-p 'subr-tests--derived-mode-2
+ 'subr-tests--parent-mode))
+ (should (provided-mode-derived-p 'subr-tests--derived-mode-2 'prog-mode)))
(ert-deftest number-sequence-test ()
(should (= (length