branch: externals/org-transclusion
commit 11462931077568b8f4fe30bd2d47a1dcb508eaf0
Merge: ed141838d0 8317ec94fa
Author: nobiot <m...@nobiot.com>
Commit: GitHub <nore...@github.com>

    Merge pull request #157 from devcarbon-com/feature--things-at-point
    
    Feature: select end via n things at point.
---
 org-transclusion-src-lines.el | 72 +++++++++++++++++++++++++++++++------------
 org-transclusion.el           | 37 +++++++++++++++-------
 2 files changed, 79 insertions(+), 30 deletions(-)

diff --git a/org-transclusion-src-lines.el b/org-transclusion-src-lines.el
index b0aaafdc8d..97fdbf3583 100644
--- a/org-transclusion-src-lines.el
+++ b/org-transclusion-src-lines.el
@@ -32,6 +32,8 @@
 (declare-function org-transclusion-org-file-p
                   "org-transclusion")
 
+(declare-function org-transclusion-keyword-value-thing-at-point
+                  "org-transclusion")
 ;;;; Setting up the extension
 
 ;; Add a new transclusion type
@@ -46,6 +48,8 @@
           #'org-transclusion-keyword-value-rest)
 (add-hook 'org-transclusion-keyword-value-functions
           #'org-transclusion-keyword-value-end)
+(add-hook 'org-transclusion-keyword-value-functions
+          #'org-transclusion-keyword-value-thing-at-point)
 ;; plist back to string
 (add-hook 'org-transclusion-keyword-plist-to-string-functions
           #'org-transclusion-keyword-plist-to-string-src-lines)
@@ -62,6 +66,22 @@
 
 ;;; Functions
 
+(defun org-transclusion--bounds-of-n-things-at-point (thing count)
+  "Return the bounds of COUNT THING (s) -at-point."
+  (save-excursion
+    (let ((bounds (bounds-of-thing-at-point thing)))
+      (when bounds
+        (push-mark (car bounds) t t)
+        (goto-char (cdr bounds))
+        (while (and (> count 1) bounds)
+          (setq bounds (bounds-of-thing-at-point thing))
+          (when bounds
+            (if (> count 1)
+                (forward-thing thing)
+              (goto-char (cdr bounds)))
+            (setq count (1- count))))
+        (car (region-bounds))))))
+
 (defun org-transclusion-add-src-lines (link plist)
   "Return a list for non-Org text and source file.
 Determine add function based on LINK and PLIST.
@@ -107,7 +127,9 @@ it means from line 10 to the end of file."
          (type (org-element-property :type link))
          (entry-pos) (buf)
          (lines (plist-get plist :lines))
-         (end-search-op (plist-get plist :end)))
+         (end-search-op (plist-get plist :end))
+         (thing-at-point (plist-get plist :thing-at-point))
+         (thing-at-point (when thing-at-point (make-symbol thing-at-point))))
     (if (not (string= type "id")) (setq buf (find-file-noselect path))
       (let ((filename-pos (org-id-find path)))
         (setq buf (find-file-noselect (car filename-pos)))
@@ -125,15 +147,23 @@ it means from line 10 to the end of file."
                                    ;; ::/regex/ or ::number is used
                                    (if (org-link-search search-option)
                                        (line-beginning-position))))))
-                             ((point-min))))
-                (end-pos (when end-search-op
-                           (save-excursion
-                             (ignore-errors
-                               ;; FIXME `org-link-search' does not
-                               ;; return postion when either ::/regex/
-                               ;; or ::number is used
-                               (when (org-link-search end-search-op)
-                                 (line-beginning-position))))))
+                            ((point-min))))
+                (bounds (when thing-at-point
+                          (let ((count (if end-search-op
+                                           (string-to-number end-search-op) 
1)))
+                            (save-excursion
+                              (goto-char start-pos)
+                              (back-to-indentation)
+                              (org-transclusion--bounds-of-n-things-at-point 
thing-at-point count)))))
+                (end-pos (cond ((when thing-at-point (cdr bounds)))
+                               ((when end-search-op
+                                  (save-excursion
+                                    (ignore-errors
+                                      ;; FIXME `org-link-search' does not
+                                      ;; return postion when either ::/regex/
+                                      ;; or ::number is used
+                                      (when (org-link-search end-search-op)
+                                        (line-beginning-position))))))))
                 (range (when lines (split-string lines "-")))
                 (lbeg (if range (string-to-number (car range))
                         0))
@@ -148,7 +178,8 @@ it means from line 10 to the end of file."
                 ;;; This `cond' means :end prop has priority over the end
                 ;;; position of the range. They don't mix.
                 (end (cond
-                      ((when (and end-pos (> end-pos beg))
+                      ((when thing-at-point end-pos)
+                       (when (and end-pos (> end-pos beg))
                          end-pos))
                       ((if (zerop lend) (point-max)
                          (goto-char start-pos)
@@ -175,12 +206,13 @@ for the range works."
     (when src-lang
       (setq payload
             (plist-put payload :src-content
-                       (concat
-                        (format "#+begin_src %s" src-lang)
-                        (when rest (format " %s" rest))
-                        "\n"
-                        (plist-get payload :src-content)
-                        "#+end_src\n"))))
+                       (let ((src-content (plist-get payload :src-content)))
+                         (concat
+                          (format "#+begin_src %s" src-lang)
+                          (when rest (format " %s" rest))
+                          "\n"
+                          (org-transclusion--ensure-newline src-content)
+                          "#+end_src\n")))))
     ;; Return the payload either modified or unmodified
     payload))
 
@@ -230,12 +262,14 @@ abnormal hook
   (let ((lines (plist-get plist :lines))
         (src (plist-get plist :src))
         (rest (plist-get plist :rest))
-        (end (plist-get plist :end)))
+        (end (plist-get plist :end))
+        (thing-at-point (plist-get plist :thing-at-point)))
     (concat
      (when lines (format ":lines %s" lines))
      (when src (format " :src %s" src))
      (when rest (format " :rest \"%s\"" rest))
-     (when end (format " :end \"%s\"" end)))))
+     (when end (format " :end \"%s\"" end))
+     (when thing-at-point (format " :thing-at-point %s" thing-at-point)))))
 
 (defun org-transclusion-src-lines-p (type)
   "Return non-nil when TYPE is \"src\" or \"lines\".
diff --git a/org-transclusion.el b/org-transclusion.el
index 2989ff098f..9ceaaa004f 100644
--- a/org-transclusion.el
+++ b/org-transclusion.el
@@ -201,6 +201,7 @@ that consists of the following properties:
 
 (defvar org-transclusion-keyword-value-functions
   '(org-transclusion-keyword-value-link
+    org-transclusion-keyword-value-thing-at-point
     org-transclusion-keyword-value-level
     org-transclusion-keyword-value-disable-auto
     org-transclusion-keyword-value-only-contents
@@ -799,6 +800,15 @@ It is meant to be used by
     (user-error "Error.  Link in #+transclude is mandatory at %d" (point))
     nil))
 
+(defun org-transclusion-keyword-value-thing-at-point (string)
+  "It is a utility function used converting a keyword STRING to plist.
+It is meant to be used by `org-transclusion-get-string-to-plist'.
+It needs to be set in `org-transclusion-get-keyword-values-hook'.
+Double qutations are optional :thing-at-point \"sexp\".  The regex should
+match any valid elisp symbol (but please don't quote it)."
+  (when (string-match ":thing-at-point \\([[:alnum:][:punct:]]+\\)" string)
+    (list :thing-at-point (org-strip-quotes (match-string 1 string)))))
+
 (defun org-transclusion-keyword-value-disable-auto (string)
   "It is a utility function used converting a keyword STRING to plist.
 It is meant to be used by `org-transclusion-get-string-to-plist'.
@@ -942,6 +952,11 @@ Return nil if not found."
 ;;-----------------------------------------------------------------------------
 ;;;; Functions for inserting content
 
+(defun org-transclusion--ensure-newline (str)
+  (if (not (string-suffix-p "\n" str))
+      (concat str "\n")
+    str))
+
 (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.
@@ -971,17 +986,17 @@ based on the following arguments:
          (end-mkr)
          (ov-src (text-clone-make-overlay sbeg send sbuf)) ;; source-buffer 
overlay
          (tc-pair ov-src)
-         (content content))
+         (content (org-transclusion--ensure-newline content)))
     (when (org-transclusion-type-is-org type)
-        (with-temp-buffer
-          ;; This temp buffer needs to be in Org Mode
-          ;; Otherwise, subtree won't be recognized as a Org subtree
-          (delay-mode-hooks (org-mode))
-          (insert content)
-          (org-with-point-at 1
-            (let* ((to-level (plist-get keyword-values :level))
-                   (level (org-transclusion-content-highest-org-headline))
-                   (diff (when (and level to-level) (- level to-level))))
+      (with-temp-buffer
+        ;; This temp buffer needs to be in Org Mode
+        ;; Otherwise, subtree won't be recognized as a Org subtree
+        (delay-mode-hooks (org-mode))
+        (insert content)
+        (org-with-point-at 1
+          (let* ((to-level (plist-get keyword-values :level))
+                 (level (org-transclusion-content-highest-org-headline))
+                 (diff (when (and level to-level) (- level to-level))))
             (when diff
               (cond ((< diff 0) ; demote
                      (org-map-entries (lambda ()
@@ -991,7 +1006,7 @@ based on the following arguments:
                      (org-map-entries (lambda ()
                                         (dotimes (_ diff)
                                           (org-do-promote))))))))
-            (setq content (buffer-string)))))
+          (setq content (buffer-string)))))
     (insert
      (run-hook-with-args-until-success
       'org-transclusion-content-format-functions

Reply via email to