Fix running hook variable set as buffer-local

* yasnippet.el (yas--eval-for-effect): Use `yas--safely-call-fun'
instead of `yas--safely-run-hook'.
(yas--safely-call-fun): Display the called argument (even a lambda) on
errors.
(yas--safely-run-hook): Take a hook variable instead of the hook value
itself.  Use `run-hooks' to take buffer-local values into account.
This means it’s no longer possible to warn which hook function had an
error.
(yas--check-commit-snippet): Refactor to conform to
`yas--safely-run-hooks'.
* yasnippet-tests.el (snippet-exit-hooks-bindings): New test that
checks for buffer-local, global and env hooks support.
This commit is contained in:
Etienne 2017-02-17 14:17:04 -05:00 committed by Noam Postavsky
parent cddb8260a0
commit 6e9b7f9432
2 changed files with 45 additions and 9 deletions

View File

@ -583,6 +583,38 @@ SUB"))))
(ert-simulate-command '(yas-next-field))
(should (eq yas--ran-exit-hook t)))))))
(ert-deftest snippet-exit-hooks-bindings ()
"Check that `yas-after-exit-snippet-hook' is handled correctly
in the case of a buffer-local variable and being overwritten by
the expand-env field."
(defvar yas--ran-exit-hook)
(with-temp-buffer
(yas-saving-variables
(let ((yas--ran-exit-hook nil)
(yas-triggers-in-field t)
(yas-after-exit-snippet-hook nil))
(yas-with-snippet-dirs
'((".emacs.d/snippets"
("emacs-lisp-mode"
("foo" . "foobar\n")
("baz" . "\
# expand-env: ((yas-after-exit-snippet-hook (lambda () (setq yas--ran-exit-hook 'letenv))))
# --
foobaz\n"))))
(yas-reload-all)
(emacs-lisp-mode)
(yas-minor-mode +1)
(add-hook 'yas-after-exit-snippet-hook (lambda () (push 'global yas--ran-exit-hook)))
(add-hook 'yas-after-exit-snippet-hook (lambda () (push 'local yas--ran-exit-hook)) nil t)
(insert "baz")
(ert-simulate-command '(yas-expand))
(should (eq 'letenv yas--ran-exit-hook))
(insert "foo")
(ert-simulate-command '(yas-expand))
(should (eq 'global (nth 0 yas--ran-exit-hook)))
(should (eq 'local (nth 1 yas--ran-exit-hook))))))))
(defvar yas--barbaz)
(defvar yas--foobarbaz)

View File

@ -1352,7 +1352,7 @@ Returns (TEMPLATES START END). This function respects
((debug error) (cdr oops)))))
(defun yas--eval-for-effect (form)
(yas--safely-run-hook (apply-partially #'eval form)))
(yas--safely-call-fun (apply-partially #'eval form)))
(defun yas--read-lisp (string &optional nil-on-error)
"Read STRING as a elisp expression and return it.
@ -3336,18 +3336,19 @@ This renders the snippet as ordinary text."
(setq yas--snippets-to-move nil))
(defun yas--safely-call-fun (fun)
"Call FUN and catch any errors."
(condition-case error
(funcall fun)
((debug error)
(yas--message 2 "Error running %s: %s"
(if (symbolp fun) fun "a hook")
(yas--message 2 "Error running %s: %s" fun
(error-message-string error)))))
(defun yas--safely-run-hook (hook)
"Call HOOK's functions.
HOOK should be a symbol, a hook variable, as in `run-hooks'."
(let ((debug-on-error (and (not (memq yas-good-grace '(t hooks)))
debug-on-error)))
(if (functionp hook) (yas--safely-call-fun hook)
(mapc #'yas--safely-call-fun hook))))
(yas--safely-call-fun (apply-partially #'run-hooks hook))))
(defun yas--check-commit-snippet ()
"Check if point exited the currently active field of the snippet.
@ -3355,7 +3356,9 @@ This renders the snippet as ordinary text."
If so cleans up the whole snippet up."
(let* ((snippets (yas-active-snippets 'all))
(snippets-left snippets)
(snippet-exit-transform nil)
(snippet-exit-transform)
;; Record the custom snippet `yas-after-exit-snippet-hook'
;; set in the expand-env field.
(snippet-exit-hook yas-after-exit-snippet-hook))
(dolist (snippet snippets)
(let ((active-field (yas--snippet-active-field snippet)))
@ -3383,9 +3386,10 @@ If so cleans up the whole snippet up."
(t
nil)))))
(unless (or (null snippets) snippets-left)
(if snippet-exit-transform
(when snippet-exit-transform
(yas--eval-for-effect snippet-exit-transform))
(yas--safely-run-hook snippet-exit-hook))))
(let ((yas-after-exit-snippet-hook snippet-exit-hook))
(yas--safely-run-hook 'yas-after-exit-snippet-hook)))))
;; Apropos markers-to-points:
;;