Skip to content

Latest commit

 

History

6 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Anki stats — an Omarchy bar widget

Shows how many flashcards are waiting, in your Omarchy bar. Click it for a panel of today's study stats; right-click to open Anki. It reads 0 when the queue is clear rather than disappearing, so a cleared queue never looks the same as a broken widget.

It works whether or not Anki is running. The widget reads collection.anki2 directly (read-only) instead of talking to AnkiConnect, which only answers while Anki is open — precisely when you don't need reminding.

Install

omarchy plugin add https://github.com/jcr-byte/omarchy-anki.git --enable

Plugins run unsandboxed inside your omarchy-shell process, so read the source first. There isn't much of it: a manifest, two QML files, and one Python script.

Update with omarchy plugin update jcr-byte.anki, remove with omarchy plugin remove jcr-byte.anki.

Settings

Set these on the widget's entry in ~/.config/omarchy/shell.json:

{ "id": "jcr-byte.anki", "includeNew": true, "refreshInterval": 300000 }
Setting Default Meaning
includeNew true Count unseen new cards in the total
refreshInterval 300000 Poll interval, milliseconds
launchCommand the bundled anki-open What right-click runs

Left click opens the stats panel, right click opens Anki, middle click forces a refresh. Hover for the breakdown without opening anything.

The panel

Left-clicking the pill opens a popup with three sections:

  • Today — answers, distinct cards, time spent and seconds per answer, the new/review/relearn split, and how many answers were Again.
  • True retention — the share of cards answered in the review state that passed, split into mature (interval ≥ 21 days) and young, with today's rate next to a 30-day rate for context. Learning and relearning answers are excluded, since drilling a card until it sticks says nothing about whether it was remembered. Each rate carries its passed/total, because a percentage off four answers is noise and only the denominator shows it.
  • Remaining — the due, learning and new counts the pill adds up.

The panel is a view over the same poll the pill uses; opening it costs no extra read of the collection.

It is also reachable from a keybind:

omarchy-shell jcr-byte.anki toggle   # the stats panel
omarchy-shell jcr-byte.anki study    # launch Anki
omarchy-shell jcr-byte.anki refresh  # re-read now

Right-click runs the bundled anki-open. It focuses the window whose class is exactly anki and starts Anki only when there is none, and it leaves a starting instance alone -- Anki takes seconds to map its window, and a second click in that gap would otherwise race a second copy for the collection lock and lose both.

It deliberately does not use omarchy-launch-or-focus, which matches its pattern against class or title and takes the first hit: any window with "anki" in its title -- an AnkiWeb tab, a terminal sitting in this plugin's directory -- gets focused ahead of Anki itself.

Both halves are arguments, anki-open [window-class] [launch-command], which is what flatpak users need -- a different window class as well as a different command:

{ "id": "jcr-byte.anki", "launchCommand": "~/.config/omarchy/plugins/jcr-byte.anki/anki-open net.ankiweb.Anki 'flatpak run net.ankiweb.Anki'" }

The guard that spots a starting instance looks for a process named anki; set ANKI_PROCESS if yours is named something else.

Daily limits

The count is capped by each deck's daily new/review limits, the same as Anki's own screen. An uncapped count sits at the size of the backlog and never reaches zero on a day the work is finished — a pill that reads 48 when Anki says 0 new is worse than no pill.

Those limits live in deck_config.config as a protobuf blob. The helper reads two integers out of it by field number rather than pulling in Anki's generated bindings. Field numbers are not a stable interface, so every parse failure falls back to the raw uncapped counts instead of guessing; the JSON reports which path ran as "limited": true|false.

Counts are rolled up per top-level deck tree and its preset applied once, which matches Anki whenever a tree shares one preset. Learning cards are never capped — Anki shows those past the daily limits too.

Requirements

  • Anki with collection schema 18 — every release from 2.1.50 (2022) through 26.x. Other schemas hide the widget rather than risk a wrong number.
  • python3 (already present on Arch).

Collections are found at ~/.local/share/Anki2 or ~/.var/app/net.ankiweb.Anki/data/Anki2 (flatpak), using the User 1 profile or else the first profile holding a collection. Override with ANKI_COLLECTION=/path/to/collection.anki2.

When the widget doesn't appear

It hides only when the collection can't be read or the schema isn't 18 — an empty queue shows 0. To tell which, run the helper by hand:

~/.config/omarchy/plugins/jcr-byte.anki/anki-due

It prints one line of JSON — counts, or an error explaining itself. A "stale": true line means the collection was momentarily unreadable and the last known counts are being shown; the widget dims itself when that happens.

Notes

  • Never writes to your collection: opened mode=ro with pragma query_only.
  • Polling creates collection.anki2-shm/-wal beside the collection. Standard SQLite WAL files that Anki itself makes and cleans up.
  • Day boundaries follow your Anki rollover hour (config.rollover), not midnight, matching Anki's own timing_today. The day number and the rollover do not line up: a collection created at noon with a 4am rollover starts day N sixteen hours after crt + N * 86400, so both the count and the "today" window are taken from the rollover itself.

License

MIT

About

Anki due-count and study-stats widget for the Omarchy bar. Reads collection.anki2 directly, so the count is there while Anki is closed.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages