org-capture: Add template hook properties
* lisp/org-capture.el (org-capture-templates): Document template hook properties. (org-capture-finalize): Execute :prepare/:before/:after-finalize functions. (org-capture-place-template): Execute :hook functions. * doc/org-manual.org: Document template hook properties. * etc/ORG-NEWS: Add news entry for template hook properties. * testing/lisp/test-org-capture.el: Add tests for template hook properties.
This commit is contained in:
parent
0be36ac13e
commit
7f3a6cf6e7
|
@ -7929,6 +7929,26 @@ Now lets look at the elements of a template definition. Each entry in
|
||||||
- ~:refile-targets~ :: Temporarily set ~org-refile-targets~ to the
|
- ~:refile-targets~ :: Temporarily set ~org-refile-targets~ to the
|
||||||
value of this property.
|
value of this property.
|
||||||
|
|
||||||
|
- ~:hook~ ::
|
||||||
|
|
||||||
|
A nullary function or list of nullary functions run before
|
||||||
|
~org-capture-mode-hook~ when the template is selected.
|
||||||
|
|
||||||
|
- ~:prepare-finalize~ ::
|
||||||
|
|
||||||
|
A nullary function or list of nullary functions run before
|
||||||
|
~org-capture-prepare-finalize-hook~ when the template is selected.
|
||||||
|
|
||||||
|
- ~:before-finalize~ ::
|
||||||
|
|
||||||
|
A nullary function or list of nullary functions run before
|
||||||
|
~org-capture-before-finalize-hook~ when the template is selected.
|
||||||
|
|
||||||
|
- ~:after-finalize~ ::
|
||||||
|
|
||||||
|
A nullary function or list of nullary functions run before
|
||||||
|
~org-capture-after-finalize-hook~ when the template is selected.
|
||||||
|
|
||||||
**** Template expansion
|
**** Template expansion
|
||||||
:PROPERTIES:
|
:PROPERTIES:
|
||||||
:DESCRIPTION: Filling in information about time and context.
|
:DESCRIPTION: Filling in information about time and context.
|
||||||
|
|
|
@ -663,6 +663,13 @@ When exiting capture mode via ~org-capture-refile~, the variable
|
||||||
~org-refile-targets~ will be temporarily bound to the value of this
|
~org-refile-targets~ will be temporarily bound to the value of this
|
||||||
template option.
|
template option.
|
||||||
|
|
||||||
|
*** Add Capture template hook properties
|
||||||
|
|
||||||
|
Capture templates can now attach template specific hooks via the
|
||||||
|
following properties: ~:hook~, ~:prepare-finalize~,
|
||||||
|
~:before-finalize~, ~:after-finalize~. These nullary functions run
|
||||||
|
prior to their global counterparts for the selected template.
|
||||||
|
|
||||||
*** New startup options =#+startup: show<n>levels=
|
*** New startup options =#+startup: show<n>levels=
|
||||||
|
|
||||||
These startup options complement the existing =overview=, =content=,
|
These startup options complement the existing =overview=, =content=,
|
||||||
|
|
|
@ -297,6 +297,21 @@ properties are:
|
||||||
|
|
||||||
:no-save Do not save the target file after finishing the capture.
|
:no-save Do not save the target file after finishing the capture.
|
||||||
|
|
||||||
|
:hook A nullary function or list of nullary functions run before
|
||||||
|
`org-capture-mode-hook' when the template is selected.
|
||||||
|
|
||||||
|
:prepare-finalize A nullary function or list of nullary functions run before
|
||||||
|
`org-capture-prepare-finalize-hook'
|
||||||
|
when the template is selected.
|
||||||
|
|
||||||
|
:before-finalize A nullary function or list of nullary functions run before
|
||||||
|
`org-capture-before-finalize-hook'
|
||||||
|
when the template is selected.
|
||||||
|
|
||||||
|
:after-finalize A nullary function or list of nullary functions run before
|
||||||
|
`org-capture-after-finalize-hook'
|
||||||
|
when the template is selected.
|
||||||
|
|
||||||
The template defines the text to be inserted. Often this is an
|
The template defines the text to be inserted. Often this is an
|
||||||
Org mode entry (so the first line should start with a star) that
|
Org mode entry (so the first line should start with a star) that
|
||||||
will be filed as a child of the target headline. It can also be
|
will be filed as a child of the target headline. It can also be
|
||||||
|
@ -741,6 +756,17 @@ of the day at point (if any) or the current HH:MM time."
|
||||||
(format "* Template function %S not found" f)))
|
(format "* Template function %S not found" f)))
|
||||||
(_ "* Invalid capture template"))))
|
(_ "* Invalid capture template"))))
|
||||||
|
|
||||||
|
(defun org-capture--run-template-functions (keyword &optional local)
|
||||||
|
"Run funcitons associated with KEYWORD on template's plist.
|
||||||
|
For valid values of KEYWORD see `org-capture-templates'.
|
||||||
|
If LOCAL is non-nil use the buffer-local value of `org-capture-plist'."
|
||||||
|
;; Used in place of `run-hooks' because these functions have no associated symbol.
|
||||||
|
;; They are stored directly on `org-capture-plist'.
|
||||||
|
(let ((value (org-capture-get keyword local)))
|
||||||
|
(if (functionp value)
|
||||||
|
(funcall value)
|
||||||
|
(mapc #'funcall value))))
|
||||||
|
|
||||||
(defun org-capture-finalize (&optional stay-with-capture)
|
(defun org-capture-finalize (&optional stay-with-capture)
|
||||||
"Finalize the capture process.
|
"Finalize the capture process.
|
||||||
With prefix argument STAY-WITH-CAPTURE, jump to the location of the
|
With prefix argument STAY-WITH-CAPTURE, jump to the location of the
|
||||||
|
@ -752,6 +778,7 @@ captured item after finalizing."
|
||||||
(buffer-base-buffer (current-buffer)))
|
(buffer-base-buffer (current-buffer)))
|
||||||
(error "This does not seem to be a capture buffer for Org mode"))
|
(error "This does not seem to be a capture buffer for Org mode"))
|
||||||
|
|
||||||
|
(org-capture--run-template-functions :prepare-finalize 'local)
|
||||||
(run-hooks 'org-capture-prepare-finalize-hook)
|
(run-hooks 'org-capture-prepare-finalize-hook)
|
||||||
|
|
||||||
;; Update `org-capture-plist' with the buffer-local value. Since
|
;; Update `org-capture-plist' with the buffer-local value. Since
|
||||||
|
@ -821,6 +848,7 @@ captured item after finalizing."
|
||||||
;; the indirect buffer has been killed.
|
;; the indirect buffer has been killed.
|
||||||
(org-capture-store-last-position)
|
(org-capture-store-last-position)
|
||||||
|
|
||||||
|
(org-capture--run-template-functions :before-finalize 'local)
|
||||||
;; Run the hook
|
;; Run the hook
|
||||||
(run-hooks 'org-capture-before-finalize-hook))
|
(run-hooks 'org-capture-before-finalize-hook))
|
||||||
|
|
||||||
|
@ -869,6 +897,9 @@ captured item after finalizing."
|
||||||
;; Restore the window configuration before capture
|
;; Restore the window configuration before capture
|
||||||
(set-window-configuration return-wconf))
|
(set-window-configuration return-wconf))
|
||||||
|
|
||||||
|
;; Do not use the local arg to `org-capture--run-template-functions' here.
|
||||||
|
;; The buffer-local value has been stored on `org-capture-plist'.
|
||||||
|
(org-capture--run-template-functions :after-finalize)
|
||||||
(run-hooks 'org-capture-after-finalize-hook)
|
(run-hooks 'org-capture-after-finalize-hook)
|
||||||
;; Special cases
|
;; Special cases
|
||||||
(cond
|
(cond
|
||||||
|
@ -1145,6 +1176,7 @@ may have been stored before."
|
||||||
(`item (org-capture-place-item))
|
(`item (org-capture-place-item))
|
||||||
(`checkitem (org-capture-place-item)))
|
(`checkitem (org-capture-place-item)))
|
||||||
(setq-local org-capture-current-plist org-capture-plist)
|
(setq-local org-capture-current-plist org-capture-plist)
|
||||||
|
(org-capture--run-template-functions :hook 'local)
|
||||||
(org-capture-mode 1))
|
(org-capture-mode 1))
|
||||||
|
|
||||||
(defun org-capture-place-entry ()
|
(defun org-capture-place-entry ()
|
||||||
|
|
|
@ -754,5 +754,48 @@
|
||||||
(org-capture nil "t")
|
(org-capture nil "t")
|
||||||
(buffer-string))))))
|
(buffer-string))))))
|
||||||
|
|
||||||
|
(ert-deftest test-org-capture/template-specific-hooks ()
|
||||||
|
"Test template-specific hook execution."
|
||||||
|
;; Runs each template hook prior to corresponding global hook
|
||||||
|
(should
|
||||||
|
(equal "hook\nglobal-hook\nprepare\nglobal-prepare
|
||||||
|
before\nglobal-before\nafter\nglobal-after"
|
||||||
|
(org-test-with-temp-text-in-file ""
|
||||||
|
(let* ((file (buffer-file-name))
|
||||||
|
(org-capture-mode-hook
|
||||||
|
'((lambda () (insert "global-hook\n"))))
|
||||||
|
(org-capture-prepare-finalize-hook
|
||||||
|
'((lambda () (insert "global-prepare\n"))))
|
||||||
|
(org-capture-before-finalize-hook
|
||||||
|
'((lambda () (insert "global-before\n"))))
|
||||||
|
(org-capture-after-finalize-hook
|
||||||
|
'((lambda () (with-current-buffer
|
||||||
|
(org-capture-get :buffer)
|
||||||
|
(goto-char (point-max))
|
||||||
|
(insert "global-after")))))
|
||||||
|
(org-capture-templates
|
||||||
|
`(("t" "Test" plain (file ,file) ""
|
||||||
|
:hook (lambda () (insert "hook\n"))
|
||||||
|
:prepare-finalize (lambda () (insert "prepare\n"))
|
||||||
|
:before-finalize (lambda () (insert "before\n"))
|
||||||
|
:after-finalize (lambda () (with-current-buffer
|
||||||
|
(org-capture-get :buffer)
|
||||||
|
(goto-char (point-max))
|
||||||
|
(insert "after\n")))
|
||||||
|
:immediate-finish t))))
|
||||||
|
(org-capture nil "t")
|
||||||
|
(buffer-string)))))
|
||||||
|
;; Accepts a list of nullary functions
|
||||||
|
(should
|
||||||
|
(equal "one\ntwo"
|
||||||
|
(org-test-with-temp-text-in-file ""
|
||||||
|
(let* ((file (buffer-file-name))
|
||||||
|
(org-capture-templates
|
||||||
|
`(("t" "Test" plain (file ,file) ""
|
||||||
|
:hook ((lambda () (insert "one\n"))
|
||||||
|
(lambda () (insert "two")))))))
|
||||||
|
(org-capture nil "t")
|
||||||
|
(buffer-string))))))
|
||||||
|
|
||||||
(provide 'test-org-capture)
|
(provide 'test-org-capture)
|
||||||
;;; test-org-capture.el ends here
|
;;; test-org-capture.el ends here
|
||||||
|
|
Loading…
Reference in New Issue