Here's my use case: I'm maintaining Anki notes in my Org files using the [`anki-editor`](https://github.com/louietan/anki-editor) package. Every few hours during the day, I like to sync my Anki notes from Emacs to Anki using the following code:
(require 'persist)
(persist-defvar anki-editor-push-agenda-fast--last-pushed-time nil
"Time at which ‘anki-editor-push-agenda-fast’ last completed.")
(defun anki-editor-push-agenda-fast ()
"Push all anki-files fast.
Grep to find only Org files that *could* contain Anki notes, and then push all the
notes in those files."
(interactive)
(require 's)
(require 'anki-editor)
(dolist (f (s-split "\n"
(shell-command-to-string "rg -l -e :ANKI_NOTE_TYPE: ~/Documents/org")
'omit-nulls))
(save-excursion
(when-let*
((buf (org-find-base-buffer-visiting f))
((or buf
(or
(null anki-editor-push-agenda-fast--last-pushed-time)
(time-less-p
anki-editor-push-agenda-fast--last-pushed-time
(file-attribute-modification-time
(file-attributes f))))))
(buf (or buf (find-file-noselect f)))
((or
(buffer-modified-p buf)
(or
(null anki-editor-push-agenda-fast--last-pushed-time)
(time-less-p
anki-editor-push-agenda-fast--last-pushed-time
(with-current-buffer buf (visited-file-modtime)))))))
(with-current-buffer buf
(anki-editor-push-notes nil nil 'file)))))
(setq anki-editor-push-agenda-fast--last-pushed-time (current-time))
(org-save-all-org-buffers))
(defun anki-editor-open-note-in-anki ()
"Open the note at the current point in Anki."
(interactive)
(if-let* ((nid (org-entry-get (point) anki-editor-prop-note-id)))
(anki-editor--anki-connect-invoke-result
'guiBrowse
`((query . ,(format "nid:%s" nid))))
t
(user-error "Must be on an Org headline that contains the property ‘%s’"
anki-editor-prop-note-id)))
In particular, I grep all files to find only the ones that *could* contain Anki notes, and only push those files.
I've recently added an optimization using the `persist` library - namely, after each call to `anki-editor-push-agenda-fast`, I store the current timestamp. Then, I examine all files to find only the ones that could have changes since the last push, either because they're modified inside Emacs, or because the buffer or file's modtime is more recent. This has been working really well. `anki-editor-push-notes` is fairly slow, but fortunately, since I use `org-roam`, most of my Org files are pretty small, so I can skip examining most files.
What I'm wondering is whether there is a package that does the following:
- given a list of file names, it returns the filenames that could have been modified.
- it's important that Emacs doesn't read files into buffers if no buffer is visiting the file in the first place - initializing Org mode on all these files would be quite expensive, and it's unnecessary.
I'm looking to add this optimization in some of my other code, so if there's an existing package, I'd like to just use that. Otherwise, I think I'll try writing a general package for this.