Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

`:before-finalize` and `:after-finalize` for Capture Templates or Documentation on Capture Events/Hooks

Open
#1,129 0 comments 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

Nobody has claimed this yet.

Assessment

Difficulty
5/5
Estimated time
Over a week
Newbie friendliness
35/100
Issue type
Feature
Clarity
Needs clarification
Activity status
Quiet
Tech stack
lua
Domain
tooling

Research direction

Start by inspecting the existing capture functionality and any capture events or hooks, then compare them with the Emacs Orgmode Template-elements reference linked in the issue. Done means either providing the requested before/after-finalize behavior or documenting an existing equivalent, with the supported capture behavior clearly described.

Written by the indexing model from the issue text.

Description

enhancement
Does this feature exist in Emacs orgmode core?

Yes

Orgmode link

https://www.gnu.org/software/emacs/manual/html_node/org/Template-elements.html

Feature value

:before-finalize and :after-finalize have their uses. In the case of Emacs, you can add deadline to a captured task, pre-/post-transform any text you've captured before jumping to the capture, etc.

Now if this can be achieved currently by some hook or event that's associated with the capture functionality, I think that'd be worth documenting somewhere.

Additional context

While I'm looking into cutting down on the templates that I use, here's what I currently have in org-capture-templates in Emacs (using doct) to give an idea of some the more "complex" things :before-finalize / :after-finalize open up to you.

(("t" "Tasks")
 ("tD" "Today (Clocked)" entry (file+function "/Users/alec/Documents/Org/Tasks/Today.org" (lambda nil (capture:goto-or-create-heading #'capture:get-todays-timestamp))) #'doct--fill-template :clock-in
  t :clock-keep t :clock-resume t :empty-lines-before 1 :immediate-finish t :jump-to-captured t :unnarrowed t :doct
  (:doct-name "Today (Clocked)" :keys "D" :type entry :file "/Users/alec/Documents/Org/Tasks/Today.org" :function (lambda nil (capture:goto-or-create-heading #'capture:get-todays-timestamp))
   :template-file "/Users/alec/.dots/emacs/.emacs.d/templates/capture/weekly-clocked-tasks.tmplt" :before-finalize (lambda nil (funcall-interactively #'org-deadline nil (current-time))) :clock-in t
   :clock-keep t :clock-resume t :inherited-keys "tD" :jump-to-captured t :immediate-finish t :empty-lines-before 1 :unnarrowed t :after-finalize
   (lambda nil (org-update-statistics-cookies t) (org-mode-restart))))
 ("tt" "Time tracking")
 ("ttt" "Tasks" entry (file "/Users/alec/Documents/Org/Tasks/Time-Tracking.org") "* TODO Task %^{Task Name } :task: \n %?" :clock-in t :clock-keep t :clock-resume t :empty-lines-before 1
  :immediate-finish t :jump-to-captured t :unnarrowed t :doct
  (:doct-name "Tasks" :type entry :keys "t" :template "* TODO Task %^{Task Name } :task: \n %?" :inherited-keys "ttt" :file "/Users/alec/Documents/Org/Tasks/Time-Tracking.org" :clock-in t :clock-keep
   t :clock-resume t :jump-to-captured t :immediate-finish t :empty-lines-before 1 :unnarrowed t :after-finalize (lambda nil (org-update-statistics-cookies t) (org-mode-restart))))
 ("ttm" "Meetings" entry (file "/Users/alec/Documents/Org/Tasks/Time-Tracking.org") "* TODO Meeting %^{Meeting Name } :meeting: \n %?" :clock-in t :clock-keep t :clock-resume t :empty-lines-before 1
  :immediate-finish t :jump-to-captured t :unnarrowed t :doct
  (:doct-name "Meetings" :type entry :keys "m" :template "* TODO Meeting %^{Meeting Name } :meeting: \n %?" :inherited-keys "ttm" :file "/Users/alec/Documents/Org/Tasks/Time-Tracking.org" :clock-in t
   :clock-keep t :clock-resume t :jump-to-captured t :immediate-finish t :empty-lines-before 1 :unnarrowed t :after-finalize (lambda nil (org-update-statistics-cookies t) (org-mode-restart))))
 ("ttp" "Phone" entry (file "/Users/alec/Documents/Org/Tasks/Time-Tracking.org") "* TODO Phone Call %^{Phone Call Subject } :phone: \n %?" :clock-in t :clock-keep t :clock-resume t :empty-lines-before
  1 :immediate-finish t :jump-to-captured t :unnarrowed t :doct
  (:doct-name "Phone" :type entry :keys "p" :template "* TODO Phone Call %^{Phone Call Subject } :phone: \n %?" :inherited-keys "ttp" :file "/Users/alec/Documents/Org/Tasks/Time-Tracking.org"
   :clock-in t :clock-keep t :clock-resume t :jump-to-captured t :immediate-finish t :empty-lines-before 1 :unnarrowed t :after-finalize
   (lambda nil (org-update-statistics-cookies t) (org-mode-restart))))
 ("tto" "Other" entry (file "/Users/alec/Documents/Org/Tasks/Time-Tracking.org") "* TODO %^{What are we doing? } :other: \n %?" :clock-in t :clock-keep t :clock-resume t :empty-lines-before 1
  :immediate-finish t :jump-to-captured t :unnarrowed t :doct
  (:doct-name "Other" :type entry :keys "o" :template "* TODO %^{What are we doing? } :other: \n %?" :inherited-keys "tto" :file "/Users/alec/Documents/Org/Tasks/Time-Tracking.org" :clock-in t
   :clock-keep t :clock-resume t :jump-to-captured t :immediate-finish t :empty-lines-before 1 :unnarrowed t :after-finalize (lambda nil (org-update-statistics-cookies t) (org-mode-restart))))
 ("tm" "Today (Manual)" entry (file+function "/Users/alec/Documents/Org/Tasks/Today.org" (lambda nil (capture:goto-or-create-heading #'capture:get-todays-timestamp))) #'doct--fill-template
  :empty-lines-before 1 :immediate-finish t :jump-to-captured t :unnarrowed t :doct
  (:doct-name "Today (Manual)" :keys "m" :type entry :file "/Users/alec/Documents/Org/Tasks/Today.org" :function (lambda nil (capture:goto-or-create-heading #'capture:get-todays-timestamp))
   :template-file "/Users/alec/.dots/emacs/.emacs.d/templates/capture/weekly-manual-tasks.tmplt" :inherited-keys "tm" :jump-to-captured t :immediate-finish t :empty-lines-before 1 :unnarrowed t
   :after-finalize (lambda nil (org-update-statistics-cookies t) (org-mode-restart))))
 ("td" "Today (Unclocked)" entry (file+function "/Users/alec/Documents/Org/Tasks/Today.org" (lambda nil (capture:goto-or-create-heading #'capture:get-todays-timestamp))) #'doct--fill-template
  :empty-lines-before 1 :immediate-finish t :jump-to-captured t :unnarrowed t :doct
  (:doct-name "Today (Unclocked)" :keys "d" :type entry :file "/Users/alec/Documents/Org/Tasks/Today.org" :function (lambda nil (capture:goto-or-create-heading #'capture:get-todays-timestamp))
   :template-file "/Users/alec/.dots/emacs/.emacs.d/templates/capture/weekly-unclocked-tasks.tmplt" :before-finalize (lambda nil (funcall-interactively #'org-deadline nil (current-time)))
   :inherited-keys "td" :jump-to-captured t :immediate-finish t :empty-lines-before 1 :unnarrowed t :after-finalize (lambda nil (org-update-statistics-cookies t) (org-mode-restart))))
 ("th" "Habits")
 ("thd" "Daily" entry (file "/Users/alec/Documents/Org/Tasks/Habits.org") #'doct--fill-template :empty-lines-before 1 :immediate-finish t :jump-to-captured t :unnarrowed t :doct
  (:doct-name "Daily" :keys "d" :type entry :template-file "/Users/alec/.dots/emacs/.emacs.d/templates/capture/daily-habit.tmplt" :inherited-keys "thd" :file
   "/Users/alec/Documents/Org/Tasks/Habits.org" :jump-to-captured t :immediate-finish t :empty-lines-before 1 :unnarrowed t :after-finalize
   (lambda nil (org-update-statistics-cookies t) (org-mode-restart))))
 ("thD" "Every Other Day" entry (file "/Users/alec/Documents/Org/Tasks/Habits.org") #'doct--fill-template :empty-lines-before 1 :immediate-finish t :jump-to-captured t :unnarrowed t :doct
  (:doct-name "Every Other Day" :keys "D" :type entry :template-file "/Users/alec/.dots/emacs/.emacs.d/templates/capture/bidaily-habit.tmplt" :inherited-keys "thD" :file
   "/Users/alec/Documents/Org/Tasks/Habits.org" :jump-to-captured t :immediate-finish t :empty-lines-before 1 :unnarrowed t :after-finalize
   (lambda nil (org-update-statistics-cookies t) (org-mode-restart))))
 ("c" "Calendar") ("ca" "Appointment")
 ("cad" "On day" entry (file+headline "/Users/alec/Documents/Org/Tasks/Calendar.org" "Appointments") #'doct--fill-template :empty-lines-before 1 :immediate-finish t :unnarrowed t :doct
  (:doct-name "On day" :keys "d" :type entry :template-file "/Users/alec/.dots/emacs/.emacs.d/templates/capture/appt.tmplt" :inherited-keys "cad" :headline "Appointments" :file
   "/Users/alec/Documents/Org/Tasks/Calendar.org" :empty-lines-before 1 :immediate-finish t :unnarrowed t))
 ("caD" "At time" entry (file+headline "/Users/alec/Documents/Org/Tasks/Calendar.org" "Appointments") #'doct--fill-template :empty-lines-before 1 :immediate-finish t :unnarrowed t :doct
  (:doct-name "At time" :keys "D" :type entry :headline "Appointments" :template-file "/Users/alec/.dots/emacs/.emacs.d/templates/capture/appt-time.tmplt" :inherited-keys "caD" :file
   "/Users/alec/Documents/Org/Tasks/Calendar.org" :empty-lines-before 1 :immediate-finish t :unnarrowed t))
 ("c" "Cookbook")
 ("cu" "From URL" entry (file "/Users/alec/Documents/Org/Mind/Cooking/Cookbook.org") "%(org-chef-get-recipe-from-url)" :empty-lines 1 :doct
  (:doct-name "From URL" :keys "u" :type entry :file "/Users/alec/Documents/Org/Mind/Cooking/Cookbook.org" :template "%(org-chef-get-recipe-from-url)" :inherited-keys "cu" :empty-lines 1))
 ("c" "Manual Entry" entry (file "/Users/alec/Documents/Org/cookbook.org")
  "* %^{Recipe title: }\n  :PROPERTIES:\n  :source-url:\n  :servings:\n  :prep-time:\n  :cook-time:\n  :ready-in:\n  :END:\n** Ingredients\n   %?\n**Directions %i %a" :empty-lines 1 :doct
  (:doct-name "Manual Entry" :type entry :file "/Users/alec/Documents/Org/cookbook.org" :template
   "* %^{Recipe title: }\n  :PROPERTIES:\n  :source-url:\n  :servings:\n  :prep-time:\n  :cook-time:\n  :ready-in:\n  :END:\n** Ingredients\n   %?\n**Directions %i %a" :inherited-keys "c" :empty-lines
   1))
 ("p" "Add Contact" entry (file "/Users/alec/Documents/Org/Just Notes/Phonebook.org") #'doct--fill-template :empty-lines-before 1 :immediate-finish t :doct
  (:doct-name "Add Contact" :keys "p" :empty-lines-before 1 :immediate-finish t :type entry :file "/Users/alec/Documents/Org/Just Notes/Phonebook.org" :template-file
   "/Users/alec/.dots/emacs/.emacs.d/templates/capture/contact.tmplt")))
Dominant language
Lua
Stars
3.9k
Forks
192
Avg merge
2d 6h
Merged PRs (30d)
18

Getting set up

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from nvim-orgmode/orgmode

All issues in nvim-orgmode/orgmode

Similar issues

More Lua issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.