I have the following org-template set up:

("mw" "Note" entry (file+headline "~/org/mathematica.org" "WIA")
  "* %f code review \n ** %T \n%? \n%a \n%i")

So that the heading name is determined by the file name and the "code review," and then there's a subheading using the date and time of the note.

If for example I've already made a note using this template while visiting the file foo.do, I would like the next entry to be with that one as in the following example:

>     * foo.do code review
>     **<2015-11-22 Sun 09:00> 
>     first note
>     **<2015-11-22 Sun 10:00> 
>     second note

But instead I get

>     * foo.do code review
>     **<2015-11-22 Sun 09:00> 
>     first note
>     * foo.do code review
>     **<2015-11-22 Sun 10:00> 
>     second note

How can I make all the foo.do code review notes be under the same heading?

2 Answers 2


This is what I use:

("p" "Pick a file" entry (function myOrg-captureFile))

for my org-capture-template with

 (defun myOrg-captureFile ()
    "pick a file for capture and file the stuff"
    (interactive "P")
    (let* ((file (read-file-name "Enter file name: "))
           (heading (read-string "Heading ")))
      (find-file file)
      (goto-char 0)
      (unless (search-forward (format "* %s" heading) nil t)
        (insert (format "* %s\n" heading))
        (goto-line -1))))

as the function definition. This works rather nicely


You can't; there's nothing implemented that would let you do it. You'll have to make some modifications to the code to support it.

I don't use capturing myself, so I took a look through the documentation to see how it works. You've no doubt read it, but you can jump right to this chapter of the manual in emacs by running M-: (info "(org) Capture"); of course it's also available online. This also tells me that the user starts a capture by calling the function org-capture, which will be the most natural place to start reading the source. C-h f org-capture will show the documentation of that function, along with a link directly to its source code.

When you define a capture template you're specifying several things: how to select the template, what type of entry to create, where to save the entry, and any boilerplate text to insert on behalf of the user.

Your question asks that org-capture match the boilerplate text against the content of the save location in order to avoid adding some lines to the file twice. You could implement it this way, but I recommend that you don't. The save location doesn't need to be an org file at all; you could be capturing to any type of file at all. The boilerplate text therefore isn't always going to use org syntax. A good example would be capturing to a BibTeX file; the boilerplate would presumably be LaTeX.

Instead I think the best way to implement it would be to add a new type of save location. These are all handled by the org-capture-set-target-location function in org-capture.el. You're currently using the 'file+headline locator, which takes a filename and a headline, and sets org-capture to insert the new entry as a subheading of that headline found in that file. This is almost what you need. If you could specify (file+headline "~/org/mathematica.org" "WIA" "%f code review") then you would be in good shape.

However, the 'file+headline locator only accepts a single headline, and doesn't allow any of the substitutions allowed in the boilerplate text.

Allowing multiple headlines shouldn't be too difficult to implement. Just modify this branch of the case in org-capture-set-target-location so that it loops over all of the remaining items in the list, first searching for the headline and then narrowing the buffer to that subtree after it either finds it or creates it. Each time through the loop the search will naturally be limited to the narrowed region of the file, so the correct subheadings will be found or created.

Allowing substitutions should be even easier; just call org-capture-fill-template on each argument before using it. This should be done for all cases, so do it before handling any of them. This list is never likely to be very long, so the simplest thing to do is to map down the list calling org-capture-fill-template on all the strings, even though you're later going to loop over the list again.

Also, once you've written this I recommend submitting your changes for inclusion in the next release; see orgmode.org for the details on how to do that.

  • org-capture can take a function, so perhaps someone will write-up an answer that addresses the question: (file+function "path/to/file" function-finding-location) -- A function to find the right location in the file. OR (function function-finding-location) -- Most general way, write your own function to find both file and location.
    – lawlist
    Nov 22, 2015 at 20:15
  • That's also a possibility; I'd missed that in the docs.
    – db48x
    Nov 22, 2015 at 21:12
  • As an aside, it'd be nice if someone restructured this code so that there was a separate function for each locator method (rather than a giant case expression) so that folks could use defadvice on them.
    – db48x
    Nov 22, 2015 at 21:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.