diff --git a/yasnippet-tests.el b/yasnippet-tests.el index f7ca2bb..578125b 100644 --- a/yasnippet-tests.el +++ b/yasnippet-tests.el @@ -1099,6 +1099,24 @@ 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-depth-2 () + (with-temp-buffer + (yas-with-snippet-dirs + '((".emacs.d/snippets" + ("text-mode" + ("nest" . "( $1")))) + (let ((yas-triggers-in-field t)) + (yas-reload-all) + (text-mode) + (yas-minor-mode +1) + (dotimes (_ 3) + (yas-mock-insert "nest") + (ert-simulate-command '(yas-expand))) + (dotimes (_ 3) + (yas-mock-insert ")") + (ert-simulate-command '(yas-next-field-or-maybe-expand))) + )))) + (ert-deftest nested-snippet-expansion-2 () (let ((yas-triggers-in-field t)) (yas-with-snippet-dirs diff --git a/yasnippet.el b/yasnippet.el index e0b5537..bf15b31 100644 --- a/yasnippet.el +++ b/yasnippet.el @@ -3501,7 +3501,8 @@ This renders the snippet as ordinary text." ;; (let ((previous-field (yas--snippet-previous-active-field snippet))) (when (and yas-snippet-end previous-field) - (yas--advance-end-maybe previous-field yas-snippet-end))) + (yas--advance-end-maybe-previous-fields + previous-field yas-snippet-end (cdr yas--active-snippets)))) ;; Convert all markers to points, ;; @@ -3849,14 +3850,9 @@ field start. This hook does nothing if an undo is in progress." (setf (yas--field-modified-p field) t) ;; Adjust any pending active fields in case of stacked ;; expansion. - (let ((pfield field) - (psnippets (yas--gather-active-snippets - overlay beg end t))) - (while (and pfield psnippets) - (let ((psnippet (pop psnippets))) - (cl-assert (memq pfield (yas--snippet-fields psnippet))) - (yas--advance-end-maybe pfield (overlay-end overlay)) - (setq pfield (yas--snippet-previous-active-field psnippet))))) + (yas--advance-end-maybe-previous-fields + field (overlay-end overlay) + (yas--gather-active-snippets overlay beg end t)) ;; Update fields now, but delay auto indentation until ;; post-command. We don't want to run indentation on ;; the intermediate state where field text might be @@ -4110,7 +4106,9 @@ for normal snippets, and a list for command snippets)." (overlay-get yas--active-field-overlay 'yas--field)))) (when 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-previous-fields + existing-field (overlay-end yas--active-field-overlay) + (cdr yas--active-snippets)))) ;; Exit the snippet immediately if no fields. (unless (yas--snippet-fields snippet) @@ -4336,6 +4334,13 @@ exit-marker have identical start and end markers." ((yas--exit-p fom) (yas--advance-start-maybe (yas--fom-next fom) newend)))) +(defun yas--advance-end-maybe-previous-fields (field end snippets) + "Call `yas--advance-end-maybe' on FIELD, and previous fields on SNIPPETS." + (dolist (snippet snippets) + (cl-assert (memq field (yas--snippet-fields snippet))) + (yas--advance-end-maybe field end) + (setq field (yas--snippet-previous-active-field snippet)))) + (defun yas--advance-start-maybe (fom newstart) "Maybe advance FOM's start to NEWSTART if it needs it.