From: Tim Visher <email@example.com> To: Emacs Org Mode mailing list <firstname.lastname@example.org> Subject: Re: Refiling All 'Terminal TODO State' Entries to a Particular Heading Date: Wed, 12 May 2021 09:35:54 -0400 [thread overview] Message-ID: <CAHa53uy1q+PL1NYtahc_8L+TZ38zKQsfGALz5j1Rhzs=G76eXw@mail.gmail.com> (raw) In-Reply-To: <CAHa53uyAgajfOk4NhovGDJ4f1OVvFf03XxwbgR89jgJ1M0K3Ew@mail.gmail.com> [-- Attachment #1: Type: text/plain, Size: 4817 bytes --] Hi Everyone, I found that my timvisher-org-refile-done-entries had a bug where it could skip entries if the org buffer had consecutive DONE/CANCELLED entries. I believe this is because of this quote from the manual: After evaluation, Org moves point to the end of the line that was just processed. Search continues from that point forward. This may not always work as expected under some conditions, such as if the current sub-tree was removed by a previous archiving operation. In such rare circumstances, Org skips the next entry entirely when it should not. To stop Org from such skips, make FUNC set the variable ‘org-map-continue-from’ to a specific buffer position. I've been doing some experimentation around how to fix this: Attempt 1 This feels like the simplest and most naive approach: (defun timvisher-org-refile-done-entry-position () (save-excursion (goto-char (point-min)) (- (re-search-forward "^\\* Done") 6))) (defun timvisher-org-refile-done-entry () (org-refile nil (current-buffer) (list "* Done" (buffer-file-name) nil (timvisher-org-refile-done-entry-position)))) (defun timvisher-org-refile-done-entries () (interactive) (while (< 0 (length (org-map-entries #'timvisher-org-refile-done-entry "LEVEL=2/+DONE|+CANCELLED" nil 'archive))))) Here we're literally just doing the org-map-entries operation forever until the operation finds nothing to operate on. I worry about infinite loops and all that here though. It also just seems, well, a little brute force. Attempt 2 (defun timvisher-org-refile-done-entry (point) (let ((done-entry-position (timvisher-org-refile-done-entry-position))) (when (< done-entry-position point) (error (concat "Refile target at %d is located after the Done " "entry at %d. Move the Done entry to the bottom " "of the file.") point done-entry-position)) (goto-char point) (org-refile nil (current-buffer) (list "* Done" (buffer-file-name) nil (timvisher-org-refile-done-entry-position))))) (defun timvisher-org-refile-done-entries () (interactive) (seq-map #'timvisher-org-refile-done-entry (reverse (org-map-entries #'point "LEVEL=2/+DONE|+CANCELLED" nil 'archive)))) Here we're recognizing that if we could process the entries in reverse then we'd never have to worry about an entry moving from underneath us as we refile. This also seems silly: 1. I'm sure there's a function already that just returns me the matching entries for a given match search. Using the mapping API for seems incorrect. 2. It requires that the Done entry be below all possible targets which I'd rather not require. My Done entry is typically above my deferred entries and I want to be able to mark deferred entries as cancelled or done and have this work properly. Overall I actually like this attempt less than the first one. Attempt 3 I'm convinced that there must be something I can do with the org-map-continue-from var but I'm having a lot of trouble grokking how to use it properly. My initial attempt looks like this: (defun timvisher-org-refile-done-entry () (let ((entry-begin-point (point))) (org-refile nil (current-buffer) (list "* Done" (buffer-file-name) nil (timvisher-org-refile-done-entry-position))) (setq org-map-continue-from entry-begin-point))) (defun timvisher-org-refile-done-entries () (interactive) (org-map-entries #'timvisher-org-refile-done-entry "LEVEL=2/+DONE|+CANCELLED" nil 'archive)) The idea being that if I do in fact refile an entry I'd actually like the 'search to continue' from where it just was. This 'works' in that it successfully refiles all the entries even if they're consecutive but it also manages to get into an infinite loop because, AFAICT, it ignores the 'archive skipping somehow. I've spent some time in the debugger and I can't figure out yet why it does that. Any tips on how I might use this variable to achieve my goals? Thanks in advance! -- In Christ, Timmy V. https://blog.twonegatives.com http://five.sentenc.es [-- Attachment #2: Type: text/html, Size: 8140 bytes --]
next prev parent reply other threads:[~2021-05-12 13:37 UTC|newest] Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top 2021-05-06 14:23 Tim Visher 2021-05-11 4:56 ` Ihor Radchenko 2021-05-12 13:35 ` Tim Visher [this message] 2021-05-12 14:54 ` Ihor Radchenko
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style List information: https://www.orgmode.org/ * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to='CAHa53uy1q+PL1NYtahc_8L+TZ38zKQsfGALz5j1Rhzs=G76eXw@mail.gmail.com' \ --email@example.com \ --firstname.lastname@example.org \ --subject='Re: Refiling All '\''Terminal TODO State'\'' Entries to a Particular Heading' \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
Code repositories for project(s) associated with this inbox: https://git.savannah.gnu.org/cgit/emacs/org-mode.git This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).