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

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

[elpa] externals/org-transclusion 43c478c6ec 1/2: fix: heuristics to ide


From: ELPA Syncer
Subject: [elpa] externals/org-transclusion 43c478c6ec 1/2: fix: heuristics to identify & break infinite loop on save
Date: Wed, 10 May 2023 17:59:38 -0400 (EDT)

branch: externals/org-transclusion
commit 43c478c6ec9e8a9f713baa3736f5e9bc4e72c8ca
Author: Noboru Ota <me@nobiot.com>
Commit: Noboru Ota <me@nobiot.com>

    fix: heuristics to identify & break infinite loop on save
    
    Reported in GitHub issues #109 #177.
    
    I cannot reproduce the issue myself so far. I am put in place (1) small
    preventive measure and (2) heuristics to defect and break the infinite
    loop on save-buffer.
    
    (1) Org-transclusion (OT) tries not to save the transcluded buffer
    content and instead save only the #+transclude keyword line to the file.
    To achieve this, OT uses 'before-' and 'after-save-hook' to remove-all
    the transclusions and then add-all them. This operation relies on the
    returned value of the point from 'org-transclusion-remove' function. In
    this commit, the point (integer) is changed to marker. This way, any
    arbitrary buffer change between these remove-all and add-all processes
    can have less impact on the moving points of reference -- makers
    automatically move to adopt to the new buffer state. I suspect something
    like 'whitespace-cleanup` put in 'before-save-buffer' might dislocate
    the positions in some situations. This preventive measure hopefully
    preempt the issues.
    
    (2) The heuristics is simple but should work if there is an unexpected
    number loop happens. Since it is simply compare the length of a list,
    and the 'dolist' loops for the same list, logically this should be
    redundant; however, since the infinite loop itself to me is anomaly,
    this heuristics might catch the issue and break the loop.
    
    As you can see, both attempts are not based on causal analysis but rather
    "stabbing in the dark" heuristics.
---
 org-transclusion.el | 42 ++++++++++++++++++++++++------------------
 1 file changed, 24 insertions(+), 18 deletions(-)

diff --git a/org-transclusion.el b/org-transclusion.el
index c039d0ae48..ede369662c 100644
--- a/org-transclusion.el
+++ b/org-transclusion.el
@@ -17,7 +17,7 @@
 
 ;; Author:        Noboru Ota <me@nobiot.com>
 ;; Created:       10 October 2020
-;; Last modified: 09 May 2023
+;; Last modified: 10 May 2023
 
 ;; URL: https://github.com/nobiot/org-transclusion
 ;; Keywords: org-mode, transclusion, writing
@@ -528,7 +528,7 @@ When success, return the beginning point of the keyword 
re-inserted."
             (when mkr-at-beg (move-marker mkr-at-beg beg))
             ;; Go back to the beginning of the inserted keyword line
             (goto-char beg))
-          beg))
+          (move-marker (make-marker) beg)))
     (message "Nothing done. No transclusion exists here.") nil))
 
 (defun org-transclusion-detach ()
@@ -558,16 +558,16 @@ function to work only on the narrowed region you are in, 
leaving
 the rest of the buffer unchanged."
   (interactive "P")
   (save-restriction
-    (let ((marker (move-marker (make-marker) (point)))
-          match point list)
+    (let ((current-marker (move-marker (make-marker) (point)))
+          match removed-marker list)
       (unless narrowed (widen))
       (goto-char (point-min))
       (while (setq match (text-property-search-forward 'org-transclusion-type))
         (goto-char (prop-match-beginning match))
-        (setq point (org-transclusion-remove))
-        (when point (push point list)))
-      (goto-char marker)
-      (move-marker marker nil) ; point nowhere for GC
+        (setq removed-marker (org-transclusion-remove))
+        (when removed-marker (push removed-marker list)))
+      (goto-char current-marker)
+      (move-marker current-marker nil) ; point nowhere for GC
       list)))
 
 (defun org-transclusion-refresh (&optional detach)
@@ -735,18 +735,24 @@ set in `before-save-hook'.  It also move the point back to
       (progn
         ;; Assume the list is in descending order.
         ;; pop and do from the bottom of buffer
-        (dolist (p org-transclusion-remember-transclusions)
-          (save-excursion
-            (goto-char p)
-            (org-transclusion-add)))
-        ;; After save and adding all transclusions, the modified flag should be
-        ;; set to nil
-        (restore-buffer-modified-p nil)
-        (when org-transclusion-remember-point
-          (goto-char org-transclusion-remember-point))
+        (let ((do-length (length org-transclusion-remember-transclusions))
+              (do-count 0))
+          (dolist (p org-transclusion-remember-transclusions)
+            (save-excursion
+              (goto-char p)
+              (org-transclusion-add)
+              (move-marker p nil)
+              (setq do-count (1+ do-count))
+              (when (> do-count do-length)
+                (error "org-transclusion: Aborting. You may be in an infinite 
loop"))))
+          ;; After save and adding all transclusions, the modified flag should 
be
+          ;; set to nil
+          (restore-buffer-modified-p nil)
+          (when org-transclusion-remember-point
+            (goto-char org-transclusion-remember-point))))
     (progn
       (setq org-transclusion-remember-point nil)
-      (setq org-transclusion-remember-transclusions nil)))))
+      (setq org-transclusion-remember-transclusions nil))))
 
 (defun org-transclusion-before-kill ()
   "Remove transclusions before `kill-buffer' or `kill-emacs'.



reply via email to

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