Commit 7c6d8912b4fc

Vincent Demeester <vincent@sbr.pm>
2026-02-13 10:25:30
fix(org-todos): revert stale buffers before refile
Refile was failing because Emacs buffers were stale (not matching disk). Added revert-buffer calls before searching for headings and sections. Also removed condition-case in org-batch-refile-entry so errors propagate with useful messages instead of returning a generic failure.
1 parent 3f878a9
Changed files (2)
dots/config/emacs/site-lisp/org-batch-functions.el
@@ -1098,44 +1098,43 @@ Returns list of sections with their positions for refiling."
 
 (defun org-batch-refile-entry (source-file source-heading target-file target-section)
   "Refile entry with SOURCE-HEADING from SOURCE-FILE to TARGET-SECTION in TARGET-FILE.
-Returns t on success, nil on failure."
-  (condition-case err
-      (with-current-buffer (find-file-noselect source-file)
-        ;; Find the source heading
-        (goto-char (point-min))
-        (unless (re-search-forward 
-                 (concat "^\\*+ \\(?:TODO\\|NEXT\\|STRT\\|WAIT\\|DONE\\|CANX\\)?\\s-*"
-                         (regexp-quote source-heading))
-                 nil t)
-          (error "Heading not found: %s" source-heading))
-        
-        (goto-char (line-beginning-position))
-        
-        ;; Find target location in target file
-        (let* ((target-buf (find-file-noselect target-file))
-               (target-pos (with-current-buffer target-buf
-                            (goto-char (point-min))
-                            (when (re-search-forward 
-                                   (concat "^\\* " (regexp-quote target-section))
-                                   nil t)
-                              (line-end-position)))))
-          
-          (unless target-pos
-            (error "Target section not found: %s" target-section))
-          
-          ;; Perform the refile using org-refile
-          (org-refile nil nil 
-                     (list target-section target-file nil target-pos))
-          
-          ;; Save both buffers
-          (save-buffer)
-          (with-current-buffer target-buf
-            (save-buffer))
-          
-          t))
-    (error
-     (message "Refile failed: %s" (error-message-string err))
-     nil)))
+Returns t on success, signals error on failure."
+  (with-current-buffer (find-file-noselect source-file)
+    ;; Ensure buffer is up-to-date with disk
+    (revert-buffer t t)
+    ;; Find the source heading (match with or without TODO keyword)
+    (goto-char (point-min))
+    (unless (re-search-forward
+             (concat "^\\*+ \\(?:TODO\\|NEXT\\|STRT\\|WAIT\\|DONE\\|CANX\\)?\\s-*"
+                     (regexp-quote source-heading))
+             nil t)
+      (error "Heading not found in %s: %s" source-file source-heading))
+
+    (goto-char (line-beginning-position))
+
+    ;; Find target location in target file
+    (let* ((target-buf (find-file-noselect target-file))
+           (target-pos (with-current-buffer target-buf
+                        (revert-buffer t t)
+                        (goto-char (point-min))
+                        (when (re-search-forward
+                               (concat "^\\* " (regexp-quote target-section))
+                               nil t)
+                          (point)))))
+
+      (unless target-pos
+        (error "Target section not found in %s: %s" target-file target-section))
+
+      ;; Perform the refile using org-refile
+      (org-refile nil nil
+                  (list target-section target-file nil target-pos))
+
+      ;; Save both buffers
+      (save-buffer)
+      (with-current-buffer target-buf
+        (save-buffer))
+
+      t)))
 
 (provide 'org-batch-functions)
 ;;; org-batch-functions.el ends here
dots/config/emacs/site-lisp/pi-org-todos.el
@@ -332,13 +332,13 @@ Returns JSON string."
                  (expand-file-name "~/desktop/org/inbox.org")))
         (tgt (pi/org-todo--get-file target-file)))
     (condition-case err
-        (if (org-batch-refile-entry src source-heading tgt target-section)
-            (pi/org-todo--json-response t 
-              `((heading . ,source-heading)
-                (target . ,target-section)
-                (source-file . ,src)
-                (target-file . ,tgt)))
-          (pi/org-todo--json-response nil nil "Refile operation failed"))
+        (progn
+          (org-batch-refile-entry src source-heading tgt target-section)
+          (pi/org-todo--json-response t 
+            `((heading . ,source-heading)
+              (target . ,target-section)
+              (source-file . ,src)
+              (target-file . ,tgt))))
       (error
        (pi/org-todo--json-response nil nil (error-message-string err))))))