Browse Source

org-element-cache: Fix transforming keywords to affiliated

* lisp/org-element.el (org-element--cache-for-removal): Consider
preceding keywords to be updated unconditionally.
(org-element-cache-map): Fix infinite loop revealed by the new test.

* testing/lisp/test-org-element.el (test-org-element/cache-affiliated):
New test.
Ihor Radchenko 3 years ago
parent
commit
515ce56d4e
2 changed files with 24 additions and 1 deletions
  1. 10 1
      lisp/org-element.el
  2. 14 0
      testing/lisp/test-org-element.el

+ 10 - 1
lisp/org-element.el

@@ -6694,6 +6694,14 @@ known element in cache (it may start after END)."
 	 (before (car elements))
 	 (after (cdr elements)))
     (if (not before) after
+      ;; If BEFORE is a keyword, it may need to be removed to become
+      ;; an affiliated keyword.
+      (when (eq 'keyword (org-element-type before))
+        (let ((prev before))
+          (while (eq 'keyword (org-element-type prev))
+            (setq before prev
+                  beg (org-element-property :begin prev))
+            (setq prev (org-element--cache-find (1- (org-element-property :begin before)))))))
       (let ((up before)
 	    (robust-flag t))
 	(while up
@@ -7288,7 +7296,8 @@ the cache."
                                         (setq start (max (or start -1)
                                                          (or (org-element-property :begin data) -1)
                                                          (or (org-element-property :begin (element-match-at-point)) -1))))
-                                      (when (>= start to-pos) (cache-walk-abort)))
+                                      (when (>= start to-pos) (cache-walk-abort))
+                                      (when (eq start -1) (setq start nil)))
                                   (cache-walk-abort))))
                       ;; Find expected begin position of an element after
                       ;; DATA.

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

@@ -4128,6 +4128,20 @@ Text
 	    :end (org-element-property :parent (org-element-at-point)))
 	   (+ parent-end 3))))))
 
+(ert-deftest test-org-element/cache-affiliated ()
+  "Test updating affiliated keywords."
+  ;; Inserting a line right after other keywords.
+  (let ((org-element-use-cache t))
+    (org-test-with-temp-text "
+#+caption: test
+#+name: test
+<point>
+line"
+      (org-element-cache-map #'ignore :granularity 'element)
+      (should (eq 'keyword (org-element-type (org-element-at-point))))
+      (insert "#")
+      (should (eq 2 (org-element-property :begin (org-element-at-point)))))))
+
 (ert-deftest test-org-element/cache-table ()
   "Test handling edits in tables."
   ;; Unindented second row of the table should not be re-parented by