semsevens3k downloadsRecord where your attention went — highlights and comments on notes, transcripts and subtitles — then revisit them. Never modifies the original file.
Attention is now part of Media One, as its Annotations module. Install Media One (formerly Media Transcript) from the community plugins, disable Attention, and reload Media One: it takes over your Attention settings. This plugin gets no further updates.
Record where your attention went — then run into it again.
Highlight and comment on notes, PDFs, transcripts and subtitles, and revisit what you marked. Annotations live in a sidecar file next to the original; the original file is never modified.
Most annotation plugins write
==highlights==into your notes. This one doesn't touch them. Most review plugins resurface whole notes, or highlights imported from a third-party service. This one resurfaces the passages you marked, wherever you marked them.
Select text in a note and a small bar appears: Mark it, or 💬 to write a comment. Click a picture for Mark, 💬 and 🔍 — zooming is still there, just no longer the only thing a click can do. A marked picture gets a ring rather than an underline, and behaves like any other mark from there. Turn that off in settings to capture only deliberately.
Either way, right-click a selection for the full menu:
Click a mark to read its comment and see every time that passage caught you; right-click it to edit or remove.
Marking something already marked doesn't create a second mark — it records
another hit. A line that moves you three times over a year is the strongest
thing this plugin can know about you, and the panel shows it as 3×. In editing modes these are appended to Obsidian's own context menu;
reading mode gets its own, raised only when there is something to offer.
The ribbon's highlighter icon opens the panel, which has two views of the same annotations:
Marks follow the note as you edit it — text inserted around them shifts them, text typed inside them widens them. A passage deleted or replaced outright can't be followed, so its mark is listed as lost rather than quietly discarded: it keeps its words, its comment and every time it caught you, and can be re-attached to a new selection without losing any of that.
Sort either view by document position, when it was last or first marked, or how many times it caught you. Hovering an entry reveals buttons to mark it again, comment on it, or remove it without going to find it first; right-click gives the full menu. The count appears only once a passage has caught you more than once. Clicking an entry jumps to the passage and flashes it. The panel appears on its own when you open a note that has annotations, and stays out of the way when you open one that doesn't.
Off by default; turn it on under How notes open.
Marks live beside the note rather than in it, so reading mode costs nothing here — you can highlight and comment without ever leaving it. That makes it the natural way to hold material you collected in order to read it: the note stops inviting stray keystrokes, and nothing you do to it can be a typo.
It is not read-only. Obsidian has no such thing, and this doesn't invent one: Ctrl+E still switches to editing, and the file stays writable.
Everything else opens as — the vault-wide default.
Exceptions by folder — somewhere you write rather than read. The deepest
matching folder wins, so raw can be reading while raw/drafts is not.
Frontmatter overrules both, using the same keys as the Force note view mode plugin, so notes already carrying them keep working:
obsidianUIMode: preview # or: source
obsidianEditingMode: live # or: source
The mode is chosen when a note is opened, and only then. Press Ctrl+E to fix a typo, glance at another tab, come back — you are still editing. Plugins that force the mode on every activation need an "ignore open files" switch to escape that; not reconsidering is simpler and never surprises you.
Running a separate view-mode plugin alongside this will make them fight — whichever acts last wins, and the winner can change from open to open. Pick one.
Everything works, with the gestures a phone has:
==highlight==Obsidian's own highlight is markdown syntax living in the note. That makes it sturdier than anything here — it cannot lose its anchor, because it is the text — and it travels to any markdown tool. What it can't do is carry a comment, a colour, or a date, or tell you what you marked last week; and it edits the file to exist at all.
Timestamps use a moment format string — the same vocabulary as daily note
filenames — defaulting to YYYY-MM-DD HH:mm:ss. Clear it for relative times
("3 days ago"), which follow your Obsidian's language.
Marks share one colour, set in settings. Choosing a swatch every time turns noticing something into a decision, and how often a passage caught you carries more than which shade you picked.
Marks are drawn as an underline by default. They are meant to be many, a page of
filled blocks is unreadable, and a background fill looks exactly like
==highlight== — the one thing worth telling apart. Annotations carrying a
comment get a little more weight. Switch to a background fill in settings.
Working: markdown notes and — when Media Transcript is installed — its transcript panel. Marking a transcript line records the moment it happens at, so the review panel can put you back there: clicking the entry seeks the player and plays.
Transcript marks belong to the media file rather than to a subtitle track, and are re-found by timestamp and quote, so re-transcribing with a different engine doesn't orphan them.
PDFs, when PDF++ is
installed: select text and Mark or 💬 it, or use PDF++'s right-click menu,
which gains Attention's items. A figure, a table or a formula has no text to
select — draw over it with PDF++'s rectangle tool, and it can be marked too; the
panel shows the region itself. PDF++ does the selecting and drawing, so marks sit
exactly where its own highlights would at any zoom; Attention keeps its record in
x.pdf.anno.json, and the PDF is never modified. Many PDFs store Chinese as
look-alike radicals (⼒ for 力); quotes are shown, copied and searched as the
ordinary characters.
See docs/architecture.md for the design and what's
still open.
lecture.mp4 ← never touched
lecture.mp4.anno.json ← your highlights and comments
周报.md ← never touched
周报.md.anno.json
One sidecar per annotated file, named after the target's full filename. Portable (move the media, take the annotations), sync-friendly (a conflict touches one file, not your whole library), and readable.
A highlight and a comment are the same thing — a comment is just an annotation with a body — so they share one file and one anchor.
Not spaced repetition. The goal isn't to memorise a passage, it's to run into it again, so there's nothing to grade:
npm install
npm run build
cp main.js manifest.json styles.css <vault>/.obsidian/plugins/attention/
MIT
npm install
npm run dev # esbuild watch — rebuilds and copies into the dev vault on every save
npm test # vitest, watch with: npm run test:watch
npm run dev copies main.js, manifest.json and styles.css into
every vault listed in .dev-vault (one per line — the development vault, and
nothing you read in) after every rebuild
(styles.css is watched separately, so CSS-only edits deploy too). Point it
elsewhere with VAULT_PLUGIN_DIR=/path/to/vault/.obsidian/plugins/attention,
or set it empty to skip deploying.
The development vault is in this repository: fixtures/vault. Open it in
Obsidian as a vault of its own and list it first in .dev-vault; see
fixtures/README.md for what each note is for and which
plugins it needs.
Copy, not symlink — this repo lives in iCloud Drive, and aiming a vault at an iCloud path risks Obsidian stalling on an evicted file.
Install hot-reload in the dev vault and
Obsidian will reload the plugin on every rebuild; the build already writes the
.hotreload marker it looks for. Without it, reload manually.
npm test covers the pure logic — anchoring, sidecar path rules, the review
policy — and placing a reading-mode selection against the DOM Obsidian draws
(under happy-dom). All of it decides whether a passage you marked can still be
found and shown to you again, and all of it fails silently when wrong, which is
exactly what clicking around does not catch.
npm run e2e checks the rest in a running Obsidian, with the fixtures vault open:
thousands of random selections across every note, each checked to be captured as
the source the reader was looking at, and jumping to a mark from the review panel.
Point it at a real vault to find the next case:
E2E_VAULT=~/path/to/vault E2E_FOLDER=some/folder E2E_NOTES=12 npm run e2e
npm run try
runs the unit tests and npm run e2e, and only if both pass installs a
production build into the vault named in .try-vault (gitignored; one path).
Ordinary builds never go there. The next release — or reinstalling from the
community browser — puts the released version back.
How a release goes out — versions, tagging, the community directory's automated
review and what it rejects — is written down in the maintainer's notes,
obsidian-plugin-publishing
(a private repository; check it out next to this one). In short: run the
review's lint rules locally first, bump manifest.json, package.json and
versions.json together, push a tag equal to the version (no v), and check
the community directory's review for that version before calling it released.