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.
-
Sorry, I forgot the context for my question. "capture" is a part of emacs org-mode– myotisAug 11, 2015 at 22:21
3 Answers
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)))
-
-
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?– myotisNov 8, 2015 at 17:18
-
I just added two functions that avoid capture entirely. I think this is what you're looking for. Nov 8, 2015 at 19:36
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.
-
Thanks! I am not sure how to use your code. I have added it to my init.el file. What do I do more?– myotisNov 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.– jchNov 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?– myotisNov 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.– jchNov 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?– myotisNov 8, 2015 at 14:39
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"))