branch: master commit 6e9b7f9432a87122cf9bb80a505be2fd9811a9cf Author: Etienne <noteti...@users.noreply.github.com> Commit: Noam Postavsky <npost...@users.sourceforge.net>
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. --- yasnippet-tests.el | 32 ++++++++++++++++++++++++++++++++ yasnippet.el | 22 +++++++++++++--------- 2 files changed, 45 insertions(+), 9 deletions(-) diff --git a/yasnippet-tests.el b/yasnippet-tests.el index dc0c43c..1c7c94f 100644 --- a/yasnippet-tests.el +++ b/yasnippet-tests.el @@ -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) diff --git a/yasnippet.el b/yasnippet.el index 7b871b9..76e1d25 100644 --- a/yasnippet.el +++ b/yasnippet.el @@ -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 - (yas--eval-for-effect snippet-exit-transform)) - (yas--safely-run-hook snippet-exit-hook)))) + (when snippet-exit-transform + (yas--eval-for-effect snippet-exit-transform)) + (let ((yas-after-exit-snippet-hook snippet-exit-hook)) + (yas--safely-run-hook 'yas-after-exit-snippet-hook))))) ;; Apropos markers-to-points: ;;