Terminal Markdown previewer — GUI-like experience.
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge pull request #34 from RivoLink/docs/update-architecture

docs: update ARCHITECTURE.md

authored by

Rivo Link and committed by
GitHub
4e5a0dbf 76b9c073

+53 -25
+53 -25
ARCHITECTURE.md
··· 8 8 - reads the initial document or opens the file picker 9 9 - initializes terminal + syntax/theme assets 10 10 11 - - `src/app.rs` 12 - - central runtime state 13 - - document content, TOC, search state, watch state 14 - - theme picker + file picker state 15 - - cache invalidation and document replacement helpers 11 + - `src/app/` 12 + - `mod.rs` — central runtime state: document content, TOC, search, watch, editor config, mode detection (`has_content()`) 13 + - `file_picker.rs` — fuzzy and browser picker state, async loading via thread + mpsc channel, queue/pending lifecycle 14 + - `fuzzy.rs` — fuzzy matching algorithm and directory sort helpers 15 + - `search.rs` — search state and match tracking 16 + - `theme_picker.rs` — theme picker state with preview cache 16 17 17 - - `src/markdown.rs` 18 - - Markdown parsing and render preparation 19 - - heading, TOC, list, table, blockquote, code block rendering 20 - - width-aware wrapping helpers 18 + - `src/markdown/` 19 + - `mod.rs` — Markdown parsing and render preparation (headings, lists, blockquotes, code blocks) 20 + - `toc.rs` — TOC extraction and normalization 21 + - `tables.rs` — table rendering with alignment support 22 + - `width.rs` — width-aware helpers 23 + - `wrapping.rs` — line wrapping for constrained widths 21 24 22 - - `src/render.rs` 23 - - draws the TUI with `ratatui` 24 - - main content, TOC, status bar 25 - - modal rendering for help, theme picker, and file picker 25 + - `src/render/` 26 + - `mod.rs` — TUI layout orchestration with `ratatui` 27 + - `content.rs` — main content panel and status bar rendering 28 + - `modal.rs` — modal rendering for help, file picker, theme picker, editor picker, picker loading/failed states 29 + - `status.rs` — status bar construction (brand, filename, search, watch, shortcuts, percentage) 30 + - `toc.rs` — TOC sidebar rendering 26 31 27 32 - `src/runtime.rs` 28 33 - event loop 29 - - keyboard/mouse handling 34 + - keyboard/mouse handling with mode-aware branching (help → picker_loading → picker_failed → file_picker → theme_picker → editor_picker → search → normal) 35 + - picker queue processing and poll loop 30 36 - watch polling 31 37 - resize-driven render width synchronization 32 38 ··· 35 41 - active theme preset selection 36 42 - syntect theme mapping 37 43 44 + - `src/editor.rs` 45 + - editor detection, classification (terminal vs GUI), and launch 46 + 38 47 - `src/cli.rs` 39 48 - command-line parsing 40 49 - usage/version text ··· 43 52 - raw mode / alternate screen lifecycle 44 53 - terminal restore guarantees 45 54 46 - - `src/tests.rs` 47 - - regression tests for rendering and state behavior 55 + - `src/update.rs` 56 + - self-update: asset download, SHA256 verification, and binary replacement 57 + 58 + - `src/tests/` 59 + - `app.rs` — app state and mode detection tests 60 + - `file_picker.rs` — picker opening, fuzzy matching, sorting, truncation 61 + - `editor.rs` — editor detection and classification 62 + - `markdown.rs` — rendering regression tests 63 + - `render.rs` — table and code block border alignment 64 + - `theme.rs` — theme picker preview and restore 65 + - `update.rs` — release asset matching and checksum verification 48 66 49 67 ## Execution flow 50 68 ··· 53 71 - a file argument, or 54 72 - `stdin`, or 55 73 - the file picker if no input is provided interactively. 56 - 3. `markdown.rs` parses the source into rendered lines + TOC. 74 + 3. `markdown/` parses the source into rendered lines + TOC. 57 75 4. `App` stores the state and caches. 58 - 5. `runtime.rs` runs the event loop. 59 - 6. `render.rs` draws each frame from `App`. 76 + 5. `runtime.rs` runs the event loop: 77 + - processes pending picker queue → spawns loading thread 78 + - polls picker loading → installs results when ready 79 + - handles input events through mode-aware branching 80 + 6. `render/` draws each frame from `App`. 81 + 82 + ## Application modes 83 + 84 + - **Initial mode** (`!app.has_content()`): no file loaded, picker is the main view. Quit shortcuts exit the app. 85 + - **Preview mode** (`app.has_content()`): file loaded via argument, stdin, or picker selection. Quit shortcuts in pickers close the modal and return to the preview. 86 + 87 + ## Picker lifecycle 88 + 89 + 1. `queue_fuzzy_file_picker()` / `queue_file_picker()` sets `PendingPicker` 90 + 2. Main loop calls `start_pending_picker_loading()` → spawns thread, creates `mpsc::channel` 91 + 3. `poll_picker_loading()` does non-blocking `try_recv()` each tick (50ms) 92 + 4. Thread completes → result installed via `install_loaded_file_picker()` 93 + 5. Cancel: `cancel_picker_loading()` resets state to `Idle`, `Receiver` is dropped, thread finishes naturally 60 94 61 95 ## Important state transitions 62 96 ··· 76 110 - search: 77 111 - query state lives in `App` 78 112 - active match drives highlight + scroll position 79 - 80 - ## Current hotspots 81 - 82 - - `src/app.rs` still centralizes many responsibilities 83 - - `src/markdown.rs` is the densest module and the main future split candidate 84 - - `src/render.rs` is growing as more modal UI is added