]> code.delx.au - gnu-emacs-elpa/commitdiff
Closes #290: problem when advancing the start of a mirror-in-field
authorJoão Távora <joaotavora@gmail.com>
Tue, 21 Aug 2012 23:52:17 +0000 (00:52 +0100)
committerJoão Távora <joaotavora@gmail.com>
Tue, 21 Aug 2012 23:52:17 +0000 (00:52 +0100)
* Rewrote 'yas--update-mirrors'
* Added unit test
* Advancing is done exceptionally in 'yas--update-mirrors'
  not 'yas--mirror-update-display' and just before we need to
  re-update the mirror-in-field.
* Alternative to prior point would be to have fields carry a reference
  to their child mirrors.

yasnippet-tests.el
yasnippet.el

index 9af244b9e8944576e847e1a445887ff535c4989d..62653b0902668c14c86b036cbb7f5d0a74111f32 100644 (file)
     (should (string= (yas--buffer-contents)
                      "brother from another bla!"))))
 
+(ert-deftest mirrors-adjacent-to-fields-with-nested-mirrors ()
+  (with-temp-buffer)
+  (yas-minor-mode 1)
+  (yas-expand-snippet "<%= f.submit \"${1:Submit}\"${2:$(and (yas-text) \", :disable_with => '\")}${2:$1ing...}${2:$(and (yas-text) \"'\")} %>")
+  (should (string= (yas--buffer-contents)
+                   "<%= f.submit \"Submit\", :disable_with => 'Submiting...' %>"))
+  (ert-simulate-command `(yas-mock-insert "Send"))
+  (should (string= (yas--buffer-contents)
+                   "<%= f.submit \"Send\", :disable_with => 'Sending...' %>")))
+
 ;; (ert-deftest in-snippet-undo ()
 ;;   (with-temp-buffer
 ;;     (yas-minor-mode 1)
index d03f4286baad4a2b3c1a9c83d0d675007d92b50b..c65aa2f7d2ab862c3966445988423ce20a84aba8 100644 (file)
@@ -4139,27 +4139,39 @@ When multiple expressions are found, only the last one counts."
 (defun yas--update-mirrors (snippet)
   "Updates all the mirrors of SNIPPET."
   (save-excursion
-    (let* ((fields (copy-list (yas--snippet-fields snippet)))
-           (field (car fields)))
-      (while field
-        (dolist (mirror (yas--field-mirrors field))
-          (let ((mirror-parent-field (yas--mirror-parent-field mirror)))
-            ;; updatte this mirror
-            ;;
-            (yas--mirror-update-display mirror field)
-            ;; for mirrors-in-fields: schedule a possible
-            ;; parent field for reupdting later on
-            ;;
-            (when mirror-parent-field
-              (add-to-list 'fields mirror-parent-field 'append #'eq))
-            ;; `yas--place-overlays' is needed if the active field and
-            ;; protected overlays have been changed because of insertions
-            ;; in `yas--mirror-update-display'
-            ;;
-            (when (eq field (yas--snippet-active-field snippet))
-              (yas--place-overlays snippet field))))
-        (setq fields (cdr fields))
-        (setq field (car fields))))))
+    (dolist (field-and-mirror (sort
+                               ;; make a list of ((F1 . M1) (F1 . M2) (F2 . M3) (F2 . M4) ...)
+                               ;; where F is the field that M is mirroring
+                               ;;
+                               (mapcan #'(lambda (field)
+                                           (mapcar #'(lambda (mirror)
+                                                       (cons field mirror))
+                                                   (yas--field-mirrors field)))
+                                       (yas--snippet-fields snippet))
+                               ;; then sort this list so that entries with mirrors with parent
+                               ;; fields appear before. This was important for fixing #290, and
+                               ;; luckily also handles the case where a mirror in a field causes
+                               ;; another mirror to need reupdating
+                               ;;
+                               #'(lambda (field-and-mirror1 field-and-mirror2)
+                                   (yas--mirror-parent-field (cdr field-and-mirror1)))))
+      (let* ((field (car field-and-mirror))
+             (mirror (cdr field-and-mirror))
+             (parent-field (yas--mirror-parent-field mirror)))
+        ;; before updating a mirror with a parent-field, maybe advance
+        ;; its start (#290)
+        ;;
+        (when parent-field
+          (yas--advance-start-maybe mirror (yas--fom-start parent-field)))
+        ;; update this mirror
+        ;;
+        (yas--mirror-update-display mirror field)
+        ;; `yas--place-overlays' is needed if the active field and
+        ;; protected overlays have been changed because of insertions
+        ;; in `yas--mirror-update-display'
+        ;;
+        (when (eq field (yas--snippet-active-field snippet))
+          (yas--place-overlays snippet field))))))
 
 (defun yas--mirror-update-display (mirror field)
   "Update MIRROR according to FIELD (and mirror transform)."