9

I need to generate text files with the following name format: YYYYY-MM-DD--hh-mm-ss.org. How can I use the capture funtionality for this? That is, instead of making one entry per capture in a single file, the function should make one single file per capture, and hopefully with all the possibilities within the capture mechanism.

1
  • Sorry, I forgot the context for my question. "capture" is a part of emacs org-mode
    – myotis
    Commented Aug 11, 2015 at 22:21

3 Answers 3

6
+50

You should be able to use the function target form to do this:

(defun my/org-file-by-date ()
  "Create an Org file with current time as name."
  (find-file (format-time-string "~/org/%Y-%m-%d--%H-%M-%S.org")))

(add-to-list 'org-capture-templates
             '("x" "Template Name" plain
              (function my/org-file-by-date)
              "Capture template contents"))

Edit 2: As it turns out, code passed to a file form or the like isn't evaluated until capture time, so there's a more compact way to do this. See Erik Sjöstrand's answer for an example.

Edit 1: To get similar functionality without going through the capture interface, you can use functions similar to these.

(defun my/org-file-by-date-with-inline-skeleton ()
  "Create Org file from skeleton with current time as name."
  (interactive)
  (find-file (format-time-string "~/org/%Y-%m-%d--%H-%M-%S.org"))
  (insert "Skeleton contents"))

(defun my/org-file-by-date-with-file-skeleton ()
  "Create Org file from skeleton file with current time as name."
  (interactive)
  (let ((filename (format-time-string "~/org/%Y-%m-%d--%H-%M-%S.org")))
    (copy-file "path/to/skeleton/file" filename)
    (find-file filename)))
3
  • Right. I've edited my answer to point at yours.
    – jch
    Commented Nov 8, 2015 at 17:13
  • Thanks ! I see, by testing the code, that it is maybe not necessary to use the capture functionality at all. Because I write very much in each of these files, and then I have to close by C-c c. I would prefer to write directly into the created file and save as normal. How can I create a file named %Y-%m-%d--%H-%M-%S.org and containing some fixed text (from a skeleton maybe?) and then opening it for writing?
    – myotis
    Commented Nov 8, 2015 at 17:18
  • I just added two functions that avoid capture entirely. I think this is what you're looking for. Commented Nov 8, 2015 at 19:36
1

There doesn't appear to be any built-in functionality to do that (edit: yes there is, see below). The simplest solution, one that does not require delving into the internals of the capture functionality, is to bind the value of org-default-notes-file at capture time:

(defun my-org-capture-advice (func &rest args)
   (let ((org-default-notes-file
         (format-time-string "~/org/%Y-%m-%d--%H-%M-%S.org")))
    (apply func args)))

(advice-add 'org-capture :around #'my-org-capture-advice)

This advice happens very early, so it doesn't yet know which template you're going to use. If the name of the file depends on the capture template, then you'll probably need to advice org-capture-set-target-location.

Edit: the function template target is a better way to achieve that. See Aaron's answer for an example.

6
  • Thanks! I am not sure how to use your code. I have added it to my init.el file. What do I do more?
    – myotis
    Commented Nov 8, 2015 at 13:25
  • Just whatever you do usually to invoke the org-capture function — C-c c if you've followed the advice in the Org manual.
    – jch
    Commented Nov 8, 2015 at 14:25
  • I still do not understand. If I type "M-x my-org-capture-advice" nothing happens. When I type my normal C-c c I got my list of captures as I have defined them. So where does your code come in?
    – myotis
    Commented Nov 8, 2015 at 14:32
  • If your org-capture-templates do not specify a file to capture into, the file chosen will be formatted as you desire.
    – jch
    Commented Nov 8, 2015 at 14:36
  • so I need to make a new capture file without a file to capture into, and then your code will do its work?
    – myotis
    Commented Nov 8, 2015 at 14:39
1

Here's a way to keep it all in the org-capture-templates list, without defining other functions. org-directory can be changed to whatever directory you want to store the files in.

(add-to-list 'org-capture-templates
             '("x" "Template name" plain
               (file (expand-file-name
                      (format-time-string "%Y-%m-%d--%H-%M-%S.org")
                      org-directory))
               "This string is inserted in the capture"))

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.