Mir is a package for incremental reading inside Emacs.
Incremental reading is a continuous process of importing, refining, memorizing and dismissing articles, which are further referred to as “topics”. A “topic” is any piece of text that you want to process. Processing in this case means:
- Importing the text into the system and scheduling when the newly created topic will be shown to you.
- Reading the topic whenever it’s scheduled.
- Making extracts and/or turning some of the text into permanent notes, flashcards, etc.
- Repeating across many days until you feel that the potential of the topic is exhausted, at which point you dismiss it.
Mir automatically schedules reviews for you, thereby increasing your familiarity with the text and strengthening the memory of the concepts within. However, mir’s scope currently does not extend into letting you turn topics into flashcards or do cloze deletions. This violates the minimum definition of incremental reading. Support for these features is in the works.
Caution: The process of incremental reading is best used with material that evokes curiosity and is inherently interesting. See the “Be careful with what you read in mir” section below for more details.
(use-package mir
:vc "https://github.com/gvalson/mir"
:commands (mir-import-buffer mir-extract-or-import-from-region)
:config
(setq "mir-archive-directory" (expand-file-name "~/Documents/mir")))Ensure that emacs is compiled with SQLite support and that the following packages are installed:
denotedenote-sequence
Then ensure that mir in your load-path, and put this in your init file:
(require 'mir)First of all, choose a folder where you’ll keep all your topics.
Everything that you import is saved in this directory as a file, so
make sure that you can access the directory comfortably in case you
want to make any manual adjustments. This variable defaults to
~/Documents/mir.
Now comes the time to import. You can use the following functions for this:
mir-import-buffer: Imports the currently opened buffer.mir-extract-or-import-from-region: Imports the selected part from the current buffer.mir-import-from-minibuffer: Enter your text via the minibuffer and import it.mir-import-file: Select a file and import it as a topic.
Each of these commands will ask you to type in a priority. Much like in SuperMemo, the topic’s priority represents its relative importance and ranges from 0 to 100. More important items have a lower priority value. Thus, an item with the priority value 0 is the most important in the collection and will appear earlier than others. If this is your first day with using mir, stop here. Your imported topics will be readable tomorrow.
Next day, run mir-read to start reading. You should see a new buffer
show up with one of your imported topics. Feel free to use
mir-extract-or-import-from-region to extract an important chunk out
into its own topic. You may also use any other command, as the buffer
is just like any other emacs buffer. When you’re done reading or
simply wish to move on, invoke mir-read-next. You can continue until
the queue runs out, after which you can either import more items or do
something else.
Generally, you should not worry about topics running out. As you get more familiar with the process and import more articles, you’ll have a near-endless stream of information. This is why assigning priorities are important: you’ll see high-priority items first.
When a topic has exhausted its value, use M-x
mir-dismiss-current-topic to dismiss it. A dismissed topic will no
longer show up when reading, but it will still be preserved in
mir-archive-directory with a keyword archive being added to its
file name. The dismissed topic will also be kept around in the
database. Dismissal is preferred over deletion, as it prevents
accidental loss of important topics. Note that currently there is no
way to fully delete topics without manually changing the database.
When using mir, you can gradually refine the imported material by making small changes across each review. To that end, mir provides the following functions for changing the topic metadata:
mir-set-priority: use this to reprioritize the topic. After invoking the command, the topic’s actual priority value may be slightly different than what you typed since priority values are normalized to be evenly distibuted between 0 to 100.mir-set-a-factor: manually set the A-factor, which governs how fast the intervals between reviews grow. If you want to use this, make sure to setmir-scale-a-factor-by-prioritytonil.mir-set-title: change the title of the current topic.mir-reschedule: Manually reschedule the topic to a set date.
What might be more important to you, however, is changing the topic’s content. There’s nothing special necessary to accomplish this: mir only cares about the file’s name in order to make its operations work. Mir does not check the file’s actual content. You’re free to edit the file as you wish (including changing its extension), as long as the ID at the beginning of the file name is preserved.
Rescheduling via mir-reschedule or lowering an element’s priority
with mir-set-priority may look similar on the surface, but they do
different things.
First, let’s examine what changing the element’s priority does. Let’s say that the priority was lowered from 10 to 50 (higher value means lower priority). This means that, on the day when the topic is scheduled to be shown, it’ll be shown much later than other topics. If, for instance, there are 100 topics that have priority values 10–50, the element will shown right after those 100 topics. Note how, when changing the priority, nothing changed about scheduling and time.
On the other hand, using mir-reschedule makes it so that the element
maintains its priority but it’ll be delayed in terms of time. Delaying
a high-priority item is a good way to postpone reviewing it, as the
high priority makes it almost certain that it’ll be looked at.
By default, topics are shown in strictly descending priority order.
This makes it so that the most important topics are displayed first.
However, you may end up in a situation where only a narrow subset of
the topics are shown to you day after day, especially in a larger
collection and especially if you don’t review a lot of topics
consistently every day. To remedy that, you can configure the variable
mir-randomize-topics-ratio. Its default value is 0.0, meaning that
0% of the queue is randomly shuffled. You can start with 0.2 (meaning
that 20% of the topics in the queue get shuffled) and later adjust to
your preference.
If you find yourself reading an extract and wanting to look at the
topic where the extract came from, you can use the command
mir-find-parent. It leverages the sequence information encoded in
the file name to find and open the parent of the current topic. For
more information, see the manual of denote-sequence, which powers
this functionality.
You can use mir-show-topic-hook to do something every time a new
topic is shown. For example, you can make it so that HTML files opened
with web-mode get displayed with emacs’ built-in web browser eww:
(add-hook 'mir-show-topic-hook
(lambda ()
(when (eq major-mode #'web-mode)
(progn
(eww-open-file buffer-file-name)
;; Important: vital mir functions won't work without
;; this.
(mir-topic-minor-mode)))))Be careful if you want to use the snippet above, however, as currently extracts from eww buffers are unreliable. This is a known issue.
Mir uses SQLite to store scheduling information and review history. By
default, the database file is located in mir-archive-directory and
named mir.db. The name and location is configurable via
mir-db-location. You can use emacs’ built-in sqlite-mode-open-file
command to inspect the database.
By default, imported topics are not scheduled until the day after they are imported. This is because:
- There may not be much novel information extracted if you already read the topic outside of mir on the same day before importing it.
- Waiting before looking at the topic allows for the mind to consolidate the disparate pieces of knowledge needed to understand it. This results in better comprehension and thus more pleasurable reading.
This behavior can be changed through the variable
mir-default-topic-interval. Set it to 0 to add the imported topics
to the queue immediately.
Using mir to read some specific material eventually results in you seeing it many times. This can be both benefitial and detrimental and that depends on your relationship with the material. If you find the material incomprehensible, boring, too heavy or generally unsuitable to your present needs, mir will amplify these feelings tenfold by showing the material over and over again. Thus, mir is best used with material that you find inherently interesting—that you’d study even if no one told you to look into it.
Note that, presently, all resources about IR assume that you’re using SuperMemo. This is due to the fact that SuperMemo was the first to implement IR in its entirety.
- Flashcard Guy (YouTube)
- What is incremental reading? (youtube)
- Starting with Incremental Reading by going through the IR Manual
- SuperMemo help: Incremental learning
If neither SuperMemo nor mir are your cup of tea, you can get at least some features of incremental reading with these tools:
- RemNote with the incremental-everything plugin.
- https://dendro.cloud/
- Anki with this add-on: https://github.com/tvhong/incremental-reading
This project was greatly aided by Prot’s denote and denote-sequence packages. Denote provides a consistent file naming and identification scheme and tools to work with said scheme, which greatly simplifies the logic of dealing with unique topics. In addition, denote-sequence makes working with the tree-like structure of extracts much easier, allowing for dynamically generating sequence numbers and easy traversal of the hierarchy.
Incremental reading was pioneered by Piotr Wozniak and SuperMemo.