From 74e8f43f065fbb9d775aa105a1e0ffc61358e2c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20T=C3=A1vora?= Date: Tue, 25 Dec 2012 04:20:03 +0000 Subject: [PATCH] Closes #351: sort mirrors by nesting depth when updating --- yasnippet-tests.el | 7 +++++++ yasnippet.el | 26 ++++++++++++++++++++++++-- 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/yasnippet-tests.el b/yasnippet-tests.el index e8c4a11..0af1452 100644 --- a/yasnippet-tests.el +++ b/yasnippet-tests.el @@ -105,6 +105,13 @@ (should (string= (yas--buffer-contents) "<%= f.submit \"Send\", :disable_with => 'Sending...' %>"))) +(ert-deftest deep-nested-mirroring-issue-351 () + (with-temp-buffer + (yas-minor-mode 1) + (yas-expand-snippet "${1:FOOOOOOO}${2:$1}${3:$2}${4:$3}") + (ert-simulate-command `(yas-mock-insert "abc")) + (should (string= (yas--buffer-contents) "abcabcabcabc")))) + ;; (ert-deftest in-snippet-undo () ;; (with-temp-buffer ;; (yas-minor-mode 1) diff --git a/yasnippet.el b/yasnippet.el index cc14fa0..d51a7ed 100644 --- a/yasnippet.el +++ b/yasnippet.el @@ -2923,7 +2923,8 @@ Use this in primary and mirror transformations to tget." start end (transform nil) parent-field - next) + next + depth) (defstruct (yas--exit (:constructor yas--make-exit (marker))) marker @@ -4155,6 +4156,26 @@ When multiple expressions are found, only the last one counts." #'(lambda (r1 r2) (>= (car r1) (car r2)))))) +(defun yas--calculate-mirror-depth (mirror &optional traversed) + (let* ((parent (yas--mirror-parent-field mirror)) + (parents-mirrors (and parent + (yas--field-mirrors parent)))) + (or (yas--mirror-depth mirror) + (setf (yas--mirror-depth mirror) + (cond ((memq mirror traversed) + 0) + ((and parent parents-mirrors) + (1+ (reduce #'max + (mapcar #'(lambda (m) + (yas--calculate-mirror-depth m + (cons mirror + traversed))) + parents-mirrors)))) + (parent + 1) + (t + 0)))))) + (defun yas--update-mirrors (snippet) "Updates all the mirrors of SNIPPET." (save-excursion @@ -4173,7 +4194,8 @@ When multiple expressions are found, only the last one counts." ;; another mirror to need reupdating ;; #'(lambda (field-and-mirror1 field-and-mirror2) - (yas--mirror-parent-field (cdr field-and-mirror1))))) + (> (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)))