branch: externals/org-transclusion
commit 6cdb148377412b07ff623b269e0bb516ace99d0d
Author: Noboru Ota <[email protected]>
Commit: Noboru Ota <[email protected]>
chg(WIP): Remove org-transclusion-add-payload
This is a beginning of a large refactor for the whole `add` operation.
---
org-transclusion.el | 274 ++++++++++++++++++++++++++++++++++++----------------
1 file changed, 190 insertions(+), 84 deletions(-)
diff --git a/org-transclusion.el b/org-transclusion.el
index f7cf59d524..3d27ef5ebc 100644
--- a/org-transclusion.el
+++ b/org-transclusion.el
@@ -450,12 +450,44 @@ does not support all the elements.
(let* ((keyword-plist (org-transclusion-keyword-string-to-plist))
(link (org-transclusion-wrap-path-to-link
(plist-get keyword-plist :link)))
+ ;; Note 2025-01-03 Retrospectively, PAYLOAD feels redundant now that
+ ;; `org-transclusion-add' is being refactored. For
+ ;; backword-compatibility, I am keeping PAYLOAD.
(payload (run-hook-with-args-until-success
- 'org-transclusion-add-functions link keyword-plist)))
- (if (functionp payload)
- ;; Allow for asynchronous transclusion
- (funcall payload link keyword-plist copy)
- (org-transclusion-add-payload payload link keyword-plist copy)))))
+ 'org-transclusion-add-functions link keyword-plist))
+ (tc-type (plist-get payload :tc-type))
+ (content (plist-get payload :src-content))
+ (keyword-plist (if (org-transclusion-type-is-org tc-type)
+ (plist-put
+ keyword-plist :highest-level
+ (org-transclusion-content-highest-org-headline))
+ keyword-plist))
+ (content
+ (run-hook-with-args-until-success
+ 'org-transclusion-content-format-functions
+ tc-type content keyword-plist)))
+ (if (or (string-empty-p content)
+ (eq content nil))
+ ;; Keep going with program when no content `org-transclusion-add-all'
+ ;; should move to the next transclusion
+ (prog1 nil
+ (message
+ "No content found with \"%s\". Check the link at point %d, line
%d"
+ (org-element-property :raw-link link)
+ (point) (org-current-line)))
+ (pcase-let ((`(,beg . ,end) (org-transclusion-content-insert content)))
+ (when (and beg end)
+ (unless copy
+ (org-transclusion-content-add-text-props-and-overlay
+ payload keyword-plist beg end))
+ (run-hook-with-args 'org-transclusion-after-add-functions
+ beg end)))
+
+ ;; (if (functionp payload)
+ ;; ;; Allow for asynchronous transclusion
+ ;; (funcall payload link keyword-plist copy)
+ ;; (org-transclusion-add-payload payload link keyword-plist copy)
+ ))))
;;;###autoload
(defun org-transclusion-add-all (&optional narrowed)
@@ -961,9 +993,13 @@ hooks in `org-transclusion-add-functions'."
;; Don't ever prompt to create a headline when transcluding.
;; t is a less surprising default than nil - fuzzy search.
(let ((org-link-search-must-match-exact-headline t))
- (org-link-open link)
- ;; In the target buffer temporarily
- (move-marker (make-marker) (point)))))
+ (condition-case nil
+ (progn
+ (org-link-open link)
+ ;; In the target buffer temporarily
+ (move-marker (make-marker) (point)))
+ ;; TODO add more link info
+ (error (message "Cannot open link"))))))
(defun org-transclusion-add-org-id (link plist)
"Return a list for Org-ID LINK object and PLIST.
@@ -1021,7 +1057,7 @@ Return nil if not found."
(org-transclusion-content-org-filtered
nil plist)))))))
-(defun org-transclusion-add-other-file (link plist)
+(defun org-transclusion-add-other-file (link _plist)
"Return a list for non-Org file LINK object and PLIST.
Return nil if not found."
(and-let* (;; (_ (string= "file" (org-element-property :type link)))
@@ -1039,77 +1075,150 @@ Return nil if not found."
;;-----------------------------------------------------------------------------
;;;; Functions for inserting content
-(defun org-transclusion-content-insert (keyword-values type content sbuf sbeg
send copy)
- "Insert CONTENT at point and put source overlay in SBUF.
-Return t when successful.
-
-This function formats CONTENT with using one of the
-`org-transclusion-content-format-functions'; e.g. align a table
-for Org.
-
-This function is intended to be used within
-`org-transclusion-add'. All the arguments should be
-obtained by one of the `org-transclusion-add-functions'.
-
-This function adds text properties required for Org-transclusion
-to the inserted content. It also puts an overlay to an
-appropriate region of the source buffer. They are constructed
-based on the following arguments:
-
-- KEYWORD-VALUES :: Property list of the value of transclusion keyword
-- TYPE :: Transclusion type; e.g. \"org-link\"
-- CONTENT :: Text content of the transclusion source to be inserted
-- SBUF :: Buffer of the transclusion source where CONTENT comes from
-- SBEG :: Begin point of CONTENT in SBUF
-- SEND :: End point of CONTENT in SBUF"
- (let* ((beg (point)) ;; before the text is inserted
- (end) ;; at the end of text content after inserting it
- (id (org-id-uuid))
- (tc-buffer (current-buffer))
- (ov-src (text-clone-make-overlay sbeg send sbuf)) ;; source-buffer
overlay
- (tc-pair ov-src)
- (content content)
- (current-level (or (org-current-level) 0)))
- (insert
- (run-hook-with-args-until-success
- 'org-transclusion-content-format-functions
- type content (plist-get keyword-values :current-indentation)))
- (setq end (point))
- (unless copy
- (add-text-properties
- beg end
- `( local-map ,org-transclusion-map
- read-only t
- front-sticky t
- ;; rear-nonticky seems better for
- ;; src-lines to add "#+result" after C-c
- ;; C-c
- rear-nonsticky t
- org-transclusion-id ,id
- org-transclusion-type ,type
- org-transclusion-pair ,tc-pair
- org-transclusion-orig-keyword ,keyword-values
- ;; TODO Fringe is not supported for terminal
- line-prefix ,(org-transclusion-propertize-transclusion)
- wrap-prefix ,(org-transclusion-propertize-transclusion)))
- ;; Put the transclusion overlay
- (let ((ov-tc (text-clone-make-overlay beg end)))
- (overlay-put ov-tc 'evaporate t)
- (overlay-put ov-tc 'face 'org-transclusion)
- (overlay-put ov-tc 'priority -60))
- ;; Put to the source overlay
- (overlay-put ov-src 'org-transclusion-by id)
- (overlay-put ov-src 'org-transclusion-buffer tc-buffer)
- (overlay-put ov-src 'evaporate t)
- (overlay-put ov-src 'face 'org-transclusion-source)
- (overlay-put ov-src 'line-prefix (org-transclusion-propertize-source))
- (overlay-put ov-src 'wrap-prefix (org-transclusion-propertize-source))
- (overlay-put ov-src 'priority -60)
- ;; TODO this should not be necessary, but it is at the moment
- ;; live-sync-enclosing-element fails without tc-pair on source overlay
- (overlay-put ov-src 'org-transclusion-pair tc-pair))
+(defun org-transclusion-content-insert (content)
+ "Insert CONTENT and return cons cell of BEG and END."
+ (let ((beg (line-beginning-position))
+ end-mkr end)
+ (org-transclusion-with-inhibit-read-only
+ (when (save-excursion
+ (end-of-line) (insert-char ?\n)
+ (insert content)
+ (unless (eobp) (delete-char 1))
+ (setq end-mkr (move-marker (make-marker) (point)))
+ t)
+ ;; `org-transclusion-keyword-remove' checks element at point is a
+ ;; keyword or not
+ (org-transclusion-keyword-remove)
+ (setq end (marker-position end-mkr))))
+ ;; Assume beg and end are non-nil?
+ (when (and beg end)
+ ;; (run-hook-with-args 'org-transclusion-after-add-functions beg end)
+ ;; Point END-MKR to nowhere for garbage collection.
+ (move-marker end-mkr nil)
+ (cons beg end))))
+
+(defun org-transclusion-content-add-text-props-and-overlay (payload
keyword-values beg end)
+ "
+BEG: before the text is inserted
+END: the end of text content after inserting it
+;; - KEYWORD-VALUES :: Property list of the value of transclusion keyword
+;; - TYPE :: Transclusion type; e.g. \"org-link\"
+
+This function assumes that the current point is within the
+current buffer."
+ (and-let* ((id (org-id-uuid))
+ (tc-buffer (current-buffer))
+ (src-beg (plist-get payload :src-beg))
+ (src-end (plist-get payload :src-end))
+ (src-buf (plist-get payload :src-buf))
+ (ov-src (text-clone-make-overlay src-beg src-end src-buf))
+ (tc-pair ov-src)
+ (tc-type (plist-get payload :tc-type)))
+ (add-text-properties
+ beg end
+ `( local-map ,org-transclusion-map
+ read-only t
+ front-sticky t
+ ;; rear-nonticky seems better for
+ ;; src-lines to add "#+result" after C-c
+ ;; C-c
+ rear-nonsticky t
+ org-transclusion-id ,id
+ org-transclusion-type ,tc-type
+ org-transclusion-pair ,tc-pair
+ org-transclusion-orig-keyword ,keyword-values
+ ;; TODO Fringe is not supported for terminal
+ line-prefix ,(org-transclusion-propertize-transclusion)
+ wrap-prefix ,(org-transclusion-propertize-transclusion)))
+ ;; Put the transclusion overlay
+ (let ((ov-tc (text-clone-make-overlay beg end)))
+ (overlay-put ov-tc 'evaporate t)
+ (overlay-put ov-tc 'face 'org-transclusion)
+ (overlay-put ov-tc 'priority -60))
+ ;; Put to the source overlay
+ (overlay-put ov-src 'org-transclusion-by id)
+ (overlay-put ov-src 'org-transclusion-buffer tc-buffer)
+ (overlay-put ov-src 'evaporate t)
+ (overlay-put ov-src 'face 'org-transclusion-source)
+ (overlay-put ov-src 'line-prefix (org-transclusion-propertize-source))
+ (overlay-put ov-src 'wrap-prefix (org-transclusion-propertize-source))
+ (overlay-put ov-src 'priority -60)
+ ;; TODO this should not be necessary, but it is at the moment
+ ;; live-sync-enclosing-element fails without tc-pair on source overlay
+ (overlay-put ov-src 'org-transclusion-pair tc-pair)
+ ;; Return t
t))
+;; (defun org-transclusion-content-insert (keyword-values type content sbuf
sbeg send copy)
+;; "Insert CONTENT at point and put source overlay in SBUF.
+;; Return t when successful.
+
+;; This function formats CONTENT with using one of the
+;; `org-transclusion-content-format-functions'; e.g. align a table
+;; for Org.
+
+;; This function is intended to be used within;; `org-transclusion-add'. All
the arguments should be
+;; obtained by one of the `org-transclusion-add-functions'.
+
+;; This function adds text properties required for Org-transclusion
+;; to the inserted content. It also puts an overlay to an
+;; appropriate region of the source buffer. They are constructed
+;; based on the following arguments:
+
+;; - KEYWORD-VALUES :: Property list of the value of transclusion keyword
+;; - TYPE :: Transclusion type; e.g. \"org-link\"
+;; - CONTENT :: Text content of the transclusion source to be inserted
+;; - SBUF :: Buffer of the transclusion source where CONTENT comes from
+;; - SBEG :: Begin point of CONTENT in SBUF
+;; - SEND :: End point of CONTENT in SBUF"
+;; (let* ((beg (point)) ;; before the text is inserted
+;; (end) ;; at the end of text content after inserting it
+;; (id (org-id-uuid))
+;; (tc-buffer (current-buffer))
+;; (ov-src (text-clone-make-overlay sbeg send sbuf)) ;; source-buffer
overlay
+;; (tc-pair ov-src)
+;; (content content)
+;; (current-level (or (org-current-level) 0)))
+;; (insert
+;; (run-hook-with-args-until-success
+;; 'org-transclusion-content-format-functions
+;; type content (plist-get keyword-values :current-indentation)))
+;; (setq end (point))
+;; (unless copy
+;; (add-text-properties
+;; beg end
+;; `( local-map ,org-transclusion-map
+;; read-only t
+;; front-sticky t
+;; ;; rear-nonticky seems better for
+;; ;; src-lines to add "#+result" after C-c
+;; ;; C-c
+;; rear-nonsticky t
+;; org-transclusion-id ,id
+;; org-transclusion-type ,type
+;; org-transclusion-pair ,tc-pair
+;; org-transclusion-orig-keyword ,keyword-values
+;; ;; TODO Fringe is not supported for terminal
+;; line-prefix ,(org-transclusion-propertize-transclusion)
+;; wrap-prefix ,(org-transclusion-propertize-transclusion)))
+;; ;; Put the transclusion overlay
+;; (let ((ov-tc (text-clone-make-overlay beg end)))
+;; (overlay-put ov-tc 'evaporate t)
+;; (overlay-put ov-tc 'face 'org-transclusion)
+;; (overlay-put ov-tc 'priority -60))
+;; ;; Put to the source overlay
+;; (overlay-put ov-src 'org-transclusion-by id)
+;; (overlay-put ov-src 'org-transclusion-buffer tc-buffer)
+;; (overlay-put ov-src 'evaporate t)
+;; (overlay-put ov-src 'face 'org-transclusion-source)
+;; (overlay-put ov-src 'line-prefix (org-transclusion-propertize-source))
+;; (overlay-put ov-src 'wrap-prefix (org-transclusion-propertize-source))
+;; (overlay-put ov-src 'priority -60)
+;; ;; TODO this should not be necessary, but it is at the moment
+;; ;; live-sync-enclosing-element fails without tc-pair on source overlay
+;; (overlay-put ov-src 'org-transclusion-pair tc-pair))
+;; t))
+
(defun org-transclusion-content-highest-org-headline ()
"Return the highest level as an integer of all the headlines in buffer.
Returns nil if there is no headline. Note that level 1 is the
@@ -1153,7 +1262,7 @@ This function is the default for org-transclusion-type
(TYPE)
;; Return the temp-buffer's string
(buffer-string)))))
-(defun org-transclusion-content-format-org-headlines (_type content
keyword-values)
+(defun org-transclusion-content-format-org-headlines (_type _content
keyword-values)
"Adjust org headline levels for CONTENT.
KEYWORD-VALUES is a plist of transclusion properties. This
function assumes the point is within temp-buffer with `org-mode'
@@ -1166,7 +1275,7 @@ active."
(let* ((raw-to-level (plist-get keyword-values :level))
(to-level (if (and (stringp raw-to-level)
(string= raw-to-level "auto"))
- (1+ current-level)
+ (1+ (org-current-level))
raw-to-level))
;; TODO this function must know about the transclusion-buffer, but
it
;; does not.
@@ -1179,8 +1288,7 @@ active."
(org-do-demote)))))
((> diff 0) ; promote
(org-map-entries (lambda ()
- (dotimes (_ diff)
- (org-do-promote))))))))
+ (dotimes (_ diff) (org-do-promote))))))))
(buffer-string)))
@@ -1323,8 +1431,6 @@ is non-nil."
nil
data))
-;;;;---------------------------------------------------------------------------
-
;;-----------------------------------------------------------------------------
;;; Utility Functions