5e8020aa38
Editor previews (colour swatches, arrows, embeds), the 18 obsidian-basics tasks (find and replace with regex, back/forward, auto-pair, footnotes, folding, search operators, split view, PDF/audio/ video embeds, spelling, drag and drop, pinned tabs, settings) and round 2: ```query blocks, stacked tabs, pop-out windows, tasks ticked inside embeds, text around an embed, embeds that follow edits, block menu shortcut. New crates: notescraft-regex (linear-time engine) and notescraft-syntax. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
12 KiB
12 KiB
NotesCraft vs Obsidian (core) — BASIC feature audit
Sources: SPEC.md §5/§6/§6.1, ROADMAP.md, docs/ARCHITECTURE.md, grep CommandSpec::new in crates/engine/src + crates/ui-egui/src, code greps. Status: built / partial / missing / unknown. Checked 2026-10-19.
Markdown and editing
| Feature | Status | Evidence | Missing |
|---|---|---|---|
| Footnotes (reference) | partial | Options::ENABLE_FOOTNOTES crates/markdown/src/scanning/common.rs:21 |
no Footnote AST kind or renderer; shows as raw text, no jump/back-link UI |
Inline footnotes ^[..] |
missing | no ^[ scan in crates/markdown/src |
not parsed at all |
| Horizontal rule | partial | slash menu divider entry (ui.settings…slash popup); Event::Rule unhandled in scanning/common.rs |
renders as plain --- text, no styled rule |
| Nested task lists, clickable checkboxes in rendered mode | built | edit_tests.rs:102 clicking_a_task_checkbox_flips_it; lines.rs item_task |
— |
| Bullet/numbered list folding | missing | no list-fold in note_view/blocks.rs |
no fold UI for lists |
| Heading folding (rendered) | partial | vim za → vim_edit.rs vim_fold (headings + callouts) |
no chevron/click fold without vim mode |
| Heading folding (source mode) | missing | no fold in views/center/source.rs |
no code-folding UI |
| Table editing helpers | partial | renders alignment card note_view/blocks/table.rs; blocks::insert makes table |
no add/remove row/col, sort, align-edit, no editing UI on rendered table |
==highlight== |
built | ItemKind::Highlight + Span::Highlight (markdown/src/lib.rs:126, note_view/inlines.rs:98) |
— |
%%comments%% |
built | ItemKind::Comment hidden in preview (inlines.rs:107) |
— |
| Math | built | math crate, math.render command, math_view.rs |
— |
| Callouts (foldable) | built | blocks.rs callout card + fold chevron; 13 types markdown/src/scanning/callouts.rs |
— |
| Code block copy | built | note_view/blocks/code_card.rs (Copy, Wrap) |
— |
| Embedded notes/headings/blocks | built | note_view/blocks/embed.rs (![[note#Heading]], #^id, cycle-safe) |
— |
| Embedded images with size | built | embed.rs images(ui, target, size); ![[img.png|300x200]] AST |
— |
| Embedded PDF rendering | missing | parsed only: Embed{subpath:page=3} markdown/src/lib.rs:406; no pdf embed code in note_view |
no PDF viewer |
| Embedded audio/video | missing | no mp3/mp4/audio/video refs in note_view or editor |
not rendered |
| Embedded search queries (```query) | missing | no query embed handling |
not supported |
| Link to heading/block with autocomplete | built | completion.rs Trigger::Heading/Block + autocomplete.rs |
— |
| Aliases in link autocomplete | built | widgets/autocomplete.rs:31 lists info.aliases |
— |
| Aliases in link resolution | built | index/src/lookup/resolve.rs:107 hit_by_alias |
— |
| Markdown links with spaces | built | links.rs decode_percent; CommonMark <path with spaces> via pulldown |
— |
| Auto-pair brackets/quotes | missing | no auto_pair/autopair in editor/src |
not implemented |
| Smart list indent/outdent | built | editor/src/keys.rs on_tab (Tab/Shift-Tab) + list continuation |
— |
| Spellcheck | missing | lint spelling rule is "slot only, never reports" (lint/src/rules.rs:38) |
no checker (owner decision pending per ROADMAP) |
| Find/replace in note (+regex) | partial | vim / ? n N :s :%s (vim crate); no GUI |
no find/replace dialog in normal mode |
| Word/char count | built | shell/statusbar.rs words/chars/tokens |
— |
| Line numbers | missing | no line-number gutter in note_view/center/source.rs |
— |
| Readable line length | missing | only ui.note_padding setting; no max text-width |
no readable-line-length cap |
| Font size setting | missing | editor.rs font_size hardcoded 16.0; Editor settings page has only Vim (settings_view/categories/editor.rs, 16 lines) |
no setting |
| RTL | missing | no rtl handling | — |
| Strict line breaks setting | partial | renders line-by-line (Obsidian default behaviour) | no toggle |
| Indent with tab/spaces setting | missing | on_tab fixed behaviour |
no setting |
| Default view mode for new tabs | missing | per-tab toggle only; no setting | no setting, no "always reading/live" |
| Open in reading mode | missing | no reading-mode-only open action | — |
Navigation and panes
| Feature | Status | Evidence | Missing |
|---|---|---|---|
| Split panes (vert/horiz) | missing | single editor area views/center.rs; no split code |
no splits |
| Stacked tabs | missing | flat tab strip views/center.rs |
— |
| Pop-out window | missing | single viewport; only ViewportCommand::Close (menubar.rs) |
no second viewport |
| Pinned tabs | missing | pin applies to folders only (context_menu.rs MenuKind::Pin) |
no tab pinning |
| Tab reorder by drag | missing | no drag/swap in views/center.rs |
— |
| Back/forward history (Cmd-[/]) | missing | no nav history anywhere in ui-egui |
— |
| Link hover page preview | missing | LinkOut.hovered used for styling only (painting.rs) |
no preview popup |
| Quick switcher (aliases/headings/blocks) | partial | widgets/palette.rs Mode: commands or note titles (view.switcher) |
searches titles only, no heading/block > search |
| Command palette | built | widgets/palette.rs, Cmd-K/P (window/frame.rs) |
— |
| Open random note | missing | no random command in engine command list | — |
| Open today's note | built | daily.note command (vault/daily.rs), menubar file.new_daily |
— |
| Folder notes | missing | no folder-note concept (folder view lists contents) | — |
| Outline pane | built | panels/right/outline.rs, jump on click |
— |
| Backlinks pane (linked + unlinked) | built | panels/right/backlinks_panel.rs with Link button on mentions |
— |
| Outgoing links pane | partial | engine links.outgoing command; no UI pane (only knowledge Related tab) |
no outgoing-links pane |
| Tag pane | built | panels/tags_panel.rs, click → search query |
— |
| Bookmarks | built | bookmarks.add/remove/list, bookmarks_view.rs |
— |
| Graph (local/global, filters) | built | views/graph_view/* incl. orphan/tags filters, local graph, drag-to-pin |
— |
| Graph groups (colour) | missing | graph_view/controls.rs has 3 filters only |
no colour groups |
| Graph timelapse | missing | none | — |
| Canvas | built | canvas_view.rs, canvas crate, SPEC §9 |
— |
| Explorer sort orders | partial | panels/tree.rs sort_tree: name, folders-first only |
no modified/created/reverse sort |
| Explorer drag-and-drop move | missing | tree drag payload targets assistant composer (tree.rs:465), not file move |
— |
| Reveal in Finder/Explorer | built | MenuKind::Reveal "Reveal in Explorer" (context_menu.rs:119) + Explorer reveal (phase 15) |
— |
| Open in default app | missing | no system-open action in context menu | — |
| Copy path / copy obsidian URL | partial | MenuKind::CopyPath (context_menu.rs) |
no obsidian:// URL copy |
| Rename updating links | built | note.rename + update_links_on_rename setting (prefs/config.rs) |
— |
| Move file to… | partial | rename dialog accepts folder path → note.rename moves |
no dedicated folder-picker move |
| Delete to trash | built | MenuKind::Delete → .notescraft/trash/ (vault/src/lib.rs:298) |
— |
| Duplicate (make a copy) | built | note.duplicate command + context menu |
— |
| Note composer (merge/extract) | missing | no such commands | — |
| Workspaces (saved layouts) | missing | deferred SPEC 6.1 | — |
| File recovery / snapshots | built | .notescraft/recovery/ mirror (shell/recovery.rs) + git auto-snapshot |
— |
| Templates with variables | built | templates crate, template.insert, {{title}}/{{date}} |
— |
| Daily notes | built | daily.* commands, folder/format/template settings |
— |
| Unique note creator | missing | no unique/timestamp command | — |
| Slash commands | built | slash.* commands + slash popup with groups |
— |
| Properties (typed, aliases, tags) | built | note.properties* commands, views/properties_view, types.json import |
cssclasses not special-cased (unknown) |
| Bases/database | missing | deferred SPEC 6.1 | by design |
| Hotkeys customisation | built | Settings → Hotkeys with capture (settings_view/categories.rs:158) |
— |
| Themes | partial | built-ins via theme.set; user-theme TOML loader exists (themes/src/load.rs) |
Session::themes() lists builtin_ids() only — vault themes not wired |
| CSS snippets | missing | none | — |
| Plugins (WASM host) | built | plugins.enable/disable, plugins crate (SPEC §7) |
no community browse page (ROADMAP pending) |
| Vault switcher | built | shell/app/vault/vault_switch.rs + recent vaults |
— |
| Multiple windows | missing | one egui viewport | — |
| Sync / Publish | missing | deferred SPEC 6.1 | by design |
| Audio recorder | missing | deferred SPEC 6.1 | by design |
| Web clipper | missing | deferred SPEC 6.1 | by design |
| Slides | missing | deferred SPEC 6.1 | by design |
| Zoom / UI scale | built | ui.zoom_*, Settings scale page |
— |
Settings and search
| Feature | Status | Evidence | Missing |
|---|---|---|---|
| Spellcheck language | missing | no spellcheck at all | — |
| Attachments folder setting | built | attachment_folder prefs/config.rs + Files & links page |
— |
| Link format (wiki/md, shortest/relative/absolute) | missing | resolve is basename-first, embeds always ![[name]] (vault/attachments.rs) |
no setting |
| Auto-update internal links setting | built | update_links_on_rename (Files & links page) |
— |
| Deleted files setting | missing | delete always to .notescraft/trash |
no OS-trash/permanent choice |
| Default location for new notes | missing | New note created in right-clicked folder | no default-folder setting |
| Trash behaviour | partial | internal .notescraft/trash/ with collision suffixes |
no restore/empty-trash UI found |
| Show hidden files | missing | no setting | — |
| Excluded files for search | missing | knowledge has excluded folders; search does not | — |
| Search operators | partial | path: file: tag: line: "phrase" -term OR (index/src/search/query.rs) |
no section:, block:, task:, match-case |
| Regex search | missing | /…/ → Error::Unsupported("regex search") (query.rs:171) |
regex crate not approved |
| Search result sort/collapse/context | partial | ranked hits + 2 snippets (search_panel/results.rs) |
no sort order, no per-file collapse, no extra-context toggle |
tag:/#tag click-to-search |
partial | tag pane click → search (tags_panel.rs:24) |
#tag in note body is not clickable |
| Search-and-replace across vault | missing | no replace in search panel or engine | — |
TOP 20 gaps for a daily user, most valuable first
- Find and replace in note (GUI) — S (edit over a buffer byte range exists; dialog + highlight loop)
- Back/forward navigation history (Cmd-[/]) — S (stack of open/scroll positions)
- Hover page preview on links — M (offscreen render of target already exists for snapshots)
- Split panes (side-by-side notes) — L (tab area becomes a pane list with per-pane render)
- Heading folding by click in visual/source mode — S (fold model exists for callouts/vim)
- Explorer drag-and-drop to move files — M (DnD payload exists; needs drop targets +
note.rename) - Explorer sort orders (modified/created/reverse) — S (
tree.rs sort_tree+ setting) - Footnote rendering (and inline
^[..]) — M (scanner + renderer + jump) - Auto-pair brackets/quotes + smart quotes — S (key handling in
editor/keys.rs) - Search-and-replace across vault — M (per-note replace via buffer edits, review UI exists from batch)
- Regex search — S (one dependency decision, wire into query parser)
- Quick switcher heading/block search — S (autocomplete data already indexed)
- Pinned tabs + tab drag reorder — S/M (tab strip already custom-drawn)
- Default view mode for new tabs / open in reading mode — S (per-tab toggle exists)
- Spellcheck — L (new dependency or in-house dictionary; ROADMAP blocks on owner)
- Line numbers + readable line length + font size setting — S each (editor opts already take font_size)
- Open in default app + copy obsidian URL — S each
- Outgoing links pane — S (
links.outgoingcommand already returns data) - Embedded PDF page rendering — L (pdf viewer; note there is already a
pdfexport crate) - Audio/video embed playback — M (audio sink exists for UI sounds; egui video is real work)