Change yas-lookup-snippet to return a yas--template struct

This allows proper handling of a snippet's expand-env field when doing

    (yas-expand-snippet (yas-lookup-snippet NAME))

* yasnippet.el (yas-expand-snippet): Return the yas--template struct
instead of snippet body.
(yas-expand-snippet): Let first argument be a yas--template struct.
* yasnippet-tests.el (snippet-lookup, snippet-load-uuid): Update tests
accordingly.
(yas-lookup-snippet-with-env): New test.
This commit is contained in:
Noam Postavsky 2018-02-03 11:07:01 -05:00
parent 05ac1da894
commit c9277d326e
2 changed files with 77 additions and 55 deletions

View File

@ -1031,11 +1031,28 @@ hello ${1:$(when (stringp yas-text) (funcall func yas-text))} foo${1:$$(concat \
"Test `yas-lookup-snippet'." "Test `yas-lookup-snippet'."
(yas-with-some-interesting-snippet-dirs (yas-with-some-interesting-snippet-dirs
(yas-reload-all 'no-jit) (yas-reload-all 'no-jit)
(should (equal (yas-lookup-snippet "printf" 'c-mode) "printf($1);")) (should (equal (yas--template-content (yas-lookup-snippet "printf" 'c-mode))
(should (equal (yas-lookup-snippet "def" 'c-mode) "# define")) "printf($1);"))
(should (equal (yas--template-content (yas-lookup-snippet "def" 'c-mode))
"# define"))
(should-not (yas-lookup-snippet "no such snippet" nil 'noerror)) (should-not (yas-lookup-snippet "no such snippet" nil 'noerror))
(should-not (yas-lookup-snippet "printf" 'emacs-lisp-mode 'noerror)))) (should-not (yas-lookup-snippet "printf" 'emacs-lisp-mode 'noerror))))
(ert-deftest yas-lookup-snippet-with-env ()
(with-temp-buffer
(yas-with-snippet-dirs
'((".emacs.d/snippets"
("emacs-lisp-mode"
("foo" . "\
# expand-env: ((foo \"bar\"))
# --
`foo`"))))
(yas-reload-all)
(emacs-lisp-mode)
(yas-minor-mode +1)
(yas-expand-snippet (yas-lookup-snippet "foo"))
(should (equal (buffer-string) "bar")))))
(ert-deftest basic-jit-loading () (ert-deftest basic-jit-loading ()
"Test basic loading and expansion of snippets" "Test basic loading and expansion of snippets"
(yas-with-some-interesting-snippet-dirs (yas-with-some-interesting-snippet-dirs
@ -1063,13 +1080,15 @@ hello ${1:$(when (stringp yas-text) (funcall func yas-text))} foo${1:$$(concat \
(with-temp-buffer (with-temp-buffer
(text-mode) (text-mode)
(yas-minor-mode +1) (yas-minor-mode +1)
(should (equal (yas-lookup-snippet "one") "one")) (should (equal (yas--template-content (yas-lookup-snippet "one"))
"one"))
(should (eq (yas--key-binding "\C-c1") 'yas-expand-from-keymap)) (should (eq (yas--key-binding "\C-c1") 'yas-expand-from-keymap))
(yas-define-snippets (yas-define-snippets
'text-mode '(("_1" "one!" "won" nil nil nil nil nil "uuid-1"))) 'text-mode '(("_1" "one!" "won" nil nil nil nil nil "uuid-1")))
(should (null (yas-lookup-snippet "one" nil 'noerror))) (should (null (yas-lookup-snippet "one" nil 'noerror)))
(should (null (yas--key-binding "\C-c1"))) (should (null (yas--key-binding "\C-c1")))
(should (equal (yas-lookup-snippet "won") "one!"))))) (should (equal (yas--template-content(yas-lookup-snippet "won"))
"one!")))))
(ert-deftest snippet-save () (ert-deftest snippet-save ()
"Make sure snippets can be saved correctly." "Make sure snippets can be saved correctly."

View File

@ -2412,18 +2412,17 @@ Honours `yas-choose-tables-first', `yas-choose-keys-first' and
:key #'yas--template-name :test #'string=))) :key #'yas--template-name :test #'string=)))
(defun yas-lookup-snippet (name &optional mode noerror) (defun yas-lookup-snippet (name &optional mode noerror)
"Get the snippet content for the snippet NAME in MODE's tables. "Get the snippet named NAME in MODE's tables.
MODE defaults to the current buffer's `major-mode'. If NOERROR MODE defaults to the current buffer's `major-mode'. If NOERROR
is non-nil, then don't signal an error if there isn't any snippet is non-nil, then don't signal an error if there isn't any snippet
called NAME. called NAME.
Honours `yas-buffer-local-condition'." Honours `yas-buffer-local-condition'."
(let ((snippet (yas--lookup-snippet-1 name mode)))
(cond (cond
(snippet (yas--template-content snippet)) ((yas--lookup-snippet-1 name mode))
(noerror nil) (noerror nil)
(t (error "No snippet named: %s" name))))) (t (error "No snippet named: %s" name))))
(defun yas-insert-snippet (&optional no-condition) (defun yas-insert-snippet (&optional no-condition)
"Choose a snippet to expand, pop-up a list of choices according "Choose a snippet to expand, pop-up a list of choices according
@ -3783,12 +3782,17 @@ Move the overlays, or create them if they do not exit."
;; running, but if managed correctly (including overlay priorities) ;; running, but if managed correctly (including overlay priorities)
;; they should account for all situations... ;; they should account for all situations...
(defun yas-expand-snippet (content &optional start end expand-env) (defun yas-expand-snippet (snippet &optional start end expand-env)
"Expand snippet CONTENT at current point. "Expand SNIPPET at current point.
Text between START and END will be deleted before inserting Text between START and END will be deleted before inserting
template. EXPAND-ENV is a list of (SYM VALUE) let-style dynamic bindings template. EXPAND-ENV is a list of (SYM VALUE) let-style dynamic
considered when expanding the snippet." bindings considered when expanding the snippet. If omitted, use
SNIPPET's expand-env field.
SNIPPET may be a snippet structure (e.g., as returned by
`yas-lookup-snippet'), or just a string representing a snippet's
body text."
(cl-assert (and yas-minor-mode (cl-assert (and yas-minor-mode
(memq 'yas--post-command-handler post-command-hook)) (memq 'yas--post-command-handler post-command-hook))
nil nil
@ -3820,17 +3824,19 @@ considered when expanding the snippet."
(cond (yas-selected-text) (cond (yas-selected-text)
((and (region-active-p) ((and (region-active-p)
(not clear-field)) (not clear-field))
to-delete))) to-delete))))
snippet)
(goto-char start) (goto-char start)
(setq yas--indent-original-column (current-column)) (setq yas--indent-original-column (current-column))
;; Delete the region to delete, this *does* get undo-recorded. ;; Delete the region to delete, this *does* get undo-recorded.
(when to-delete (when to-delete
(delete-region start end)) (delete-region start end))
(let ((content (if (stringp snippet) snippet
(yas--template-content snippet))))
(when (and (not expand-env) (yas--template-p snippet))
(setq expand-env (yas--template-expand-env snippet)))
(cond ((listp content) (cond ((listp content)
;; x) This is a snippet-command ;; x) This is a snippet-command.
;;
(yas--eval-for-effect content)) (yas--eval-for-effect content))
(t (t
;; x) This is a snippet-snippet :-) ;; x) This is a snippet-snippet :-)
@ -3840,9 +3846,8 @@ considered when expanding the snippet."
(setq snippet (setq snippet
(yas--snippet-create content expand-env start (point)))) (yas--snippet-create content expand-env start (point))))
;; stacked-expansion: This checks for stacked expansion, save the ;; Stacked-expansion: This checks for stacked expansion, save the
;; `yas--previous-active-field' and advance its boundary. ;; `yas--previous-active-field' and advance its boundary.
;;
(let ((existing-field (and yas--active-field-overlay (let ((existing-field (and yas--active-field-overlay
(overlay-buffer yas--active-field-overlay) (overlay-buffer yas--active-field-overlay)
(overlay-get yas--active-field-overlay 'yas--field)))) (overlay-get yas--active-field-overlay 'yas--field))))
@ -3850,13 +3855,11 @@ considered when expanding the snippet."
(setf (yas--snippet-previous-active-field snippet) existing-field) (setf (yas--snippet-previous-active-field snippet) existing-field)
(yas--advance-end-maybe existing-field (overlay-end yas--active-field-overlay)))) (yas--advance-end-maybe existing-field (overlay-end yas--active-field-overlay))))
;; Exit the snippet immediately if no fields ;; Exit the snippet immediately if no fields.
;;
(unless (yas--snippet-fields snippet) (unless (yas--snippet-fields snippet)
(yas-exit-snippet snippet)) (yas-exit-snippet snippet))
;; Now, schedule a move to the first field ;; Now, schedule a move to the first field.
;;
(let ((first-field (car (yas--snippet-fields snippet)))) (let ((first-field (car (yas--snippet-fields snippet))))
(when first-field (when first-field
(sit-for 0) ;; fix issue 125 (sit-for 0) ;; fix issue 125
@ -3869,7 +3872,7 @@ considered when expanding the snippet."
;; Keep region for ${0:exit text}. ;; Keep region for ${0:exit text}.
(setq deactivate-mark nil)))) (setq deactivate-mark nil))))
(yas--message 4 "snippet %d expanded." (yas--snippet-id snippet)) (yas--message 4 "snippet %d expanded." (yas--snippet-id snippet))
t)))) t)))))
(defun yas--take-care-of-redo (snippet) (defun yas--take-care-of-redo (snippet)
"Commits SNIPPET, which in turn pushes an undo action for reviving it. "Commits SNIPPET, which in turn pushes an undo action for reviving it.