aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Monnier2023-11-08 11:32:27 -0500
committerStefan Monnier2023-11-08 22:42:16 -0500
commit19445b6b7bb04e44e39ef2e39a620bd3eadb0acd (patch)
treebd8b0f0a0a31556c11fd717264b5c0f89f6a3da5
parent21f36705266934d5a351d4d7f360734540132139 (diff)
downloademacs-19445b6b7bb04e44e39ef2e39a620bd3eadb0acd.tar.gz
emacs-19445b6b7bb04e44e39ef2e39a620bd3eadb0acd.zip
subr.el: Provide a functional API around `derived-mode-parent`
The `derived-mode-parent` property should be an implementation detail, so we can change it more easily. To that end, add functions to set and query it. * lisp/subr.el (derived-mode-all-parents): New function. (provided-mode-derived-p): Use it. (derived-mode-set-parent): New function.
-rw-r--r--lisp/subr.el31
1 files changed, 21 insertions, 10 deletions
diff --git a/lisp/subr.el b/lisp/subr.el
index d4173b4daba..6a4c1abfb62 100644
--- a/lisp/subr.el
+++ b/lisp/subr.el
@@ -2678,20 +2678,27 @@ The variable list SPEC is the same as in `if-let*'."
2678 2678
2679;; PUBLIC: find if the current mode derives from another. 2679;; PUBLIC: find if the current mode derives from another.
2680 2680
2681(defun derived-mode-all-parents (mode &optional known-children)
2682 "Return all the parents of MODE, starting with MODE.
2683The returned list is not fresh, don't modify it.
2684\n(fn MODE)" ;`known-children' is for internal use only.
2685 (if (memq mode known-children)
2686 (error "Cycle in the major mode hierarchy: %S" mode)
2687 (push mode known-children))
2688 (let* ((parent (or (get mode 'derived-mode-parent)
2689 ;; If MODE is an alias, then follow the alias.
2690 (let ((alias (symbol-function mode)))
2691 (and (symbolp alias) alias)))))
2692 (cons mode (if parent (derived-mode-all-parents parent known-children)))))
2693
2681(defun provided-mode-derived-p (mode &rest modes) 2694(defun provided-mode-derived-p (mode &rest modes)
2682 "Non-nil if MODE is derived from one of MODES. 2695 "Non-nil if MODE is derived from one of MODES.
2683Uses the `derived-mode-parent' property of the symbol to trace backwards.
2684If you just want to check `major-mode', use `derived-mode-p'." 2696If you just want to check `major-mode', use `derived-mode-p'."
2685 (declare (side-effect-free t)) 2697 (declare (side-effect-free t))
2686 (while 2698 (let ((ps (derived-mode-all-parents mode)))
2687 (and 2699 (while (and ps (not (memq (car ps) modes)))
2688 (not (memq mode modes)) 2700 (setq ps (cdr ps)))
2689 (let* ((parent (get mode 'derived-mode-parent))) 2701 (car ps)))
2690 (setq mode (or parent
2691 ;; If MODE is an alias, then follow the alias.
2692 (let ((alias (symbol-function mode)))
2693 (and (symbolp alias) alias)))))))
2694 mode)
2695 2702
2696(defun derived-mode-p (&rest modes) 2703(defun derived-mode-p (&rest modes)
2697 "Non-nil if the current major mode is derived from one of MODES. 2704 "Non-nil if the current major mode is derived from one of MODES.
@@ -2699,6 +2706,10 @@ Uses the `derived-mode-parent' property of the symbol to trace backwards."
2699 (declare (side-effect-free t)) 2706 (declare (side-effect-free t))
2700 (apply #'provided-mode-derived-p major-mode modes)) 2707 (apply #'provided-mode-derived-p major-mode modes))
2701 2708
2709(defun derived-mode-set-parent (mode parent)
2710 "Declare PARENT to be the parent of MODE."
2711 (put mode 'derived-mode-parent parent))
2712
2702(defvar-local major-mode--suspended nil) 2713(defvar-local major-mode--suspended nil)
2703(put 'major-mode--suspended 'permanent-local t) 2714(put 'major-mode--suspended 'permanent-local t)
2704 2715