Skip to content

Commit

Permalink
Closes #318: now checks for circular parenthood in snippet dirs
Browse files Browse the repository at this point in the history
  • Loading branch information
joaotavora committed May 6, 2013
1 parent 742b353 commit 0da5672
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 4 deletions.
16 changes: 16 additions & 0 deletions yasnippet-tests.el
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,22 @@ TODO: correct this bug!"
(yas-reload-all)
(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)
(with-temp-buffer
(should (= 4 (hash-table-count yas--scheduled-jit-loads)))
Expand Down
26 changes: 22 additions & 4 deletions yasnippet.el
Original file line number Diff line number Diff line change
Expand Up @@ -660,6 +660,11 @@ There might be additional parenting information stored in the
`derived-mode-parent' property of some mode symbols, but that is
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)
"Keymap alist supporting direct snippet keybindings.

Expand Down Expand Up @@ -1151,9 +1156,21 @@ conditions to filter out potential expansions."

(defun yas--all-parents (mode)
"Returns a list of all parent modes of MODE."
(let ((parents (gethash mode yas--parents)))
(append parents
(mapcan #'yas--all-parents parents))))
(or (gethash mode yas--ancestors)
(let ((seen '()))
(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)
(when table
Expand Down Expand Up @@ -1866,6 +1883,7 @@ loading."
;;
(setq yas--tables (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
;; mode menu parts of `yas--minor-mode-menu' (thus also cleaning
Expand Down Expand Up @@ -2531,7 +2549,7 @@ neither do the elements of PARENTS."
(buffer-substring-no-properties (point-min)
(point-max))))))))
(when major-mode-sym
(cons major-mode-sym parents))))
(cons major-mode-sym (remove major-mode-sym parents)))))

(defvar yas--editing-template nil
"Supporting variable for `yas-load-snippet-buffer' and `yas--visit-snippet'.")
Expand Down

0 comments on commit 0da5672

Please sign in to comment.