Test and fix problem with mirror+autofill

cc-mode fill paragraph narrows to the paragraph being filled.  This
causes problems if there is a mirror needing to be updated outside of
the current paragraph.

* yasnippet-tests.el: New test.
* yasnippet.el (yas--update-mirrors): Widen while updating the mirrors.
This commit is contained in:
Noam Postavsky 2016-04-28 21:16:30 -04:00
parent 7799aa908b
commit bfe14f19ac
2 changed files with 58 additions and 36 deletions

View File

@ -68,6 +68,26 @@
(should (string= (yas--buffer-contents) (should (string= (yas--buffer-contents)
"bla from another BLA")))) "bla from another BLA"))))
(ert-deftest mirror-with-transformation-and-autofill ()
"Test interaction of autofill with mirror transforms"
(let ((words "one two three four five")
filled-words)
(with-temp-buffer
(c-mode) ; In `c-mode' filling comments works by narrowing.
(yas-minor-mode +1)
(setq fill-column 10)
(auto-fill-mode +1)
(yas-expand-snippet "/* $0\n */")
(yas-mock-insert words)
(setq filled-words (delete-and-extract-region (point-min) (point-max)))
(yas-expand-snippet "/* $1\n */\n$2$2")
(should (string= (yas--buffer-contents)
"/* \n */\n"))
(yas-mock-insert words)
(should (string= (yas--buffer-contents)
(concat filled-words "\n"))))))
(ert-deftest primary-field-transformation () (ert-deftest primary-field-transformation ()
(with-temp-buffer (with-temp-buffer
(yas-minor-mode 1) (yas-minor-mode 1)

View File

@ -4192,42 +4192,44 @@ When multiple expressions are found, only the last one counts."
(defun yas--update-mirrors (snippet) (defun yas--update-mirrors (snippet)
"Update all the mirrors of SNIPPET." "Update all the mirrors of SNIPPET."
(save-excursion (save-restriction
(dolist (field-and-mirror (widen)
(sort (save-excursion
;; make a list of ((F1 . M1) (F1 . M2) (F2 . M3) (F2 . M4) ...) (dolist (field-and-mirror
;; where F is the field that M is mirroring (sort
;; ;; make a list of ((F1 . M1) (F1 . M2) (F2 . M3) (F2 . M4) ...)
(cl-mapcan #'(lambda (field) ;; where F is the field that M is mirroring
(mapcar #'(lambda (mirror) ;;
(cons field mirror)) (cl-mapcan #'(lambda (field)
(yas--field-mirrors field))) (mapcar #'(lambda (mirror)
(yas--snippet-fields snippet)) (cons field mirror))
;; then sort this list so that entries with mirrors with parent (yas--field-mirrors field)))
;; fields appear before. This was important for fixing #290, and (yas--snippet-fields snippet))
;; luckily also handles the case where a mirror in a field causes ;; then sort this list so that entries with mirrors with parent
;; another mirror to need reupdating ;; fields appear before. This was important for fixing #290, and
;; ;; luckily also handles the case where a mirror in a field causes
#'(lambda (field-and-mirror1 field-and-mirror2) ;; another mirror to need reupdating
(> (yas--calculate-mirror-depth (cdr field-and-mirror1)) ;;
(yas--calculate-mirror-depth (cdr field-and-mirror2)))))) #'(lambda (field-and-mirror1 field-and-mirror2)
(let* ((field (car field-and-mirror)) (> (yas--calculate-mirror-depth (cdr field-and-mirror1))
(mirror (cdr field-and-mirror)) (yas--calculate-mirror-depth (cdr field-and-mirror2))))))
(parent-field (yas--mirror-parent-field mirror))) (let* ((field (car field-and-mirror))
;; before updating a mirror with a parent-field, maybe advance (mirror (cdr field-and-mirror))
;; its start (#290) (parent-field (yas--mirror-parent-field mirror)))
;; ;; before updating a mirror with a parent-field, maybe advance
(when parent-field ;; its start (#290)
(yas--advance-start-maybe mirror (yas--fom-start parent-field))) ;;
;; update this mirror (when parent-field
;; (yas--advance-start-maybe mirror (yas--fom-start parent-field)))
(yas--mirror-update-display mirror field) ;; update this mirror
;; `yas--place-overlays' is needed if the active field and ;;
;; protected overlays have been changed because of insertions (yas--mirror-update-display mirror field)
;; in `yas--mirror-update-display' ;; `yas--place-overlays' is needed if the active field and
;; ;; protected overlays have been changed because of insertions
(when (eq field (yas--snippet-active-field snippet)) ;; in `yas--mirror-update-display'
(yas--place-overlays snippet field)))))) ;;
(when (eq field (yas--snippet-active-field snippet))
(yas--place-overlays snippet field)))))))
(defun yas--mirror-update-display (mirror field) (defun yas--mirror-update-display (mirror field)
"Update MIRROR according to FIELD (and mirror transform)." "Update MIRROR according to FIELD (and mirror transform)."