A terminal markdown reader and task manager built with Rust, ratatui, and crossterm. Renders markdown with syntax highlighting, word wrapping, and live file watching — all without leaving the terminal.

Run mdr <file.md> to open a file in reader mode. Press f to open the file picker overlay — type to filter, enter to select.

Features

  • Markdown rendering — headings, bold, italic, strikethrough, code blocks with syntax highlighting (via syntect), blockquotes, tables, ordered/unordered lists, task lists, horizontal rules. Inline code renders with a subtle background highlight.
  • Cursor navigation — line-by-line cursor with highlighting, Vim-style page scrolling (Ctrl-f/Ctrl-b)
  • Word wrapping — proper continuation indentation for nested lists
  • Live reload — file watcher detects changes and re-renders automatically
  • Multiple tabs — open several files, switch with Tab/Shift-Tab, close with q
  • File picker — press f to open an overlay listing .md files. Fuzzy search (nucleo-matcher) to filter, arrow keys to navigate, enter to open
  • Search — press / to search, n/N to jump between matches
  • Task list support — toggle checkboxes with x or Space, jump between tasks with Ctrl-n/Ctrl-p, filter to unchecked tasks with u
  • Inline #tags — Obsidian-style inline tags render in theme-defined label colors. Recognized labels: feature, improvement, bug, refactor, docs, chore, data, model, experiment
  • Label picker — press l to filter the document by tag with fuzzy matching. Filters stack with the unchecked task filter for compound views (e.g. unchecked features only)
  • Section folding — press Enter on a heading to collapse/expand, [/] to fold/unfold all. Each heading folds independently.
  • Table of contents — press o for an outline overlay listing all headings with indentation. Jump to any section.
  • Follow links — press Enter on a markdown link to open .md files in a new tab or URLs in the browser
  • Bookmarks — press b to toggle a bookmark (shown as in the gutter), '/" to cycle between them, B to open the bookmark list
  • Configurable themes — 9 themes defined as individual TOML files in ~/.config/mdr/themes/, each with a named color palette, UI role mappings, and category label colors. Truecolor (24-bit RGB).
  • Gutter — dedicated column for fold indicators and bookmark markers
  • Scrollbar — configurable via ~/.config/mdr/config.toml
  • Mouse scroll — scroll the viewport with the mouse wheel
  • External editor — press e to open the file in $EDITOR
  • Help modal — press ? for a keybinding reference
  • Esc clears all — press Esc to reset all active filters (search, tags, tasks) at once

Key bindings

KeyAction
j / k / arrowsMove cursor up/down
g / GJump to top/bottom
Ctrl-f / Ctrl-bPage down / up
EnterFold/unfold section, or follow link
[ / ]Fold all / unfold all
x / SpaceToggle task checkbox
Ctrl-n / Ctrl-pNext/previous unchecked task
uToggle unchecked task filter
lFilter by label (fuzzy)
oOutline / table of contents
bToggle bookmark
BBookmark list
' / "Next / previous bookmark
/Search
n / NNext/previous match
fFile picker
eOpen in $EDITOR
tTheme picker
Tab / Shift-TabNext/previous tab
?Help
EscClear all filters
qClose tab / quit
Ctrl-cQuit

Configuration

Settings are persisted to ~/.config/mdr/config.toml:

1theme = "tokyo night moon"
2scrollbar = true

Themes live in ~/.config/mdr/themes/ as individual TOML files with a named color palette, UI role mappings, and label colors:

 1[colors]
 2fg = "#c8d3f5"
 3bg_highlight = "#2f334d"
 4fg_gutter = "#3b4261"
 5comment = "#636da6"
 6red = "#ff757f"
 7green = "#c3e88d"
 8blue = "#82aaff"
 9magenta = "#c099ff"
10teal = "#4fd6be"
11orange = "#ff966c"
12# ...
13
14[ui]
15border = "fg_gutter"
16accent = "magenta"
17heading = "blue"
18error = "red"
19cursor_bg = "bg_highlight"
20# ...
21
22[labels]
23bugs = "red"
24features = "green"
25improvements = "magenta"
26refactor = "yellow"
27docs = "blue"
28chore = "comment"
29data = "teal"
30model = "purple"
31experiment = "orange"

Ships with 9 themes: synthwave, monochrome, ocean, sunset, matrix, tokyo night moon, classic, fire, purple.

Architecture

Single-threaded event loop with a minimal UI — a status bar shows the app name, current file, active filters, and contextual hints. A 2-column gutter shows fold indicators and bookmark markers. Input is polled via crossterm, and an AtomicBool flag set by the notify file watcher triggers reloads. The rendering pipeline parses the full markdown source into styled lines using pulldown-cmark, caches the result, and only re-parses when content, theme, or terminal width changes. Code blocks are syntax-highlighted via syntect. Inline #tags are detected during word wrapping and colored per-theme. Overlay pickers (TOC, labels, bookmarks, themes) share a generic PickerState<T> for navigation. Themes are fully config-driven — loaded from individual TOML files at startup using serde, with truecolor (24-bit RGB) support.

Code