emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[elpa] master e74f00e 18/63: Fix whitespace lossage between mirrors


From: Noam Postavsky
Subject: [elpa] master e74f00e 18/63: Fix whitespace lossage between mirrors
Date: Mon, 17 Jul 2017 22:54:13 -0400 (EDT)

branch: master
commit e74f00e70324101130c00b10af15f1f23e150654
Author: Noam Postavsky <address@hidden>
Commit: Noam Postavsky <address@hidden>

    Fix whitespace lossage between mirrors
    
    * yasnippet.el (yas--update-mirrors): Delay indentation until all
    mirrors are updated.
    (yas--mirror-update-display): Don't indent here.
    * yasnippet-tests.el (single-line-multi-mirror-indentation-2): New test.
---
 yasnippet-tests.el | 10 +++++++
 yasnippet.el       | 81 +++++++++++++++++++++++++-----------------------------
 2 files changed, 47 insertions(+), 44 deletions(-)

diff --git a/yasnippet-tests.el b/yasnippet-tests.el
index f57b1f2..a6abcb7 100644
--- a/yasnippet-tests.el
+++ b/yasnippet-tests.el
@@ -244,6 +244,16 @@ $1   ------------------------")
 XXXXX   ---------------- XXXXX ----
 XXXXX   ------------------------"))))
 
+(ert-deftest single-line-multi-mirror-indentation-2 ()
+  "Like `single-line-multi-mirror-indentation' but 2 mirrors interleaved."
+  ;; See also Github issue #768.
+  (with-temp-buffer
+    (c-mode)
+    (yas-minor-mode 1)
+    (yas-expand-snippet "${1:one} ${2:two};\n$1 $2_;\n$2 $1_;\n")
+    (should (string= (yas--buffer-contents)
+                     "one two;\none two_;\ntwo one_;\n"))))
+
 (ert-deftest indent-org-property ()
   "Handling of `org-mode' property indentation, see `org-property-format'."
   ;; This is an interesting case because `org-indent-line' calls
diff --git a/yasnippet.el b/yasnippet.el
index cc7f719..fa538c1 100644
--- a/yasnippet.el
+++ b/yasnippet.el
@@ -4365,44 +4365,42 @@ When multiple expressions are found, only the last one 
counts."
   (save-restriction
     (widen)
     (save-excursion
-      (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
-                ;;
-                (cl-mapcan #'(lambda (field)
-                               (mapcar #'(lambda (mirror)
-                                           (cons field mirror))
-                                       (cl-sort
-                                        (cl-copy-list
-                                         (yas--field-mirrors field))
-                                        #'<
-                                        :key #'yas--mirror-start)))
-                           (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--calculate-mirror-depth (cdr field-and-mirror1))
-                       (yas--calculate-mirror-depth (cdr 
field-and-mirror2))))))
-        (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 snippet)
-          ;; `yas--place-overlays' is needed since the active field and
-          ;; protected overlays might have been changed because of insertions
-          ;; in `yas--mirror-update-display'.
-          (let ((active-field (yas--snippet-active-field snippet)))
-            (when active-field (yas--place-overlays snippet 
active-field))))))))
+      (cl-loop
+       for (field . mirror)
+       in (cl-sort
+           ;; Make a list of (FIELD . MIRROR).
+           (cl-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 also handles the case where a mirror in
+           ;; a field causes another mirror to need reupdating.
+           #'> :key (lambda (fm) (yas--calculate-mirror-depth (cdr fm))))
+       ;; Before updating a mirror with a parent-field, maybe advance
+       ;; its start (#290).
+       do (let ((parent-field (yas--mirror-parent-field mirror)))
+            (when parent-field
+              (yas--advance-start-maybe mirror (yas--fom-start parent-field))))
+       ;; Update this mirror.
+       do (yas--mirror-update-display mirror field snippet)
+       ;; Delay indenting until we're done all mirrors.  We must do
+       ;; this to avoid losing whitespace between fields that are
+       ;; still empty (i.e., they will be non-empty after updating).
+       when (eq yas-indent-line 'auto)
+       collect (cons (yas--mirror-start mirror) (yas--mirror-end mirror))
+       into indent-regions
+       ;; `yas--place-overlays' is needed since the active field and
+       ;; protected overlays might have been changed because of insertions
+       ;; in `yas--mirror-update-display'.
+       do (let ((active-field (yas--snippet-active-field snippet)))
+            (when active-field (yas--place-overlays snippet active-field)))
+       finally do
+       (let ((yas--inhibit-overlay-hooks t))
+         (cl-loop for (beg . end) in (cl-sort indent-regions #'< :key #'car)
+                  do (yas--indent-region beg end snippet)))))))
 
 (defun yas--mirror-update-display (mirror field snippet)
   "Update MIRROR according to FIELD (and mirror transform)."
@@ -4423,12 +4421,7 @@ When multiple expressions are found, only the last one 
counts."
         (set-marker (yas--mirror-end mirror) (point))
         (yas--advance-start-maybe (yas--mirror-next mirror) (point))
         ;; super-special advance
-        (yas--advance-end-of-parents-maybe mirror-parent-field (point)))
-      (when (eq yas-indent-line 'auto)
-        (let ((yas--inhibit-overlay-hooks t))
-          (yas--indent-region (yas--mirror-start mirror)
-                              (yas--mirror-end mirror)
-                              snippet))))))
+        (yas--advance-end-of-parents-maybe mirror-parent-field (point))))))
 
 (defun yas--field-update-display (field)
   "Much like `yas--mirror-update-display', but for fields."



reply via email to

[Prev in Thread] Current Thread [Next in Thread]