Super Smart Random Note

approved

by zakin

Open random notes matched by saved filters written in Obsidian's search query syntax. - This plugin has not been manually reviewed by Obsidian staff.

52 downloadsUpdated 14d agoMIT

Super Smart Random Note

Open random notes matched by saved filters, written in (a subset of) Obsidian's own search query syntax.

  • Default command — "Open random note (default)", always available. Query is empty by default, meaning "any note in the vault".
  • Custom commands — define as many named filters as you want in the plugin settings. Each one becomes its own command in the command palette (bindable to a hotkey, launcher plugins, etc.).

Why a reimplementation instead of Obsidian's real search engine?

Obsidian doesn't expose its internal search engine through the public plugin API — there's no documented way to hand it a query string and get back a list of matching files. This plugin ships its own parser/evaluator that follows the same documented operators (see "Supported syntax" below), evaluated directly against each note's content (frontmatter included) plus its tags from the metadata cache. It is a close but not pixel-perfect clone of core search — see "Known differences" below.

Supported syntax

OperatorMeaningExample
(bare word)Note content contains the wordmeeting
"phrase"Note content contains the exact phrase"kickoff meeting"
/regex/Note content matches the regex (flags allowed, e.g. /foo/i)/\d{4}-\d{2}-\d{2}/
file:Match against the file namefile:.png
path:Match against the full file pathpath:"Journal/2026"
content:Match against the full note content (same as bare word)content:"happy cat"
tag:Note has this tag (nested tags included, e.g. tag:#work matches #work/meeting)tag:#idea
line:At least one line matchesline:(mix flour)
section:At least one heading section matches (best-effort split on heading lines)section:(dog cat)
block:At least one paragraph/block matches (best-effort split on blank lines)block:(dog cat)
task:At least one task line (- [ ]/- [x]) matchestask:call
task-todo:At least one unchecked task line matchestask-todo:call
task-done:At least one checked ([x]) task line matchestask-done:call
[key]Frontmatter property key exists and is truthy[status]
[key:value]Frontmatter property key equals value (or contains it, for list properties). Wikilink-valued properties (- "[[Poems]]") match on the link's target/alias text, not the bracket syntax[status:Draft], [types:poems]
[key:v1 OR v2]Property equals any of the given values[status:Draft OR Published]
ORLogical or (must be uppercase, space-separated)meeting OR work
-Exclude (prefix, no space before the term)meeting -work
(space)Implicit ANDmeeting work
(...)Groupingmeeting (work OR personal)
field:(a b)Distributes the field over each grouped termtag:(idea work) → has both #idea and #work

Matching is always case-insensitive, except inside /regex/ literals (add the i flag yourself if you want a case-insensitive regex).

Known differences from Obsidian's built-in search

  • No "Match case" toggle — everything but explicit regex is case-insensitive.
  • section: and block: use a simple heuristic (split on heading lines / blank lines) rather than Obsidian's real block/section parser.
  • No fuzzy matching — all text matching is plain substring (or regex).
  • Bare words and content: only look at note content, not the file name — use file:/path: explicitly if you want to match on the name.
  • Reads every markdown file's content on each random-note request (via the cached vault read), so very large vaults may see a brief delay.
  • [key:value] properties are read with a small built-in YAML frontmatter parser (not Obsidian's metadataCache, which updates on a debounce and can briefly miss a property you just added) — it covers scalars, quoted strings, inline lists ([a, b]), and block lists (- item), but not full YAML (no nested maps, multi-line strings, anchors, etc.).
  • An unrecognized word: immediately followed by a space (or the end of the query) — e.g. types: poems — is a query error, not a search: it looks exactly like an attempted property filter but silently splitting it into two unrelated bare-word terms (types: and poems, found anywhere in the file independently) would return a plausible-looking but wrong count. Use [types:poems] for a real property filter, or quote it — "types: poems" — to search that literal text as a phrase. foo:bar (no space) still works as one literal token, e.g. for a URL.

Settings

  • General — "Open notes in" sets the vault-wide default (same tab / new tab / new window) for every command.
  • Commands — one row per command: the always-present "Default" row plus every custom filter you add. Click a row's name (or its gear icon) to edit its query and optionally override where that command opens notes; the search icon previews how many notes currently match; custom rows also get duplicate and delete icons. Type a name at the bottom and hit "Add command" to create a new filter, then edit its query from its row.

Development

npm install
npm run dev    # watch build
npm run build  # type-check + production build
npm run lint   # eslint (typescript-eslint recommended-type-checked)

Copy main.js, manifest.json, and styles.css into <vault>/.obsidian/plugins/super-smart-random-note/ to install manually, or add the repo to BRAT.

The settings tab implements Obsidian's declarative getSettingDefinitions() API (1.13.0+) with the old imperative display() kept as a fallback for older versions — both paths share the same row-rendering code.

Prior art

The command-row-plus-modal editing UX is modeled after obsidian-advanced-random-note. obsidian-lottery was also a reference for the general idea of filtered random-note picking.

For plugin developers

Search results and similarity scores are powered by semantic analysis of your plugin's README. If your plugin isn't appearing for searches you'd expect, try updating your README to clearly describe your plugin's purpose, features, and use cases.