Handle field adjust of pending active fields

* yasnippet.el (yas--on-field-overlay-modification): Call
yas--advance-end-maybe on all pending active snippets in case of
stacked expansion.
(yas-next-field): Get current snippet according to
active field bounds.
* yasnippet-tests.el (nested-snippet-expansion-4): New test.
This commit is contained in:
Noam Postavsky 2018-09-26 18:37:08 -04:00
parent ffc733d4cf
commit eeb05f0910
2 changed files with 32 additions and 3 deletions

View File

@ -1066,6 +1066,26 @@ hello ${1:$(when (stringp yas-text) (funcall func yas-text))} foo${1:$$(concat \
(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}}"))))) (should (string= (buffer-string) "\\sqrt[3]{\\sqrt[5]{2}}")))))
(ert-deftest nested-snippet-expansion-4 ()
"See Github #959."
(let ((yas-triggers-in-field t))
(yas-with-snippet-dirs
'((".emacs.d/snippets"
("text-mode"
("ch" . "<-${1:ch}"))))
(yas-reload-all)
(text-mode)
(yas-minor-mode +1)
(yas-expand-snippet "ch$0\n")
(ert-simulate-command '(yas-expand))
(ert-simulate-command '(forward-char 2))
(ert-simulate-command '(yas-expand))
(yas-mock-insert "abc")
(ert-simulate-command '(yas-next-field-or-maybe-expand))
(yas-mock-insert "def")
(ert-simulate-command '(yas-next-field-or-maybe-expand))
(should (string= (buffer-string) "<-<-abcdef\n")))))
;;; Loading ;;; Loading
;;; ;;;

View File

@ -3326,8 +3326,9 @@ Otherwise delegate to `yas-next-field'."
If there's none, exit the snippet." If there's none, exit the snippet."
(interactive) (interactive)
(unless arg (setq arg 1)) (unless arg (setq arg 1))
(let* ((snippet (car (yas-active-snippets))) (let* ((active-field (overlay-get yas--active-field-overlay 'yas--field))
(active-field (overlay-get yas--active-field-overlay 'yas--field)) (snippet (car (yas-active-snippets (yas--field-start active-field)
(yas--field-end active-field))))
(target-field (yas--find-next-field arg snippet active-field))) (target-field (yas--find-next-field arg snippet active-field)))
(yas--letenv (yas--snippet-expand-env snippet) (yas--letenv (yas--snippet-expand-env snippet)
;; Apply transform to active field. ;; Apply transform to active field.
@ -3745,7 +3746,15 @@ field start. This hook does nothing if an undo is in progress."
;; We delete text starting from the END of insertion. ;; We delete text starting from the END of insertion.
(yas--skip-and-clear field end)) (yas--skip-and-clear field end))
(setf (yas--field-modified-p field) t) (setf (yas--field-modified-p field) t)
(yas--advance-end-maybe field (overlay-end overlay)) ;; Adjust any pending active fields in case of stacked
;; expansion.
(let ((pfield field)
(psnippets (yas-active-snippets beg end)))
(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)))))
(save-excursion (save-excursion
(yas--field-update-display field)) (yas--field-update-display field))
(yas--update-mirrors snippet))) (yas--update-mirrors snippet)))