alphapapa / org-ql

A searching tool for Org-mode, including custom query languages, commands, saved searches and agenda-like views, etc.
GNU General Public License v3.0
1.41k stars 110 forks source link

org-archive-subtree with ":action" works only the first heading #295

Open Cletip opened 2 years ago

Cletip commented 2 years ago

Hello,

I'm trying to do the following: find the headings that have passed (no matter the conditions to find them, just make a query that returns two different headings to do the test) Once these headings are found, I want to archive them. So I have a command that looks like this (with ":action"):

(org-ql-select (org-agenda-files)
    '(and
      (rifle "heading to test")
      (scheduled :to today)
      (ts-active :to today))
    :action '(org-archive-subtree)
    ;; try this too, same result
;;  :action #'org-archive-subtree
    )

Unfortunately, only the first heading is archived, and I don't understand why.

Thanks in advance for your future answers

alphapapa commented 2 years ago

Hello,

I don't know why, either. It doesn't necessarily indicate a bug in org-ql. You'll need to look at the implementation of org-archive-subtree and see how it works. As well, you need to be specific about the versions of the software involved.

alphapapa commented 2 years ago

At a quick glance, I would guess that it's because org-archive-subtree calls outline-next-visible-heading at the end, which may jump over the next potential match that org-ql would have found.

Cletip commented 2 years ago

Thank you for your answer I did some tests, like this one:

        (defun test()
          (interactive)
          (save-excursion
            (org-archive-subtree))

      (org-ql-select (org-agenda-files)
            '(and
              (not (scheduled))
              (not (deadline))
              (not (done))
              (ts-active :to today)
              )
            :action '(test)
            )

Unfortunately, it still doesn't work.

Unfortunately, I will have to look for another solution, because as soon as I reload the "org-archive-subtree" function, the function does not work anymore.

Finally, my version of org is the following:

Org mode version 9.5.2 (release_9.5.2-25-gaf6f12 @ /usr/share/emacs/28.1/lisp/org/)

alphapapa commented 2 years ago

Well, since this isn't necessarily a bug in org-ql, I don't have time to commit to debugging this problem at the moment. I'd suggest a few things:

  1. Try to make a minimal working example. Use a clean Emacs configuration (e.g. using with-emacs.sh), a very simple Org file with two or three headings, and a simple script of actions to reproduce the problem, explaining what was expected and what actually happened.
  2. If you can do that, you can more easily use Edebug to step through org-archive-subtree and find what's going wrong.
  3. If you can do that, we can figure out what, if anything, needs to be done in org-ql about it.

Thanks.

Cletip commented 2 years ago

Ok I understand perfectly. I'm not going to hide from you that I don't have much time right now, and I found an alternative solution.

I'll take your comments into account, and I'll try one day.

Thank you for your answers

alphapapa commented 2 years ago

Okay, would you please share the alternative solution you found?

Cletip commented 2 years ago

Yhea sure,

This must be done in two steps : first, put in "DONE" what you want to archive thanks to org-ql (it's the query). Here, I chose to archive my past appointments : they are defined as headings not scheduled, no deadline, not in done, with an active timestamp. It also needs to be hooked with something that happens all the time: the start or stop of emacs for exemple.


  (defun cp/org-ql-search-for-past-timestamps()
    (org-ql-select (org-agenda-files)
      '(and
        (not (scheduled))
        (not (deadline))
        (not (done))
        (ts-active :to today)
        )
      :action '(org-todo "DONE")
      )
    )

  (add-hook 'kill-emacs-hook #'cp/org-ql-search-for-past-timestamps)

Then, once this function is automatically activated, it is necessary to archive (why not) to the save of the buffer. For that, I use this function :


  (defun cp/org-archive-done-tasks ()
    (interactive)
    (when (org-roam-buffer-p)
      (save-excursion
        (goto-char (point-min))
        (while (re-search-forward
                (concat "* " (regexp-opt org-done-keywords) " ") nil t)
          ;; (goto-char (line-beginning-position))
          (when (= (org-outline-level) 1)
            ;; (when (y-or-n-p (format "do u archive this item %S ?" (org-entry-get nil "ITEM"))
            (org-archive-subtree)
            ;; )
            )))))

  (add-hook 'before-save-hook 'cp/org-archive-done-tasks)

I archive only the level 1s as you can see. I consider that the others stay in their place, because they are part of a "project" with several tasks.

And that's it. Only drawback: emacs asks if you want to save when you kill it. I don't mind, I think you have to change one of the hooks, or touch an option in emacs (I don't have its name) "don't ask for backup when emacs is killed.