Fix nested snippet expansion

* yasnippet.el (yas--place-overlays): Don't move active field overlays
unless we're working on the innermost snippet.
(yas--move-to-field): Keep `yas--active-field-overlay's `yas--snippet'
property in sync with its `yas--field' property.
* yasnippet-tests.el (nested-snippet-expansion-1): Rename from
nested-snippet-expansion-1.
(nested-snippet-expansion-2, nested-snippet-expansion-3): New tests.
This commit is contained in:
Noam Postavsky 2017-02-15 22:58:34 -05:00
parent 0d9afb2c69
commit 7f337f4488
2 changed files with 53 additions and 2 deletions

View File

@ -678,7 +678,7 @@ hello ${1:$(when (stringp yas-text) (funcall func yas-text))} foo${1:$$(concat \
(yas-should-expand '(("foo-barbaz" . "OKfoo-barbazOK")
("foo " . "foo "))))))))
(ert-deftest nested-snippet-expansion ()
(ert-deftest nested-snippet-expansion-1 ()
(with-temp-buffer
(yas-minor-mode +1)
(let ((yas-triggers-in-field t))
@ -689,6 +689,52 @@ hello ${1:$(when (stringp yas-text) (funcall func yas-text))} foo${1:$$(concat \
(should (= (length (yas--snippet-fields (nth 0 snippets))) 2))
(should (= (length (yas--snippet-fields (nth 1 snippets))) 1))))))
(ert-deftest nested-snippet-expansion-2 ()
(let ((yas-triggers-in-field t))
(yas-with-snippet-dirs
'((".emacs.d/snippets"
("text-mode"
("nest" . "one($1:$1) two($2).$0"))))
(yas-reload-all)
(text-mode)
(yas-minor-mode +1)
(insert "nest")
(ert-simulate-command '(yas-expand))
(yas-mock-insert "nest")
(ert-simulate-command '(yas-expand))
(yas-mock-insert "x")
(ert-simulate-command '(yas-next-field-or-maybe-expand))
(yas-mock-insert "y")
(ert-simulate-command '(yas-next-field-or-maybe-expand))
(ert-simulate-command '(yas-next-field-or-maybe-expand))
(yas-mock-insert "z")
(ert-simulate-command '(yas-next-field-or-maybe-expand))
(should (string= (buffer-string)
"one(one(x:x) two(y).:one(x:x) two(y).) two(z).")))))
(ert-deftest nested-snippet-expansion-3 ()
(let ((yas-triggers-in-field t))
(yas-with-snippet-dirs
'((".emacs.d/snippets"
("text-mode"
("rt" . "\
\\sqrt${1:$(if (string-equal \"\" yas/text) \"\" \"[\")}${1:}${1:$(if (string-equal \"\" yas/text) \"\" \"]\")}{$2}$0"))))
(yas-reload-all)
(text-mode)
(yas-minor-mode +1)
(insert "rt")
(ert-simulate-command '(yas-expand))
(yas-mock-insert "3")
(ert-simulate-command '(yas-next-field-or-maybe-expand))
(yas-mock-insert "rt")
(ert-simulate-command '(yas-next-field-or-maybe-expand))
(yas-mock-insert "5")
(ert-simulate-command '(yas-next-field-or-maybe-expand))
(yas-mock-insert "2")
(ert-simulate-command '(yas-next-field-or-maybe-expand))
(ert-simulate-command '(yas-next-field-or-maybe-expand))
(should (string= (buffer-string) "\\sqrt[3]{\\sqrt[5]{2}}")))))
;;; Loading
;;;

View File

@ -3166,7 +3166,11 @@ If there's none, exit the snippet."
(defun yas--place-overlays (snippet field)
"Correctly place overlays for SNIPPET's FIELD."
(yas--make-move-field-protection-overlays snippet field)
(yas--make-move-active-field-overlay snippet field))
;; Only move active field overlays if this is field is from the
;; innermost snippet.
(when (eq snippet (car (yas-active-snippets (1- (yas--field-start field))
(1+ (yas--field-end field)))))
(yas--make-move-active-field-overlay snippet field)))
(defun yas--move-to-field (snippet field)
"Update SNIPPET to move to field FIELD.
@ -3174,6 +3178,7 @@ If there's none, exit the snippet."
Also create some protection overlays"
(goto-char (yas--field-start field))
(yas--place-overlays snippet field)
(overlay-put yas--active-field-overlay 'yas--snippet snippet)
(overlay-put yas--active-field-overlay 'yas--field field)
(let ((number (yas--field-number field)))
;; check for the special ${0: ...} field