mirror of
https://github.com/joaotavora/yasnippet.git
synced 2025-10-13 21:13:04 +00:00
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:
parent
cddb8260a0
commit
6e9b7f9432
@ -583,6 +583,38 @@ SUB"))))
|
|||||||
(ert-simulate-command '(yas-next-field))
|
(ert-simulate-command '(yas-next-field))
|
||||||
(should (eq yas--ran-exit-hook t)))))))
|
(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--barbaz)
|
||||||
(defvar yas--foobarbaz)
|
(defvar yas--foobarbaz)
|
||||||
|
|
||||||
|
22
yasnippet.el
22
yasnippet.el
@ -1352,7 +1352,7 @@ Returns (TEMPLATES START END). This function respects
|
|||||||
((debug error) (cdr oops)))))
|
((debug error) (cdr oops)))))
|
||||||
|
|
||||||
(defun yas--eval-for-effect (form)
|
(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)
|
(defun yas--read-lisp (string &optional nil-on-error)
|
||||||
"Read STRING as a elisp expression and return it.
|
"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))
|
(setq yas--snippets-to-move nil))
|
||||||
|
|
||||||
(defun yas--safely-call-fun (fun)
|
(defun yas--safely-call-fun (fun)
|
||||||
|
"Call FUN and catch any errors."
|
||||||
(condition-case error
|
(condition-case error
|
||||||
(funcall fun)
|
(funcall fun)
|
||||||
((debug error)
|
((debug error)
|
||||||
(yas--message 2 "Error running %s: %s"
|
(yas--message 2 "Error running %s: %s" fun
|
||||||
(if (symbolp fun) fun "a hook")
|
|
||||||
(error-message-string error)))))
|
(error-message-string error)))))
|
||||||
|
|
||||||
(defun yas--safely-run-hook (hook)
|
(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)))
|
(let ((debug-on-error (and (not (memq yas-good-grace '(t hooks)))
|
||||||
debug-on-error)))
|
debug-on-error)))
|
||||||
(if (functionp hook) (yas--safely-call-fun hook)
|
(yas--safely-call-fun (apply-partially #'run-hooks hook))))
|
||||||
(mapc #'yas--safely-call-fun hook))))
|
|
||||||
|
|
||||||
(defun yas--check-commit-snippet ()
|
(defun yas--check-commit-snippet ()
|
||||||
"Check if point exited the currently active field of the 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."
|
If so cleans up the whole snippet up."
|
||||||
(let* ((snippets (yas-active-snippets 'all))
|
(let* ((snippets (yas-active-snippets 'all))
|
||||||
(snippets-left snippets)
|
(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))
|
(snippet-exit-hook yas-after-exit-snippet-hook))
|
||||||
(dolist (snippet snippets)
|
(dolist (snippet snippets)
|
||||||
(let ((active-field (yas--snippet-active-field snippet)))
|
(let ((active-field (yas--snippet-active-field snippet)))
|
||||||
@ -3383,9 +3386,10 @@ If so cleans up the whole snippet up."
|
|||||||
(t
|
(t
|
||||||
nil)))))
|
nil)))))
|
||||||
(unless (or (null snippets) snippets-left)
|
(unless (or (null snippets) snippets-left)
|
||||||
(if snippet-exit-transform
|
(when snippet-exit-transform
|
||||||
(yas--eval-for-effect 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:
|
;; Apropos markers-to-points:
|
||||||
;;
|
;;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user