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 – myotis Aug 11 '15 at 22:21
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? – myotis Nov 8 '15 at 17:18
-
I just added two functions that avoid capture entirely. I think this is what you're looking for. – Aaron Harris Nov 8 '15 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? – myotis Nov 8 '15 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 Nov 8 '15 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 Nov 8 '15 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 Nov 8 '15 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 Nov 8 '15 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"))