Closes #318: now checks for circular parenthood in snippet dirs

This commit is contained in:
Joao Tavora 2013-05-05 20:41:04 -04:00
parent 742b353a81
commit 0da56720a8
2 changed files with 38 additions and 4 deletions

View File

@ -312,6 +312,22 @@ TODO: correct this bug!"
(yas-reload-all) (yas-reload-all)
(yas--basic-jit-loading-1)))) (yas--basic-jit-loading-1))))
(ert-deftest loading-with-cyclic-parenthood ()
"Test loading when cyclic parenthood is setup."
(yas-saving-variables
(yas-with-snippet-dirs '((".emacs.d/snippets"
("c-mode"
(".yas-parents" . "cc-mode"))
("cc-mode"
(".yas-parents" . "yet-another-c-mode"))
("yet-another-c-mode"
(".yas-parents" . "c-mode"))))
(yas-reload-all)
(condition-case nil
(yas--all-parents 'c-mode)
(error
(ert-fail "cyclic parenthood test failed"))))))
(defun yas--basic-jit-loading-1 (&optional compile) (defun yas--basic-jit-loading-1 (&optional compile)
(with-temp-buffer (with-temp-buffer
(should (= 4 (hash-table-count yas--scheduled-jit-loads))) (should (= 4 (hash-table-count yas--scheduled-jit-loads)))

View File

@ -660,6 +660,11 @@ There might be additional parenting information stored in the
`derived-mode-parent' property of some mode symbols, but that is `derived-mode-parent' property of some mode symbols, but that is
not recorded here.") not recorded here.")
(defvar yas--ancestors (make-hash-table)
"A hash table of mode symbols do lists of all parent mode symbols.
A cache managed by `yas--all-parents'")
(defvar yas--direct-keymaps (list) (defvar yas--direct-keymaps (list)
"Keymap alist supporting direct snippet keybindings. "Keymap alist supporting direct snippet keybindings.
@ -1151,9 +1156,21 @@ conditions to filter out potential expansions."
(defun yas--all-parents (mode) (defun yas--all-parents (mode)
"Returns a list of all parent modes of MODE." "Returns a list of all parent modes of MODE."
(let ((parents (gethash mode yas--parents))) (or (gethash mode yas--ancestors)
(append parents (let ((seen '()))
(mapcan #'yas--all-parents parents)))) (labels ((yas--all-parents-1
(m)
(cond ((memq m seen)
(yas--message 1
"Cyclic parenthood: mode %s has already seen as a parent of mode %s"
m mode)
nil)
(t
(let* ((parents (gethash m yas--parents)))
(setq seen (append seen parents))
(append parents (mapcan #'yas--all-parents-1 parents)))))))
(puthash mode (yas--all-parents-1 mode)
yas--ancestors)))))
(defun yas--table-templates (table) (defun yas--table-templates (table)
(when table (when table
@ -1866,6 +1883,7 @@ loading."
;; ;;
(setq yas--tables (make-hash-table)) (setq yas--tables (make-hash-table))
(setq yas--parents (make-hash-table)) (setq yas--parents (make-hash-table))
(setq yas--ancestors (make-hash-table))
;; Before killing `yas--menu-table' use its keys to cleanup the ;; Before killing `yas--menu-table' use its keys to cleanup the
;; mode menu parts of `yas--minor-mode-menu' (thus also cleaning ;; mode menu parts of `yas--minor-mode-menu' (thus also cleaning
@ -2531,7 +2549,7 @@ neither do the elements of PARENTS."
(buffer-substring-no-properties (point-min) (buffer-substring-no-properties (point-min)
(point-max)))))))) (point-max))))))))
(when major-mode-sym (when major-mode-sym
(cons major-mode-sym parents)))) (cons major-mode-sym (remove major-mode-sym parents)))))
(defvar yas--editing-template nil (defvar yas--editing-template nil
"Supporting variable for `yas-load-snippet-buffer' and `yas--visit-snippet'.") "Supporting variable for `yas-load-snippet-buffer' and `yas--visit-snippet'.")