Skip to content

fix(picker): render plain choice names without MarkdownRenderer - #2252

Merged
chhoumann merged 2 commits into
masterfrom
issue-2251
Oct 24, 2026
Merged

chhoumann merged 2 commits into
masterfrom
issue-2251

Conversation

@chhoumann

@chhoumann chhoumann commented Oct 23, 2026 •

Copy link
Copy Markdown
Owner

Fixes #2251.

Why

With Iconic enabled, Run QuickAdd took about a second to open on a large vault. The picker rendered every choice name with MarkdownRenderer.render. That call runs every plugin's Markdown post processors. Iconic's post processor reads metadataCache.getTags(), a scan of the whole vault, on every call before it looks for a tag. So 27 rows meant 27 vault scans per open, and more on each keystroke. The settings list had the same cost.

What changed

  • renderChoiceName now writes a plain name straight into <p dir="auto">, which is the output Obsidian's renderer gives for such a name. Names that use Markdown or HTML still go through the renderer.
  • The picker and the settings list now share renderChoiceName.
  • A name counts as plain when it uses only letters, digits, spaces, non-ASCII characters (except the line and paragraph separators), and ,.'"?;()-, and it does not open a list, an indented code block, or a www. autolink.

Scope

Blast Radius

Every picker row and settings row with a plain name skips the Markdown renderer. If the gate accepted a name that Obsidian renders differently, that name would show as literal text. The fuzz and e2e checks below found no such name.

Verification

  • Picker open time in an Obsidian 1.13.7 vault with 28k tagged notes and Iconic 1.1.11: about 905 ms → 2-8 ms. getTags() calls per open: 27 → 0. Settings tab: about 950 ms → 27-51 ms.
  • I rendered 4,730 names that the gate accepts through Obsidian's real renderer. All 4,730 matched the plain output byte for byte. The new tests/e2e/choice-name-render.test.ts checks the real picker against the renderer, and it fails if dir="auto" is removed.
  • Screenshots of the picker and of the settings list are byte-identical before and after the change.

Note

Render plain picker choice names as text without MarkdownRenderer

Adds an isPlainName classifier to renderChoiceName so ordinary names render as an automatic-direction text paragraph, while names with Markdown or HTML constructs still go through the async Markdown renderer. Routes ChoiceSuggester.renderSuggestion through the shared helper, keeping the existing rejection fallback. Adds unit and end-to-end tests covering plain names, Markdown-sensitive names, and HTML comparison against Obsidian's renderer.

Macroscope summarized 7573699.


Note

Medium Risk
Misclassified plain names would show literally instead of formatted Markdown; settings list callers no longer handle render promise rejections, though the picker still does.

Overview
Fixes Run QuickAdd slowness (#2251) by skipping Obsidian’s MarkdownRenderer for choice names that would render as plain text anyway, so third-party Markdown post-processors are not invoked once per row.

renderChoiceName now classifies names with isPlainName (allowed punctuation/Unicode, excluding list openings and www. autolinks) and writes them as <p dir="auto"> text; Markdown/HTML names still use await MarkdownRenderer.render with source path /. The function is async, and settings list plus ChoiceSuggester both route through this helper (the picker keeps its existing render-failure fallback).

Tests add plain vs markdown matrices, a picker integration check that only styled names hit the renderer, and an e2e test that picker row HTML matches Obsidian’s renderer output.

Reviewed by Cursor Bugbot for commit 7573699. Bugbot is set up for automated code reviews on this repo. Configure here.

Summary by CodeRabbit

  • Bug Fixes
    • Choice names now display consistently across choice lists and suggestions. Plain-text names, including punctuation, dates, and URLs, remain plain text, while names with Markdown formatting continue to render with their styling.
    • Improved handling of choice-name rendering so updated content appears reliably.

@coderabbitai

coderabbitai Bot commented Oct 23, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review.

Recent review info
Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: d2fdce73-e3c9-4318-b813-c9cd6aeb1a72
Commits

Reviewing files that changed from the base of the PR and between c2ea25a and 7573699.

Files selected for processing: 8
  • src/gui/choiceList/ChoiceListItem.svelte
  • src/gui/choiceList/MultiChoiceListItem.svelte
  • src/gui/choiceList/renderChoiceName.test.ts
  • src/gui/choiceList/renderChoiceName.ts
  • src/gui/suggesters/choiceSuggester.test.ts
  • src/gui/suggesters/choiceSuggester.ts
  • src/quickAddSettingsTab.test.ts
  • tests/e2e/choice-name-render.test.ts

Included review availability: This review used your included allowance. Your plan provides up to 8 included reviews per hour; 7 remain after this review.

Walkthrough

Choice names now use a shared asynchronous renderer. Names that meet the plain-text criteria are inserted as text; other names use MarkdownRenderer. The choice suggester and choice-list components call the shared helper, with unit and end-to-end tests covering rendering.

Changes: Choice Name Rendering

Layer / File(s) Summary
Shared rendering behavior
src/gui/choiceList/renderChoiceName.ts, src/gui/choiceList/renderChoiceName.test.ts, tests/e2e/choice-name-render.test.ts
The helper uses an owned paragraph and textContent for qualifying plain names. Other names go through awaited MarkdownRenderer.render. Unit and end-to-end tests cover both paths and compare rendered output.
Picker integration
src/gui/suggesters/choiceSuggester.ts, src/gui/suggesters/choiceSuggester.test.ts, src/gui/choiceList/*, src/quickAddSettingsTab.test.ts
ChoiceSuggester now uses the shared helper. Choice-list callers and settings tests explicitly discard the helper's return value where needed. Tests check plain and Markdown-styled names.

Priority: Normal

Estimated code review effort: 3 (Moderate) | ~20 minutes

Change: Bug fix · Severity of issue fixed: Medium

Sequence Diagram(s)

sequenceDiagram
  participant ChoiceSuggester
  participant renderChoiceName
  participant MarkdownRenderer
  participant ChoiceRow
  ChoiceSuggester->>renderChoiceName: pass choice name and rendering context
  alt plain-text criteria match
    renderChoiceName->>ChoiceRow: set textContent in owned paragraph
  else markdown rendering required
    renderChoiceName->>MarkdownRenderer: render choice name
    MarkdownRenderer-->>renderChoiceName: return rendered content
  end
Loading
Merge Risk: Minimal · up to 75736

The rendering change is ready to merge after normal checks; no actionable issue remains identified.

Pre-merge checks: Passed 5
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title "fix(picker): render plain choice names without MarkdownRenderer" matches the main change. The PR writes eligible plain choice names directly into a paragraph in the picker and settings list…
Linked Issues check Passed Issue #2251 requires the QuickAdd picker to open near-instantly with Iconic enabled. The change routes picker rows through renderChoiceName, writes eligible plain names directly to <p dir="auto">,…
Out of Scope Changes check Passed The changes remain connected to #2251. The shared helper, settings-list integration, rejection fallback, unit tests, and end-to-end rendering test support the same rendering and performance change. No…
Docstring Coverage Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 2 functions across 6 files. (2 skipped: 2 …
Full details: Title check

Explanation

The title "fix(picker): render plain choice names without MarkdownRenderer" matches the main change. The PR writes eligible plain choice names directly into a paragraph in the picker and settings list. Names with Markdown or HTML constructs still use MarkdownRenderer. The title names the picker scope and the bypass of MarkdownRenderer, so a reviewer can see the primary change. It uses the conventional commit prefix and is 63 characters long, within a reasonable limit.

Full details: Linked Issues check

Explanation

Issue #2251 requires the QuickAdd picker to open near-instantly with Iconic enabled. The change routes picker rows through renderChoiceName, writes eligible plain names directly to &lt;p dir="auto"&gt;, and keeps Markdown rendering for names that need it. This removes the repeated Markdown post-processor calls for ordinary choice names. Unit, suggester, and end-to-end tests cover the classifier and compare picker output with Obsidian's renderer.

Full details: Out of Scope Changes check

Explanation

The changes remain connected to #2251. The shared helper, settings-list integration, rejection fallback, unit tests, and end-to-end rendering test support the same rendering and performance change. No unrelated product behavior or unrelated files appear in the reviewed diff.

Full details: Docstring Coverage

Explanation

Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 2 functions across 6 files. (2 skipped: 2 unsupported.)

Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

A rabbit hops past names in flight
Plain words land as text just right
Bold marks take the markdown trail
Tests check each rendered detail
The picker rows now greet the light

Comment @coderabbitai help to get the list of available commands.

@chhoumann
chhoumann marked this pull request as ready for review October 24, 2026 07:10
@chhoumann

Copy link
Copy Markdown
Owner Author

Independent verification: PASS (an agent that did not write the change ran it in Obsidian 1.13.7, with a 28k-note vault and Iconic 1.1.11 enabled).

  • Plain names: picker opens in 2.4-9.5 ms. getTags() calls: 0 on open, 0 on a typed query.
  • Names sent through the renderer (the pre-fix path): 912-988 ms, with 27 getTags() calls on open and 12 on the query.
  • A Markdown name still renders <strong> in the picker.
  • tests/e2e/choice-name-render.test.ts passes.

The verdict ran on ed0d14f7. The head 7573699a differs only in comments, and both build a byte-identical main.js.

@chhoumann
chhoumann merged commit 59721f2 into master Oct 24, 2026
17 of 18 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] QuickAdd: Run QuickAdd" picker takes ~1 s to open when Iconic is enabled (~8 ms without it)

1 participant