Skip to content

Commit

Permalink
Fix nested snippet expansion
Browse files Browse the repository at this point in the history
* 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.
  • Loading branch information
npostavs committed Mar 11, 2017
1 parent 0d9afb2 commit 7f337f4
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 2 deletions.
48 changes: 47 additions & 1 deletion yasnippet-tests.el
Expand Up @@ -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))
Expand All @@ -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
;;;
Expand Down
7 changes: 6 additions & 1 deletion yasnippet.el
Expand Up @@ -3166,14 +3166,19 @@ 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.
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
Expand Down

0 comments on commit 7f337f4

Please sign in to comment.