文档
不同的 Org元素 具有不同的执行器,‘org-exec’ 将根
据所指元素的类型,将控制流和 ARGS 参数转交给其他
执行器。
LINK 可以是一条 Org链接,还可以是用于触发命令的
symbol.
LINK 是 Org链接 时,支持的类型包括:
string, org-element-link, vector. 即:
(org-exec "[[id:target]]" ...)
(org-exec (org-element-link-parser) ...)
(org-exec [[id:target]] ...)
当 LINK 为 nil 时,执行当前位置的元素。
LINK 是 symbol 时,执行 ‘org-exec’ 内部命令。
支持的命令包括:
'set-executor
(org-exec 'set-executor
ORG-ELEMENT-TYPE FUNCTION)
FUNCTION 将会被 (apply FUNCTION ARGS).
当 EXECUTOR 为 nil 时, ‘org-exec’ 会使用内置
的执行器执行 `link' 所指元素,非 nil 时用
EXECUTOR 执行。调用方式为:
(apply executor args)
特性
FEAT
<<@([[id:F:exec-default]])>>
<<@([[id:F:exec-src-block]])>>
<<@([[id:F:exec-subtree]])>>
exec-src-block
D:exec-src-block
KEYWORD 对应 Header Arguments
SYMBOL 对应 Variables.
如: (exec-src-block :eval "yes" 'a 10).
exec-src-block
;; args 应为一对一对的参数, 如果入参长度为奇数
;; 我们直接 drop 掉最后一个参数。
(when (= (% (length args) 2) 1)
(setq args (seq-subseq args 0 -1)))
(let* ((params "") header-args variables)
(dolist (kv (seq-partition args 2))
(cond
((keywordp (car kv))
(push (format
"%S %S" (car kv) (cadr kv))
header-args))
((push (format
"%S=%S" (car kv)
(cond
((symbolp (cadr kv))
`(identity ',(cadr kv)))
(t (cadr kv))))
variables))))
(when header-args
(setq params
(concat params
(string-join
(nreverse header-args)
" "))))
(when variables
(setq params
(concat params
" :var "
(string-join
(nreverse variables)
" "))))
(setq params (string-trim params))
(message "[org-exec]params: %S" params)
(org-babel-execute-src-block
nil nil
;; 因为 `org-babel-execute-src-block' 开头
;; 调用 `org-babel-get-src-block-info' 时
;; 就已经 eval 了 header args, 所以我们在这里
;; 也直接对输入 header args 求值。
(org-babel-parse-header-arguments params)))
exec-subtree
exec-subtree
;; 对于 headline 类型的 target, 我们提供额外的执
;; 行配置:
;;
;; ORG-EXE-DEPENDS 及 ORG-EXE-EXECUTOR.
;;
;; 前者会作为 当前target 的依赖先于 target执行;
;; 后者作为 当前target 的执行器,如有提供,决定
;; 如何执行 target.
(![&rest args]
;; 如 target 有依赖,先执行其依赖。
(let* ((title (org-entry-get nil "ITEM"))
(depends
(org-entry-get nil "ORG-EXE-DEPENDS"))
(depends
(when depends
(org-element-parse-secondary-string
depends '(link))))
;; 如 target 有特定的 executor, 使用该
;; executor 执行 target, 否则用
;; `org-babel-execute-subtree'.
(executor
(org-entry-get
nil "ORG-EXE-EXECUTOR"))
(executor
(if executor (read executor)))
(executor
(if (commandp executor)
executor
#'org-babel-execute-subtree)))
(save-excursion
(catch (org exec break)
(mapcar exec depends)))
(message "Executing subtree %s by %S..."
title executor)
(call-interactively executor)
(message "Subtree %s evaluation complete."
title)))
exec-default
exec-default
(let ((buf (current-buffer)))
(message "Executing buffer %S..." buf)
(org-babel-execute-buffer)
(message
"Buffer %S evaluation complete." buf))
版本
1.0
;;; org-exec -*- lexical-binding: t; -*-
(defalias 'org-exec
(lambda (&optional link executor &rest args)
(interactive)
(declare (indent defun))
(cond*
((bind* target))
((or (null link) (stringp link)
(org-element-type-p link '(link)))
(setq target (when link (locate link))
link (when (org-element-type-p link '(link))
(org-element-property
:raw-link link)))
(when (and link (null target))
(error "Link %s invalid." link))
(org-with-point-at target
(cond
(executor (apply executor args))
((org-element-type-p
(org-element-at-point) '(src-block))
<<2025-07-23-13-52>>)
(t
<<2025-07-23-13-57>>)))))))
2.2
TARGET
;;; org-exec -*- lexical-binding: t; -*-
(!let ((exec (make-symbol "exec"))
(org (! org)) !def)
(!def exec
<<@([[id:org-exec]])>>)
(setf !def (! org def))
(!def 'exec (! package exec :fapply (!let apply)))
(setf !def (org exec def))
(!def 'cmd
(![&optional link executor &rest args]
(interactive)
(pcase link
('break (org exec break t))
('locate (org exec locate))
(_ (apply exec link executor args)))))
<<@([[id:PRIVATE]])>>
(!def 'locate
<<@([[id:locate]])>>)
(!def 'break
(![a] (throw (org exec break) a)))
(!def 'defexec
(![type executor]
(org exec types type executor)))
(setf !def (org exec defexec))
<<@([[id:FEAT]])>>
(! defdoc 'org-exec
"Org 执行器,执行 `link' 所指元素。
<<@([[id:D:org-exec]])>>
详见不同类型的执行器: "
(! button (org exec types 'all)))
(setf !def '!def)
(!def 'org-exec (org exec cmd))
)
org-exec
(![&optional link executor &rest args]
;; 我们也支持 (org-exec [[link]] ...)
;; 不过,link 的有效性受限于 elisp reader,
;; 使用时需注意。
(when (vectorp link)
(setq link (format "%S" link)))
(!let* ((locate (org exec locate))
(target (when link (locate link)))
(link (when (org-element-type-p
link '(link))
(org-element-property
:raw-link link)))
(types (org exec types))
(pre (org exec pre-hooks))
(post (org exec post-hooks))
etype exec ret)
(when (and link (null target))
(error "Link %s invalid." link))
(org-with-point-at target
(setf etype (org-element-type
(org-element-at-point))
exec (or executor (types etype)
(types 'default)))
(unless exec
(error "No executor found for link %s"
link))
(when link
(message "Executing link: %s..." link))
(run-hooks pre)
(unwind-protect
(save-excursion
(save-window-excursion
(setq ret (apply exec args))))
(run-hooks post))
ret)))
PRIVATE
(!def 'pre-hooks nil)
(!def 'post-hooks nil)
(!def 'types
(let ((D nil))
(![type &optional executor]
(cond
((eq type 'all) (mapcar 'cdr D))
(executor
(setf (alist-get type D)
(defalias (make-symbol
(format "%S" type))
(indirect-function executor))))
((alist-get type D))))))
F:src-block
(!def 'src-block
(![&rest args]
"码块执行器。
<<@([[id:D:exec-src-block]])>>"
<<@([[id:exec-src-block]])>>))
F:exec-default
(!def 'default
(![&rest args]
<<@([[id:exec-default]])>>))
F:exec-substree
(!def 'headline
<<@([[id:exec-subtree]])>>)