branch: externals/org-transclusion
commit 0eb2b01d1cc192a4690b749b587669a8baef2708
Author: Noboru Ota <[email protected]>
Commit: Noboru Ota <[email protected]>
feat: add org-transient
---
org-transclusion-transient.el | 135 ++++++++++++++++++++++++++++++++++++++++++
org-transclusion.el | 2 +-
2 files changed, 136 insertions(+), 1 deletion(-)
diff --git a/org-transclusion-transient.el b/org-transclusion-transient.el
new file mode 100644
index 0000000000..971807ff43
--- /dev/null
+++ b/org-transclusion-transient.el
@@ -0,0 +1,135 @@
+;; -*- lexical-binding: t; -*-
+
+;; https://github.com/nobiot/org-transclusion/issues/169
+
+(require 'org-transclusion)
+
+;; Utilities
+
+(defmacro hydra-org-transclusion--detect-transclude-at-point-wrapper (body)
+ `(let ((line-text (buffer-substring-no-properties
+ (line-beginning-position) (line-end-position)))
+ (position (point))
+ (end-of-line (line-end-position)))
+ (if (string-match-p "#\\+transclude:" line-text)
+ (save-excursion
+ (unless (eq position end-of-line) (end-of-line))
+ (insert " ")
+ ,body
+ (pulse-momentary-highlight-region end-of-line (line-end-position)
+ 'pulse-highlight-start-face))
+ (user-error "You'r not on #+transclude: [[link]] line."))))
+
+(defun org-transclusion--transient-read-level (&rest _)
+ "Read a string from the minibuffer, restricted to the range 1 to 9 or an
empty value."
+ (cl-loop for result =
+ (read-string "Enter org-transclusion content headline\
+level (1-9) or leave empty: ")
+ if (or (string= result "")
+ (string-match-p "^[1-9]$" result))
+ return result
+ else do (progn
+ (message "Invalid input. Number 1-9 or leave empty")
+ (sit-for 1))))
+
+(defun org-transclusion-insert-from-link ()
+ (interactive)
+ (and-let* ((link-elem-at-pt
+ (or (org-element-lineage (org-element-context) 'link t) ;
at-point
+ ;; if not at-point, find the first one in the current line
+ (save-excursion
+ (beginning-of-line)
+ (re-search-forward org-link-bracket-re (line-end-position)
t)
+ (org-element-lineage (org-element-context) 'link t))))
+ (beg (org-element-begin link-elem-at-pt))
+ (end (org-element-end link-elem-at-pt))
+ (link-string (buffer-substring beg end)))
+ (beginning-of-line)
+ (open-line 1)
+ (insert (format "#+transclude: %s" link-string))
+ (beginning-of-line)
+ (pulse-momentary-highlight-region beg (line-end-position)
'pulse-highlight-start-face)))
+
+(transient-define-prefix org-transclusion--buffer-transient ()
+ "Prefix that waves at the user"
+ [[:description "Add/Remove"
+ ("a" "Add at point" org-transclusion-add)
+ ("A" "Add all in buffer" org-transclusion-add-all)
+ ("R" "Remove all in buffer" org-transclusion-remove-all)]
+ [:description "Options for #+TRANSCLUDE keyword"
+ (:info "Select options. Keep adding")
+ ("i" "insert from link at point or current line"
+ org-transclusion-transient--insert
+ :inapt-if org-transclusion-at-keyword-p)
+ ("l" "level" org-transclusion-transient--level
+ :inapt-if-not org-transclusion-at-keyword-p)
+ ("o" "only-contents"
org-transclusion-transient--only-contents
+ :inapt-if-not org-transclusion-at-keyword-p)
+ ("ex" "exclude-elements"
+ org-transclusion-transient--exclude-elements
+ :inapt-if-not org-transclusion-at-keyword-p)
+ ("el" "expand-links" org-transclusion-transient--expand-links
+ :inapt-if-not org-transclusion-at-keyword-p)]]
+ [:description ""
+ (:info ".")])
+
+(transient-define-prefix org-transclusion--at-point-transient ()
+ "Prefix that waves at the user"
+ [:description
+ "Operation on Transclusion at Point"
+ [:description "Remove"
+ ("r" "Remove at point" org-transclusion-remove)
+ ("d" "Detach at point" org-transclusion-detach)
+ ("R" "Remove all in buffer" org-transclusion-remove-all)]
+ [:description "Other at-point functions"
+ ("P" "Promote" org-transclusion-promote-subtree)
+ ("D" "Demote" org-transclusion-demote-subtree)
+ ("o" "Open the source buffer" org-transclusion-open-source)
+ ("O" "Move to the source buffer"
org-transclusion-move-to-source)]]
+ [:description ""
+ (:info ".")])
+
+(transient-define-suffix org-transclusion-transient--insert ()
+ :transient 'transient--do-return
+ (interactive)
+ (org-transclusion-insert-from-link)
+ (org-transclusion--buffer-transient))
+
+(transient-define-suffix org-transclusion-transient--level ()
+ :transient 'transient--do-stay
+ (interactive)
+ (let ((level-string (org-transclusion--transient-read-level)))
+ (hydra-org-transclusion--detect-transclude-at-point-wrapper
+ (insert (if (string-empty-p level-string)
+ ":level"
+ (format ":level %s" level-string))))))
+
+(transient-define-suffix org-transclusion-transient--only-contents ()
+ :transient 'transient--do-stay
+ (interactive)
+ (hydra-org-transclusion--detect-transclude-at-point-wrapper
+ (insert ":only-contents")))
+
+(transient-define-suffix org-transclusion-transient--expand-links ()
+ :transient 'transient--do-stay
+ (interactive)
+ (hydra-org-transclusion--detect-transclude-at-point-wrapper
+ (insert ":expand-links")))
+
+(transient-define-suffix org-transclusion-transient--exclude-elements ()
+ :transient 'transient--do-stay
+ (interactive)
+ (and-let* ((list-elements (completing-read-multiple
+ "Select elements to exclude: "
+ org-element-all-elements))
+ (elements-string (mapconcat #'identity list-elements "\s")))
+ (hydra-org-transclusion--detect-transclude-at-point-wrapper
+ (insert (format ":exclude-elements %S" elements-string)))))
+
+(defun org-transclusion-transient-menu ()
+ (interactive)
+ (let ((org-transclusion-buffer (current-buffer)))
+ (if (org-transclusion-within-transclusion-p)
+ (org-transclusion--at-point-transient)
+ (org-transclusion--buffer-transient))))
+
diff --git a/org-transclusion.el b/org-transclusion.el
index 1b69d02be7..30c0c46bbf 100644
--- a/org-transclusion.el
+++ b/org-transclusion.el
@@ -381,7 +381,7 @@ transclusion keyword."
(interactive "P")
(let* ((context (org-element-lineage
- (org-element-context)'(link) t))
+ (org-element-context) '(link) t))
(auto-transclude-p (if (or (not arg) (numberp arg))
org-transclusion-mode
;; if `universal-argument' is passed,