Ricardo Pietrobon
Ricardo Pietrobon

Reputation: 858

selecting entries in org-mode with a deadline

For a number of reasons I have a single file org-mode file with a long todo list, where priority tasks have deadlines and non-priority ones have no deadlines.
The file is now too big and slowing down my shortcuts. My goal is to split the tasks with and without a deadline into two separate files.
I have tried to display the tasks on a calendar and copy the most recent ones (org-mode displays up to 14 days), but that will only allow me to copy their headings and not the task body.

Is there a way to select only the entries (marked with a "*") with a deadline, leaving everything else out?

Upvotes: 0

Views: 840

Answers (2)

NickD
NickD

Reputation: 6402

The sort/cut/paste approach in the previous answer should work fine. The following alternative approach may be of interest if you want to go deeper into org-mode, but it requires some knowledge of lisp as well as a few org-mode functions.

The idea is to refile entries using org-refile. But that refiles only a single entry, so we map it over all entries using org-map-entries.

The idea is simple but the implementation is a bit messier. First, we need to tell org-refile where to refile by setting the variable org-refile-targets, but since there might be a global setting, we need to use let to redefine this variable locally.

Second, we need to select the right entries: org-map-entries takes a matching argument that can be used for that; in particular, "DEADLINE<>\"\"" (testing that the DEADLINE special property of the entry is not equal to the empty string) can be used for that. This then almost works:

(let ((org-refile-targets '(("refiled.org" :level . 1))))
  (org-map-entries #'org-refile "DEADLINE<>\"\"" 'file))

Almost, but not quite: every time org-refile is called, it leaves point at the beginning of the next line and org-map-entries moves it to the end of the line, before attempting the next match; so if you have two DEADLINE entries, one after the other, the second one will be missed. The fix for that is to make sure that you set org-map-continue-from to a position in the buffer that will not miss the next headline. Putting all of this together, you can define the following two functions:

(defun ndk-refile ()
  (org-refile)
  (beginning-of-line)
  (setq org-map-continue-from (point)))

(defun ndk-refile-all ()
  (interactive)
  (let ((org-refile-targets '(("refiled.org" :level . 1))))
    (org-map-entries #'ndk-refile "DEADLINE<>\"\"" 'file)))

Create the refiled.org file with a * Tasks first-level heading and then call the latter function with M-x ndk-refile-all. You will be asked about the refiling destination on each call of org-refile unfortunately, but I didn't dig into how to tame the fit of interaction that it suffers from. Suggestions towards that end are welcome.

BTW, make sure to back up the original file.

Upvotes: 0

sanenr9
sanenr9

Reputation: 598

I believe you could easily sort your file by deadline (C-c ^ and then d) and then find the last headline including a deadline, mark all deadline tasks with C-Space and cut and paste these headlines into a new file.

Does this help?

Upvotes: 3

Related Questions