mdp

module
v0.3.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 19, 2026 License: Apache-2.0

README

mdp

A fast markdown preview server for Neovim with live reload, scroll sync, and client-side rendering of Mermaid diagrams, KaTeX math, syntax highlighting, and GitHub-style callouts. All assets are embedded in the binary -- no CDN requests at runtime.

Quick Start

# Install
go install github.com/donaldgifford/mdp/cmd/mdp@latest

# Preview a markdown file
mdp serve README.md

The browser opens automatically. Edit the file and save -- the preview updates instantly.

Neovim Plugin

lazy.nvim / LazyVim

Minimal — defaults are provided by the plugin's lazy.lua:

{ "donaldgifford/mdp" }

With custom options:

{
  "donaldgifford/mdp",
  opts = {
    port = 0,               -- 0 = auto-assign
    browser = true,         -- Open browser on start
    theme = "",             -- "" = auto-detect from vim.o.background, or any built-in name
    scroll_sync = true,     -- Sync preview scroll with cursor
    idle_timeout_secs = 30, -- Shut down after N seconds with no open tab (0 = disabled)
    log_file = vim.fn.stdpath("log") .. "/mdp.log", -- "" to disable
  },
}

When theme is empty (the default), the plugin resolves the theme from vim.o.background: darkgithub-dark, lightgithub-light, unset → auto (browser prefers-color-scheme). Set theme to any built-in name (e.g. "tokyo-night") to pin a specific theme regardless of background setting.

On install/update, build.lua downloads a pre-built binary from GitHub releases. If no release is available (e.g., testing a branch), it falls back to building from source with go build.

Commands
Command Description
:MdpPreview Show preview — starts if needed, otherwise syncs buffer
:MdpStop Stop the preview server
:MdpStart Start the preview server explicitly
:MdpToggle Toggle start/stop
:MdpOpen Re-open the browser tab without restarting
:MdpInstall Download latest release binary
:MdpInstall! Build binary from source

The default keybinding is <leader>mp:MdpPreview. This is the only key you need for day-to-day use. :MdpStop is available if you want to shut down explicitly rather than waiting for the idle timeout.

Idle Timeout

By default the server shuts down automatically 30 seconds after the last browser tab is closed. This prevents orphaned processes when switching between tmux sessions or Neovim instances. Set idle_timeout_secs = 0 to disable.

Logging

Server output is written to ~/.local/state/nvim/mdp.log by default (XDG-compliant, same directory as other Neovim logs). Each session is delimited by start/end markers so multiple runs are easy to distinguish.

# Watch logs in real time
tail -f ~/.local/state/nvim/mdp.log

Set log_file = "" in opts to disable logging.

How It Works

The plugin starts mdp serve --stdin <file> as a background job. Buffer content is sent over stdin as newline-delimited JSON on every save and during insert mode (debounced). Cursor position is sent on every cursor movement (throttled) for scroll sync.

CLI Reference

mdp serve [flags] <file>
Flags
Flag Default Description
--port 0 Port to listen on (0 = auto-assign)
--browser true Open browser automatically
--theme auto Built-in theme name, auto, or path to CSS file
--hljs-theme "" Path to custom hljs CSS (only with --theme=<file>)
--scroll-sync true Enable scroll sync via cursor tracking
--stdin false Read content/cursor updates from stdin
--css "" Path to custom CSS file appended after theme CSS
--open-to-network false Listen on 0.0.0.0 instead of localhost
--idle-timeout 30s Shut down after no clients for this duration (0=disabled)
-v, --verbose false Enable debug logging
--version Print version, commit, and build date

Supported Markdown Features

  • GitHub Flavored Markdown: tables, task lists, strikethrough, autolinks
  • Syntax highlighting: all languages supported by highlight.js with GitHub light/dark themes
  • Mermaid diagrams: flowcharts, sequence diagrams, gantt charts, etc.
  • KaTeX math: inline $...$ and block $$...$$ expressions
  • GitHub-style callouts: > [!NOTE], > [!TIP], > [!IMPORTANT], > [!WARNING], > [!CAUTION] with themed icons and colors
  • Footnotes: [^1] references with [^1]: ... definitions, collected into a linked endnote list with back-references
  • Relative images: images referenced with relative paths are resolved from the markdown file's directory

Themes

Pass --theme=<name> to pin a specific built-in theme, or --theme=auto (the default) to follow the browser's prefers-color-scheme setting.

mdp serve --theme=tokyo-night README.md
mdp serve --theme=/path/to/my-theme.css README.md   # custom CSS file
Built-in themes
Name Family Style
github-light GitHub Light
github-dark GitHub Dark
github-dimmed GitHub Dark (dimmed)
tokyo-night Tokyo Night Dark
tokyo-night-moon Tokyo Night Dark (blue-tinted)
tokyo-night-storm Tokyo Night Dark (storm)
tokyo-night-day Tokyo Night Light
rose-pine Rosé Pine Dark
rose-pine-moon Rosé Pine Dark (moon)
rose-pine-dawn Rosé Pine Light
catppuccin-latte Catppuccin Light
catppuccin-frappe Catppuccin Dark
catppuccin-macchiato Catppuccin Dark
catppuccin-mocha Catppuccin Dark

Each built-in theme provides prose styling, syntax-highlighting token colours, and Mermaid diagram theming in a single embedded CSS file.

Architecture

Editor (Neovim)                    Browser
     |                                ^
     | stdin JSON                     | WebSocket/SSE
     | {"type":"content","data":"..."}| {"type":"content","html":"..."}
     | {"type":"cursor","line":N}     | {"type":"cursor","line":N}
     v                                |
   +-----------------------------------+
   |           mdp server              |
   |  +---------+  +---------------+   |
   |  | goldmark |  |  WebSocket + |   |
   |  | parser   |  |  SSE hub     |   |
   |  +---------+  +---------------+   |
   |  +---------+  +---------------+   |
   |  |  file   |  |  /vendor/     |   |
   |  |  watcher |  |  (embedded)  |   |
   |  +---------+  +---------------+   |
   +-----------------------------------+

Install

The lazy.nvim plugin spec handles everything — see Neovim Plugin above. build.lua downloads a pre-built binary on install/update.

Standalone binary
# Via Go
go install github.com/donaldgifford/mdp/cmd/mdp@latest

# Via Homebrew (when tap is set up)
brew install donaldgifford/tap/mdp

# From GitHub releases
# Download the archive for your platform from the releases page

Library

mdp's markdown parser, theme registry, and live-reload primitive are also importable as Go packages — useful if you're building your own preview-style app and want mdp's rendering or live-reload behavior without shelling out to the CLI. See the package docs for usage:

  • pkg/parser — goldmark pipeline (GFM, syntax highlighting, Mermaid, math, callouts, footnotes) with data-source-line annotations for scroll sync.
  • pkg/theme — theme registry; resolves built-in names, auto, or a CSS file path to a Theme struct.
  • pkg/livereload — transport-agnostic Hub (WebSocket + SSE) plus a WrapHandler middleware that injects a reload <script> into HTML responses.
Use case Import
Render markdown → HTML in your own app pkg/parser
Same, with mdp's look add pkg/theme
Same, with browser auto-reload add pkg/livereload

docz uses these packages in its serve command — a real-world consumer to look at for integration patterns.

Development

make build          # Build binary with version info
make test           # Run tests
make test-coverage  # Run tests with coverage
make lint           # Run golangci-lint
make fmt            # Format code
make update-vendor  # Update vendored JS libraries from CDN

To test a development branch in Neovim, add branch to your spec:

{ "donaldgifford/mdp", branch = "feat/your-branch" }

Then :Lazy update mdp. With no release for the branch, build.lua falls back to building from source. See CONTRIBUTING.md for more details.

License

MIT

Directories

Path Synopsis
Package assets embeds the client-side preview files.
Package assets embeds the client-side preview files.
cmd
mdp command
Package main is the entry point for mdp.
Package main is the entry point for mdp.
internal
cli
Package cli implements the mdp command-line interface.
Package cli implements the mdp command-line interface.
server
Package server provides the HTTP preview server for mdp.
Package server provides the HTTP preview server for mdp.
watcher
Package watcher provides debounced file change notifications using fsnotify.
Package watcher provides debounced file change notifications using fsnotify.
pkg
livereload
Package livereload provides browser live-reload primitives: a transport-agnostic Hub that fans byte payloads out to connected WebSocket and SSE clients, plus a WrapHandler middleware that injects a reload <script> into HTML responses.
Package livereload provides browser live-reload primitives: a transport-agnostic Hub that fans byte payloads out to connected WebSocket and SSE clients, plus a WrapHandler middleware that injects a reload <script> into HTML responses.
parser
Package parser converts markdown to HTML using a configurable goldmark pipeline.
Package parser converts markdown to HTML using a configurable goldmark pipeline.
theme
Package theme provides a registry of named themes plus loaders for custom CSS files.
Package theme provides a registry of named themes plus loaders for custom CSS files.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL