فهرست منبع

org-element: Fix re-parenting during cache synchronization

* lisp/org-element.el (org-element--cache-process-request): Correctly
  re-parent elements in cache in some corner cases.
* testing/lisp/test-org-element.el (test-org-element/cache): Add tests.
Nicolas Goaziou 10 سال پیش
والد
کامیت
05be573e92
2فایلهای تغییر یافته به همراه46 افزوده شده و 3 حذف شده
  1. 12 3
      lisp/org-element.el
  2. 34 0
      testing/lisp/test-org-element.el

+ 12 - 3
lisp/org-element.el

@@ -5201,12 +5201,21 @@ request."
 		  (dolist (object (cddr object-data))
 		    (org-element--cache-shift-positions object offset))))
 	      (let ((begin (org-element-property :begin data)))
-		;; Re-parent it.
+		;; Update PARENT and re-parent DATA, only when
+		;; necessary.  Propagate new structures for lists.
 		(while (and parent
 			    (<= (org-element-property :end parent) begin))
 		  (setq parent (org-element-property :parent parent)))
-		(cond (parent (org-element-put-property data :parent parent))
-		      ((zerop offset) (throw 'quit t)))
+		(cond ((and (not parent) (zerop offset)) (throw 'quit nil))
+		      ((and parent
+			    (let ((p (org-element-property :parent data)))
+			      (or (not p)
+				  (< (org-element-property :begin p)
+				     (org-element-property :begin parent)))))
+		       (org-element-put-property data :parent parent)
+		       (let ((s (org-element-property :structure parent)))
+			 (when (and s (org-element-property :structure data))
+			   (org-element-put-property data :structure s)))))
 		;; Cache is up-to-date past THRESHOLD.  Request
 		;; interruption.
 		(when (and threshold (> begin threshold)) (setq exit-flag t))))

+ 34 - 0
testing/lisp/test-org-element.el

@@ -3186,6 +3186,40 @@ Paragraph \\alpha."
 	   (goto-char (point-max))
 	   (org-element-type
 	    (org-element-property :parent (org-element-at-point)))))))
+  ;; Preserve local structures when re-parenting.
+  (should
+   (eq 'table
+       (org-test-with-temp-text
+	   "#+begin_center\nP0\n\n<point>\n\n  P1\n  | a | b |\n| c | d |\n#+end_center"
+	 (let ((org-element-use-cache t))
+	   (save-excursion (search-forward "| c |") (org-element-at-point))
+	   (insert "- item")
+	   (search-forward "| c |")
+	   (beginning-of-line)
+	   (org-element-type
+	    (org-element-property :parent (org-element-at-point)))))))
+  (should-not
+   (eq 'center-block
+       (org-test-with-temp-text
+	   "#+begin_center\nP0\n\n<point>\n\n  P1\n  | a | b |\n#+end_center"
+	 (let ((org-element-use-cache t))
+	   (save-excursion (search-forward "| a |") (org-element-at-point))
+	   (insert "- item")
+	   (search-forward "| a |")
+	   (beginning-of-line)
+	   (org-element-type
+	    (org-element-property :parent (org-element-at-point)))))))
+  ;; When re-parenting, also propagate changes to list structures.
+  (should
+   (= 2
+      (org-test-with-temp-text "\n  Para\n  - item<point>"
+	(let ((org-element-use-cache t))
+	  (org-element-at-point)
+	  (goto-char (point-min))
+	  (insert "- Top\n")
+	  (search-forward "- item")
+	  (beginning-of-line)
+	  (length (org-element-property :structure (org-element-at-point)))))))
   ;; Modifying the last line of an element alters the element below.
   (should
    (org-test-with-temp-text "para1\n\npara2"