Is it possible to refile a dated item into the appropriate place in a datetree?
I have seen some posts that describe the use of org-archive-location but I cannot get that to work - perhaps its the wrong thing to use?
Emacs Stack Exchange is a question and answer site for those using, extending or developing Emacs. It only takes a minute to sign up.
Sign up to join this communityIs it possible to refile a dated item into the appropriate place in a datetree?
I have seen some posts that describe the use of org-archive-location but I cannot get that to work - perhaps its the wrong thing to use?
I posted a previous version of this code to answer a similar question on Stack Overflow. This version is slightly imporoved.
You can select a file to refile into and if the entry has no timestamp, the current date is used.
(defun org-refile-to-datetree (&optional file)
"Refile a subtree to a datetree corresponding to it's timestamp.
The current time is used if the entry has no timestamp. If FILE
is nil, refile in the current file."
(interactive "f")
(let* ((datetree-date (or (org-entry-get nil "TIMESTAMP" t)
(org-read-date t nil "now")))
(date (org-date-to-gregorian datetree-date))
)
(with-current-buffer (current-buffer)
(save-excursion
(org-cut-subtree)
(if file (find-file file))
(org-datetree-find-date-create date)
(org-narrow-to-subtree)
(show-subtree)
(org-end-of-subtree t)
(newline)
(goto-char (point-max))
(org-paste-subtree 4)
(widen)
))
)
)
Edit: According to the manual save-excursion
should be used within with-current-buffer
to avoid certain side-effects.
The accepted answer is likely to work, but misses some things. In particular, since it does the refiling itself, it won't trigger the actions from org-log-refile
and the like.
Based in part on some other code from a site I now can't find, I put together the following:
(defun my/org-read-datetree-date (d)
"Parse a time string D and return a date to pass to the datetree functions."
(let ((dtmp (nthcdr 3 (parse-time-string d))))
(list (cadr dtmp) (car dtmp) (caddr dtmp))))
(defun my/org-refile-to-archive-datetree ()
"Refile an entry to a datetree under an archive."
(interactive)
(require 'org-datetree)
(let ((datetree-date (my/org-read-datetree-date (org-read-date t nil))))
(org-refile nil nil (list nil (buffer-file-name) nil
(save-excursion
(org-datetree-find-date-create datetree-date)))))
(setq this-command 'my/org-refile-to-journal))
This passes the target location to org-refile
itself, which can thus do the correct subsidiary processing. My particular setup is to refile to an archive in the same file, which has a DATE_TREE
property in order to cause the datetree functions to work underneath it. If you want to specify a file, you can wrap the call in with-current-buffer
and use find-file
inside.
my/org-refile-to-archive-datetree
, though, the heading is not refiled as a child of the datetree, but as a top-level heading directly below the new date entry...do you have any suggestions?
– Henry
Jan 11 '18 at 14:45
The previous answer by Tom Hunt is almost ok, but org-refile
needs both the file and the position in the file as the rfloc argument. Unfortunately, org-datetree-find-date-create
does not return this position. (Is it something that changed in recent versions of Org mode?)
So here is a slightly enhanced version of the same function:
(defun my/org-refile-to-archive-datetree (&optional bfn)
"Refile an entry to a datetree under an archive."
(interactive)
(require 'org-datetree)
(let* ((bfn (or bfn (find-file-noselect (expand-file-name "~/Org/Diary.org"))))
(datetree-date (my/org-read-datetree-date (org-read-date t nil))))
(org-refile nil nil (list nil (buffer-file-name bfn) nil
(with-current-buffer bfn
(save-excursion
(org-datetree-find-date-create datetree-date)
(point))))))
(setq this-command 'my/org-refile-to-journal))
I added an optional buffer-file-name
argument and as a default value, I am using my ~/Org/Diary.org
journal file.
org-refile
? I use it all the time with datetrees as targets. – Brian Z Apr 10 '15 at 0:56