org-anki
org-anki copied to clipboard
org-anki can't make `ANKI_NOTE_ID` property correctly with `with-current-buffer`
- Emacs version: 28.2
- org version: Org mode version 9.6 (9.6-??-bed47b437)
- org-anki version: 1.0.4 and latest (1.0.5)
test.org
#+ANKI_DECK: TestDeck
org-anki Batch Test
* Front
Back
Test code
(with-current-buffer (find-file-noselect "~/test.org")
(org-mode)
(save-excursion
(goto-char (point-max))
(org-anki-sync-entry))
(save-buffer))
The code makes an anki card but can't make ANKI_NOTE_ID
property at the heading. Emacs shows the org-fold-region: Calling ‘org-fold-core-region’ with missing SPEC
error. And :PROPERTY:\n:END:
is printed in the beginning of scratch buffer. I'm not sure. But My guess is that the message is that org seems to try parsing Users' current buffer which is scratch-buffer
.
After some digging, I found the cause of this issue is that org-anki
uses anki-connect
API request as asynchronous call. So, org-anki-sync-entry
can't org-set-property
in the buffer which is closed already.
@eyeinsky Is there any other way to solve this? emacs-request
provides :sync
keyword only. I feel buffer-local variable is a more reasonable option for this issue.
I thought adding sync buffer-local variables fix this issue simply. But I found that org-anki
is using emacs-promise
as well as emacs-request
.
Actually buffer-name
is changed to *scratch*
from test.org
when then
clause of promise-chain is executed.
https://github.com/eyeinsky/org-anki/blob/dda524d582d11d4f5317091da7335350d2d66640/org-anki.el#L434-L443
In addition, I found this https://github.com/chuntaro/emacs-promise/issues/13
According to the above issue, The below with-current-buffer
clause has a same potential issue.
https://github.com/eyeinsky/org-anki/blob/dda524d582d11d4f5317091da7335350d2d66640/org-anki.el#L542-L548
How did you come about in running in to this, do you run an elisp script to sync certain files without having the files themselves open?
I think I did manage to reproduce it by having test.org closed, then running the test code above from the M-:
(eval-expression) minibuffer prompt.
How did you come about in running in to this, do you run an elisp script to sync certain files without having the files themselves open?
Yes. I'm writing the code to generate and sync anki cards from part of my org files which have :ANKI:
tag automatically without user interaction. I, sometimes, forget to sync anki after editing bunch of my prompts following org-roam backlinks. I figure out batch ankifying is really useful if prompts are prepared already in the org files. You can see the test code is just simplyfing the error case. It's not real usecase.
I think I did manage to reproduce it by having test.org closed, then running the test code above from the M-: (eval-expression) minibuffer prompt.
Yes. Ensure the test file is closed and call the test code from scratch buffer or M-x <org-anki-sync-batch>(if you defined as an interactive function)
.
I managed to handle this. In order to solve this issue, it needs the synchronous emacs-promise
and the synchronous emacs-request
. sync request can be solved by #56. But emacs-promise side, it needs await
of the async-await
module.
async-await
doesn't block main thread. I think async-await
can be applied into org-anki
.
After applying #56, You can make an anki card using below code.
(require 'async-await)
(funcall (async-lambda ()
(with-current-buffer (find-file-noselect "~/test.org")
(org-mode)
(setq org-anki-sync-request t)
(save-excursion
(goto-char (point-max))
(await (org-anki-sync-entry)))
(save-buffer)
(kill-buffer))
(message "done")))
I'm running into the same problem: even though calling org-anki-sync-entry
succeeds and the note is created in anki, no ANKI_NOTE_ID
property is created at the header.
I'm on emacs 29, org-mode 9.6-??-bed47b4