[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] externals/embark d320612d1d 2/3: Implement a general Org target f
From: |
ELPA Syncer |
Subject: |
[elpa] externals/embark d320612d1d 2/3: Implement a general Org target finder |
Date: |
Fri, 6 May 2022 19:57:30 -0400 (EDT) |
branch: externals/embark
commit d320612d1dabfeeb4499b69bcfc2af934acf6cdc
Author: Omar Antolín <omar.antolin@gmail.com>
Commit: Omar Antolín <omar.antolin@gmail.com>
Implement a general Org target finder
This replaces the link and table-cell target finders.
The functionality of the old link target finder is now implemented via
a transformer.
I could let it recognize EVERYTHING, but I think it's probably wisest
to only recognize types for which we have actions, and maybe a few
cases of types with no actions but for which we want w, DEL and i.
---
embark-org.el | 152 +++++++++++++++++++++++++++++++++++++++++++---------------
1 file changed, 114 insertions(+), 38 deletions(-)
diff --git a/embark-org.el b/embark-org.el
index 2f808cbe25..2055414c61 100644
--- a/embark-org.el
+++ b/embark-org.el
@@ -32,17 +32,94 @@
(require 'embark)
(require 'org)
-;;; Tables
-
-;; We define both cell and table targets
+;;; Basic target finder for Org
+
+;; There are very many org element and objects types, we'll only
+;; recognize those for which there are specific actions we can put in
+;; a keymap, or for even if there aren't any specific actions, if it's
+;; import to be able to kill, delete or duplicate (embark-insert) them
+;; conveniently. I'll start conservatively and we can add more later
+
+(defconst embark-org--types
+ '(
+ babel-call
+ ;; bold
+ ;; center-block
+ ;; citation
+ ;; citation-reference
+ ;; clock
+ ;; code
+ ;; comment
+ ;; comment-block
+ ;; diary-sexp
+ ;; drawer
+ ;; dynamic-block
+ ;; entity
+ ;; example-block
+ ;; export-block
+ ;; export-snippet
+ ;; fixed-width
+ footnote-definition
+ footnote-reference
+ ;; headline ; the bounds include the entire subtree!
+ ;; horizontal-rule
+ ;; inline-babel-call
+ ;; inline-src-block
+ ;; inlinetask
+ ;; italic
+ item
+ ;; keyword
+ ;; latex-environment
+ ;; latex-fragment
+ ;; line-break
+ link
+ ;; macro
+ ;; node-property
+ ;; paragraph ; the existing general support seems fine
+ plain-list
+ ;; planning
+ ;; property-drawer
+ ;; quote-block
+ ;; radio-target
+ ;; section
+ ;; special-block
+ src-block
+ ;; statistics-cookie
+ ;; strike-through
+ ;; subscript
+ ;; superscript
+ ;; table ; supported via a specific target finder
+ table-cell
+ ;; table-row ; we'll put row & column actions in the cell map
+ ;; target ; I think there are no useful actions for radio targets
+ timestamp
+ ;; underline
+ ;; verbatim
+ ;; verse-block
+ )
+ "Supported Org object and element types")
+
+(defun embark-org-target-element-context ()
+ "Target the smallest Org element or object around point."
+ (when-let (((derived-mode-p 'org-mode))
+ (element (org-element-context))
+ ((memq (car element) embark-org--types))
+ (begin (org-element-property :begin element))
+ (end (org-element-property :end element))
+ (target (buffer-substring begin end)))
+ ;; Adjust table-cell to exclude final |. (Why is that there?)
+ ;; Note: We are not doing this is an embark transformer because we
+ ;; want to adjust the bounds too.
+ ;; TODO? If more adjustments like this become necessary, add a
+ ;; nice mechanism for doing them.
+ (when (and (eq (car element) 'table-cell) (string-suffix-p "|" target))
+ (setq target (string-trim (string-remove-suffix "|" target))
+ end (1- end)))
+ `(,(intern (format "org-%s" (car element))) ,target ,begin . ,end)))
+
+(add-to-list 'embark-target-finders 'embark-org-target-element-context)
-(defun embark-org-target-cell ()
- "Target contents of Org table cell at point."
- (when (and (derived-mode-p 'org-mode) (org-at-table-p))
- `(org-table-cell
- ,(save-excursion (string-trim (org-table-get-field)))
- . (,(save-excursion (skip-chars-backward "^|") (point))
- . ,(save-excursion (skip-chars-forward "^|") (point))))))
+;;; Tables
(defun embark-org-target-table ()
"Target entire Org table at point."
@@ -79,10 +156,11 @@
("i" org-table-iterate)
("e" org-table-export))
-(add-to-list 'embark-target-finders #'embark-org-target-table)
+(push 'embark-org-target-table
+ (cdr (memq 'embark-org-target-element-context embark-target-finders)))
+
(add-to-list 'embark-keymap-alist '(org-table . embark-org-table-map))
-(add-to-list 'embark-target-finders #'embark-org-target-cell)
(add-to-list 'embark-keymap-alist '(org-table-cell .
embark-org-table-cell-map))
;;; Links
@@ -128,32 +206,30 @@
;; slightly more complex design allows both whole-link and inner
;; target actions to work without cycling.
-(defun embark-org-target-link ()
- "Target destination of Org link."
- (when (and (derived-mode-p 'org-mode 'org-agenda-mode)
- (org-in-regexp org-link-any-re))
- (let ((target (or (match-string-no-properties 2)
- (match-string-no-properties 0))))
- (append
- (cond
- ((string-prefix-p "http" target)
- (list 'org-url-link target))
- ((string-prefix-p "mailto:" target)
- (list 'org-email-link (string-remove-prefix "mailto:" target)))
- ((string-prefix-p "file:" target)
- (list 'org-file-link
- (replace-regexp-in-string
- "::.*" "" (string-remove-prefix "file:" target))))
- ((string-match-p "^[./]" target)
- (list 'org-file-link (abbreviate-file-name (expand-file-name
target))))
- ((string-prefix-p "elisp:(" target)
- (list 'org-expression-link (string-remove-prefix "elisp:" target)))
- ((string-prefix-p "elisp:" target)
- (list 'command (string-remove-prefix "elisp:" target)))
- (t (list 'org-link target)))
- (cons (match-beginning 0) (match-end 0))))))
-
-(add-to-list 'embark-target-finders #'embark-org-target-link)
+(defun embark-org--refine-link-type (_type target)
+ "Refine link type if we have more specific actions available."
+ (when (string-match org-link-any-re target)
+ (let ((target (or (match-string-no-properties 2 target)
+ (match-string-no-properties 0 target))))
+ (cond
+ ((string-prefix-p "http" target)
+ (cons 'org-url-link target))
+ ((string-prefix-p "mailto:" target)
+ (cons 'org-email-link (string-remove-prefix "mailto:" target)))
+ ((string-prefix-p "file:" target)
+ (cons 'org-file-link
+ (replace-regexp-in-string
+ "::.*" "" (string-remove-prefix "file:" target))))
+ ((string-match-p "^[./]" target)
+ (cons 'org-file-link (abbreviate-file-name (expand-file-name target))))
+ ((string-prefix-p "elisp:(" target)
+ (cons 'org-expression-link (string-remove-prefix "elisp:" target)))
+ ((string-prefix-p "elisp:" target)
+ (cons 'command (string-remove-prefix "elisp:" target)))
+ (t (cons 'org-link target))))))
+
+(add-to-list 'embark-transformer-alist
+ '(org-link . embark-org--refine-link-type))
(defmacro embark-org-define-link-copier (name formula description)
"Define a command that copies the Org link at point according to FORMULA.