diff --git a/yasnippet-tests.el b/yasnippet-tests.el index fbf79f8..4756571 100644 --- a/yasnippet-tests.el +++ b/yasnippet-tests.el @@ -491,15 +491,40 @@ TODO: correct this bug!" yet-another-c-mode and-also-this-one and-that-one - ;; prog-mode doesn't exit in emacs 24.3 + ;; prog-mode doesn't exist in emacs 24.3 ,@(if (fboundp 'prog-mode) '(prog-mode)) emacs-lisp-mode lisp-interaction-mode)) (observed (yas--modes-to-activate))) - (should (null (cl-set-exclusive-or expected observed))) - (should (= (length expected) - (length observed)))))))) + (should (equal (sort expected #'string<) (sort observed #'string<)))))))) + +(ert-deftest extra-modes-parenthood () + "Test activation of parents of `yas--extra-modes'." + (yas-saving-variables + (yas-with-snippet-dirs '((".emacs.d/snippets" + ("c-mode" + (".yas-parents" . "cc-mode")) + ("cc-mode" + (".yas-parents" . "yet-another-c-mode and-that-one")) + ("yet-another-c-mode" + (".yas-parents" . "c-mode and-also-this-one lisp-interaction-mode")))) + (yas-reload-all) + (with-temp-buffer + (let* ((_ (yas-activate-extra-mode 'c-mode)) + (expected `(,major-mode + c-mode + cc-mode + yet-another-c-mode + and-also-this-one + and-that-one + ;; prog-mode doesn't exist in emacs 24.3 + ,@(if (fboundp 'prog-mode) + '(prog-mode)) + emacs-lisp-mode + lisp-interaction-mode)) + (observed (yas--modes-to-activate))) + (should (equal (sort expected #'string<) (sort observed #'string<)))))))) (ert-deftest issue-492-and-494 () (defalias 'yas--phony-c-mode 'c-mode) diff --git a/yasnippet.el b/yasnippet.el index 1311cd0..a119011 100644 --- a/yasnippet.el +++ b/yasnippet.el @@ -728,22 +728,22 @@ defined direct keybindings to the command (defun yas--modes-to-activate (&optional mode) "Compute list of mode symbols that are active for `yas-expand' and friends." - (let (dfs) - (setq dfs (lambda (mode &optional explored) - (push mode explored) - (cons mode - (loop for neighbour - in (cl-list* (get mode 'derived-mode-parent) - (ignore-errors (symbol-function mode)) - (gethash mode yas--parents)) - when (and neighbour - (not (memq neighbour explored)) - (symbolp neighbour)) - append (funcall dfs neighbour explored))))) - (remove-duplicates (if mode - (funcall dfs mode) - (append yas--extra-modes - (funcall dfs major-mode)))))) + (let (dfs explored) + (setq dfs (lambda (mode) + (unless (memq mode explored) + (push mode explored) + (loop for neighbour + in (cl-list* (get mode 'derived-mode-parent) + (ignore-errors (symbol-function mode)) + (gethash mode yas--parents)) + when (and neighbour + (not (memq neighbour explored)) + (symbolp neighbour)) + do (funcall dfs neighbour))))) + (if mode + (funcall dfs mode) + (mapcar dfs (cons major-mode yas--extra-modes))) + explored)) (defvar yas-minor-mode-hook nil "Hook run when `yas-minor-mode' is turned on.")