Closed kehoen closed 4 years ago
Thank you for the kind words.
Can you provide an example template declaration so I can investigate the behavior you're seeing?
Sure. I didn’t copy everything but this is an example that I would like to have a clock in at the highest headline but put the cursor under notes.
`
("Meeting" :keys "m"
:file "~/Notes/meetings.org"
:children (
("Meetings" :keys "m"
:template ("* %t %?"
":PROPERTIES:"
":CREATED: %U"
":PURPOSE: %^{Meeting purpose}"
":END:"
"** Participants"
"- "
"** Action items"
"- None."
"** Decision made"
"- Not applicable"
"** Notes"
"*** "
"*** Other business")
:children (
("Meeting notes (clocked)"
:keys "m"
:clock-in t
)
("Meeting notes (not clocked)"
:keys "M"
:clock-in nil
)
)
)
("Phone call" :keys "p"
:template ("* %t %?"
":PROPERTIES:"
":CREATED: %U"
":PURPOSE: Phone call with %^{Other party}"
":END:"
"** Action items"
"- None."
"** Decision made"
"- Not applicable"
"** Notes"
"*** "
"*** Other business")
:children (
("Phone call (clocked)"
:keys "p"
:clock-in t
)
("Phone call (not clocked)"
:keys "P"
:clock-in nil
)
)
)
)
)
`
Thanks for the example. I understand what you're going for now.
This is a little tricky due to org-capture's
implementation.
org-capture
executes in this order:
What you want to do is:
In order to work around this I'm going to use a hook function, advice, and restructure the templates.
The first step is to split the template into two parts: the heading we want clocked and the rest of the template.
I'm using the :template
keyword for the heading you want clocked, so org-capture's clocking functionality should work as it normally does.
The child entries of the clocked heading are then split out into a custom keyword. I've chosen :body
below, but you could make it anything you like.
We can't insert the rest of the template during org-capture-mode-hook
because org-capture
invokes org-clock-in
after the hook runs.
Instead, I've advised org-clock-in
to fill and insert the :body
template string and then position the cursor after it executes. The same function removes this temporary advice.
A simplified example similar to the declarations you've provided:
(let ((org-capture-templates
(doct `("clock-in parent test"
:keys "t"
:file "/tmp/clock-in-test.org"
:clock-in t
;;I've defined this function inline in the declaration, but one could define it elsewhere.
:advice ,(defun +doct-insert-body ()
"Insert template's filled :body, position cursor, remove `org-clock-in' advice."
(unwind-protect
(when-let ((body (condition-case nil
(org-capture-fill-template (string-join (doct-get :body) "\n"))
(quit (org-capture-kill)))))
(goto-char (point-max))
(insert "\n" body)
(org-capture--position-cursor (point-min) (point-max)))
(advice-remove 'org-clock-in #'+doct-insert-body)))
:hook ,(defun +doct-advice-org-clock-in ()
"Install `org-clock-in' advice."
(advice-add 'org-clock-in :after #'+doct-insert-body))
:template ("* Clock Here")
:body ("** %^{subheading}"
"*** %?")))))
(org-capture nil "t"))
Note this will create an extra window when filling in the :body
.
Does that help?
Yes, thank you. Running that code does exactly what I need. Now, I just need to best determine how to integrate it into my use case. Thanks for taking the time to do this.
Sorry for the second msg - if you have a minute, can you help show me how to define the function outside of the capture template so I can reuse it on a number of templates? I'm having trouble accomplishing that.
Sure. The defun
form needs to be moved out of the declaration and should be before anything that uses it.
(defun +doct-insert-body ()
"Insert template's filled :body, position cursor, remove `org-clock-in' advice."
(unwind-protect
(when-let ((body (condition-case nil
(org-capture-fill-template (string-join (doct-get :body) "\n"))
(quit (org-capture-kill)))))
(goto-char (point-max))
(insert "\n" body)
(org-capture--position-cursor (point-min) (point-max)))
(advice-remove 'org-clock-in #'+doct-insert-body)))
(setq ((org-capture-templates
(doct `("clock-in parent test"
:keys "t"
:file "/tmp/clock-in-test.org"
:clock-in t
:hook ,(defun +doct-advice-org-clock-in ()
"Install `org-clock-in' advice."
(advice-add 'org-clock-in :after #'+doct-insert-body))
:template ("* Clock Here")
:body ("** %^{subheading}"
"*** %?")))))
(org-capture nil "t"))
does there need to be an advice:
declaration in the setq example above?
No. I was merely storing the function there in the example. :advice
is not a recognized doct keyword. It was just a convenient way to declare the function with the rest of the declaration if you only needed it in one spot.
Hello,
Thanks for this package - I think it is a nice idea for developing capture templates. I have successfully set up a template which I want to use
:clock-in t
. This works fine, however, if I also use%?
to assert where the cursor should be after the template is created, the clock will be assigned to that (sub)headline.Is there any way to ensure that the clock is assigned to the highest headline within the template? As a work around, I am removing the
%?
.