Org capture tricks
I recently started to use quite big org capture templates at work. They describe my usual workflow for a complete ticket (triage, implementation, code review, deploy). To make the capturing more efficient, I came up with three helpful functions:
EDIT: This post got updated with some code improvements on 03/05/2016.
Use user input in several locations
Org capture templates can prompt for user input, but then only inserts it at one location. This is quite limiting. The template I created asked for a JIRA ticket number and I wanted to use it throughout my template without prompting for the same thing again.
But org capture supports custom lisp expressions. That's like allowing cheat codes. Super powerful. So I wrote a function that will prompt the user for a string, save it to a buffer local variable and return it (so it is inserted at the first location).
(defvar oc-capture-prmt-history nil "History of prompt answers for org capture.") (defun oc/prmt (prompt variable) "PROMPT for string, save it to VARIABLE and insert it." (make-local-variable variable) (set variable (read-string (concat prompt ": ") nil oc-capture-prmt-history)))
For inserting progn
is all you need.
So let's say I have a capture template like this:
* JIRA Ticket %(oc/prmt "JIRA Project" 'jr-prj)-%(oc/prmt "JIRA Ticket No." 'jr-no) For project %(prgn jr-prj) I have to do the following stuff: ** Triage %(progn jr-prj)-%(progn jr-no) Do the triage. ** Implement %(progn jr-prj)-%(progn jr-no) Implement stuff - [ ] Tests pass?
It has two calls to oc/prmt
in the first heading and several calls to oc/ins
afterwards.
Orc capture will first prompt for the JIRA project:
Then for the ticket number:
Afterwards everywhere I use oc/ins
, the stored text is inserted:
Conditionally insert text
Sometimes I don't need a triage or an implementation for a ticket. So it would be nice to have org-capture ask whether I want to include a section.
The function is very minimal:
(defun oc/inc (what text &rest fmtvars) "Ask user to include WHAT. If user agrees return TEXT." (when (y-or-n-p (concat "Include " what "?")) (apply 'format text fmtvars))
The capture template starts to look a little bit ugly:
* JIRA Ticket %(oc/prmt "JIRA Project" 'jr-prj)-%(oc/prmt "JIRA Ticket No." 'jr-no) For project %(progn jr-prj) I have to do the following stuff: %(oc/inc "triage" "** Triage %s-%s Do the triage." jr-prj jr-no) %(oc/inc "implementation" "** Implement %s-%s Implement stuff - [ ] Tests pass?" jr-prj jr-no)
So after getting prompted for the project and ticket number, org-capture will ask whether to include the triage:
Then for the implementation. You can see that the triage text already got inserted:
The fully expanded template looks like this:
If you decide not to include a section, a blank line remains: You could fix that by putting all the include statements in one line and add a newline at the end of the text but that would look very ugly. Unfortunately it's not easy to work around that.
Let me know if you find this useful or have other ideas for org capture templates.