Hello everyone, first-time poster here who just discovered Org-Roam this week.
I was poking around for a way to cobble together a bunch of Learning/Knowledge Management ideas using Emacs, and I happened to stumble on Org-Roam, which seems like exactly what I didn’t even know I wanted. I’m still getting set up and comfortable with it, but I have a question about a possible extension:
Has anyone incorporated any kind of spaced repetition to their workflow with Org-Roam? I saw Org-FC mentioned in the appendix of the documentation, but I haven’t done anything with it yet.
I’m specifically interested in Incremental Reading, which I think the ecosystem ought to support with a little configuration.
Even if nobody else has given this a shot, I’ll share my efforts once I start working on getting it up and running, but I didn’t want to reinvent the wheel if anybody has more thoughts than you can find at the Emacs Wiki incremental reading page or the Org-Drill page.
Thanks very much for the link, that package certainly looks great, and I plan to start using it with my basic flashcards. I’ve been hoping to find a way, though, to use an in-Emacs spaced repetition package, like org-drill (linked above) or org-fc in order to present information within emacs.
One example workflow might be to put my fleeting thoughts into spaced repetition in order to prompt me to refine them into permanent slips. If I wasn’t ready to work on it, I could “remember” it and have it pop up later.
Another might be to have a longer captured excerpt pop up based on the SRS algorithm and then I could capture some portion of it to create a new note with a backlink to the longer piece.
As I said in the OP, I’m still getting comfortable with the more basic functions of org-roam, but I look forward to trying to build out some workflows like the above.
I’m very interested in this - I’ve been using Anki/AnkiEditor, but so far it’s more to remember facts than for incremental reading. I’d like to use it for that too and would be interested to hear in any solution you come up with.
Thanks very much for those links! I wasn’t able to read the first without a membership, which was disappointing, but Andy Matuschak’s thoughts were really interesting and useful. I’ve vaguely tried some variations similar to what he talks about, like using some Anki cards to remind me to apply something, rather than just remember it, but his framework is much more complete. I could see that idea working nicely with org-roam by having a card that has links to others in an SRS set up, and the prompt is to read through the links or look for more connections and link them.
I guess you are using M-x my/space-repeat-if-tag-spaced, but I designed
the function to run automatically when you use M-x org-todo if you
have a tag :spaced: on the heading.
An example of heading:
TODO something I really want to learn :spaced:
SCHEDULE:<2020-09-23>
If you call M-x org-todo on it, it will be rescheduled in a spaced
repetition fashion.
In Elisp you can call a function with M-x only if it starts like:
(defun fun () (interactive) …)
I prefer Emacs doing things for me when possible, so I hid the thing
behind a hook (which runs the function after another action I do):
sorry for the late reply. My function should just mark it done and then set it to todo again. Also it should not be used interactively, but it silently works when you mark a headline as done. Instead of setting it as DONE, it will increase the repetition counter tag.
I like your way of doing spaced repetition using just the agenda. I feel that it is more suitable for relatively large and complicated notes that simple flashcards are too cumbersome to handle.
I tried your snippet and noticed something and I wonder whether you could offer some help.
I’ve added the :spaced: tag to a heading and called org-todo on it, then a new date was scheduled. When I open the agenda (M-x org-agenda), I would like to filter by the spaced tag so I get to see all the drill items separately from my normal TODO items. I tried to use the Match a TAGS/PROP/TODO query option, and after typing spaced to the prompt, the bottom bar shows Wrong type argument: arrayp, nil, with nothing showing up in the filtered results.
Any idea how I could achieve the tag filtering? Thanks
UPDATE: here is the messages I gathered after (setq debug-on-error 't) (:
seems to say that the CLOSED property (I guess in the logbook properties, not sure) has a problem.
The heading seems to be “TODO Move objects :drill:spaced:repetition0”
It is indeed something on my side. That CLOSED thing came from another snippet I copied from somewhere else (dont even remeber now). And there are other issues in my agenda settings, which turn out to be quite a mess. For instance, I found that (setq org-agenda-files (list "~/Notebooks/org")) somehow does not include all the org files in it, and that is causing the spaced-tagged headings not showing up. I’m still struggling to set things straight.
The seq-filter trick worked, I can also filter out some org files that I’d like to ignore now. Very helpful!
But there is no end to man’s laziness: could you help me create a function that i) sets the :spaced: tag to a heading and ii) makes a schedule to it? Then I could bind that to a key-binding and quickly set up a heading for SR.
Based on your code I guess it would somehow involve the org-set-tags-to and org-todo functions? My elisp is too poor to work that out.
Mmm, why don’t you use Org Capture for that? You just need a template
and it is easy to setup: Capture (The Org Manual)
So you can avoid most of the Elisp complexity
I guess Captures will do better for creating new headings. But I have already a good number of existing ones that I’d like to include into SR.
I think I’ve managed to craft up one which seems to function, at least for now:
(defun my-set-spaced-repetition ()
"When called on a heading: 1) append the :SR: tag if not already there, 2) set a schedule
to the next day (++1d)"
(interactive)
(if (org-current-level) (progn
(let* ((tags (org-get-tags))
(sr-tag "SR"))
(if (member sr-tag tags) (message "Already has SR tag.")
(progn (add-to-list 'tags sr-tag t) ; append SR to tag list
(add-to-list 'tags "repetition0" t)
(org-set-tags tags)
(message "Added SR tag to heading.")
))
(org-schedule nil "++1d")
))))
(global-set-key (kbd "C-c r") 'my-set-spaced-repetition)
Oh, well done Jason!! I have been amazing at Elisp
For curiosity (your code looks great) there is an append function in
Elisp to join lists, so you can do things like