From 4ef7aec7e30771376f3b4e13e7ce65ab88f358fe Mon Sep 17 00:00:00 2001
From: MT <mtekman89@gmail.com>
Date: Tue, 2 May 2023 18:01:05 +0200
Subject: [PATCH 3/6] lisp/ob-tangle.el: Tangle function made aware of remote
 contents

* ob-tangle (org-babel-tangle--parse-comments): Scans a tangled file
for comment entries and populates an alist of plists containing
information about the remote contents of each block in the tangled
file.
(org-babel-tangle): Before tangling an org mode buffer, the tangle
function pre-populates a list of already tangled blocks in the remote
tangle file using `org-babel-tangle--parse-comments'.  If the desired
tangle-sync action given in the header is to "import" (instead of the
"export"/"both"/nil action), then it retrieves the remote contents and
updates the org mode source block instead, before proceeding down the
buffer to the next block.
---
 lisp/ob-tangle.el | 39 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 39 insertions(+)

diff --git a/lisp/ob-tangle.el b/lisp/ob-tangle.el
index bd9948efe..596b4b3eb 100644
--- a/lisp/ob-tangle.el
+++ b/lisp/ob-tangle.el
@@ -261,6 +261,16 @@ matching a regular expression."
                (let ((lspecs (cdr by-fn))
 		     (fnd (file-name-directory file-name))
 		     modes make-dir she-banged lang)
+                 (when (file-exists-p file-name)
+                   ;; Get list of comments in tangled file for potential detangling.
+                   (let ((blocks-in-tfile (cdar (org-babel-tangle--parse-comments
+                                                 file-name target-file))))
+                     ;; Append content boundaries to existing lspecs
+                     (mapc (lambda (lsp)
+                             (let* ((fname (nth 3 lsp))
+                                    (pos-plist (cdr (assoc fname blocks-in-tfile))))
+                               (nconc lsp (list pos-plist))))
+                           lspecs)))
 	         ;; drop source-blocks to file
 	         ;; We avoid append-to-file as it does not work with tramp.
 	         (with-temp-buffer
@@ -699,8 +709,37 @@ requesting a data import and ignores the tangle-sync header."
       (search-forward link-text nil t)
       (org-babel-detangle-single-block))))
 
+
+(defun org-babel-tangle--parse-comments (tangled-file &optional source-file)
+  "Scan TANGLED-FILE for comments, optionally only those stemming from SOURCE-FILE.
+Return an alist of tangled filenames and their blocks, along with
+a plist of their positions."
+  (with-current-buffer (find-file-noselect tangled-file)
     (goto-char (point-min))
+    (let ((comment-links nil)
+          (source-file (and source-file
+                            (expand-file-name source-file))))
       (while (re-search-forward org-link-bracket-re nil t)
+        (let* ((file-link (match-string-no-properties 1))
+               (block-name (match-string-no-properties 2))
+               (block-file (expand-file-name
+                            (progn (string-match "\\`file:\\(.+?\\)::" file-link)
+                                   (match-string-no-properties 1 file-link))))
+               (start-block (progn (forward-line 1) (point)))
+               (end-block (progn
+                            (re-search-forward
+	                     (concat " " (regexp-quote block-name) " ends here") nil t)
+                            (forward-line 0) (forward-char -1) (point))))
+          ;; if source file given, restrict scope to just those blocks.
+          (unless (and source-file (not (string= source-file block-file)))
+            (if (assoc block-file comment-links)
+                (push `(,file-link :name ,block-name :start ,start-block :end ,end-block)
+                      (cdr (assoc block-file comment-links)))
+              (push `(,block-file (,file-link :name ,block-name :start ,start-block :end ,end-block))
+                    comment-links)))))
+      comment-links)))
+
+
 
 (defun org-babel-detangle--block-contents (&optional nearest new-body)
   "Get the contents of the current exported block under cursor, or NEAREST if t.
-- 
2.40.1

