Diagram and display-math rendering: fenced mermaid blocks and $$...$$ paragraphs
become images that flow through the image pipeline under synthetic content-addressed URLs
(diagram-mermaid-<sha256> / diagram-math-<sha256>), so the cache reuses renders across
reparses and any edit to a block yields a fresh render.
Diff-mode subsystem: engine (pure line + word diff), hunk (data types),
state::DiffState (session state owned by EditorState::diff while Mode::Diff is
active), and layout (the stacked visual-line model shared by renderer and scroll math).
See docs/dev/diff-review.md.
The user manual (docs/*.md), include_str!d at build time and opened as pathless,
read-only in-memory documents (see crate::app::App::open_doc_page). Embedded rather
than extracted to disk so the manual can never drift from the build it documents and
there is no cache directory to manage. This module parses nothing — it owns static
strings and slug metadata only, which is what keeps it a leaf. See docs/dev/in-app-docs.md.
Document export. HTML is the built-in target and the intermediate format for
user-configured custom exports (custom, crate::config::CustomExportEntry), which
pipe it through an external converter. UI-agnostic: long-running work runs on a
background thread and reports completion through a caller-supplied FnOnce.
Image loading and caching: the document-layer half of image rendering (URL → decoded
DynamicImage). The UI half (decoded image → terminal cells) lives in ui::image_view.
Search-and-replace: SearchState (owned by EditorState::search while a flow is
active) plus a hard-bound key table (search_keys) that wins over the user keymap.
An active search does not change EditorState::mode; the flow is gated on
search.is_some() and app::actions::search_safe_action default-denies other actions.
Matching is literal substring, never regex, with backslash escapes for \n etc.
See docs/dev/search-replace.md.
Filesystem watcher. NotifyWatcher implements the FileWatcher trait over notify;
events are debounced (200 ms) before the worker thread reads the file and pushes one
[crate::app::AppEvent::Watcher]. The worker is the single owner of disk reads for the
watched file (organic events, the debounce timer, and force_reconcile all funnel through
do_read_and_send), so the main thread never blocks on I/O.