
Neovim マークダウンプレビュー - markdown-preview.nvim を選んだ理由
Neovimでマークダウンをプレビューするプラグインを導入しました。
Redditでの議論も参考にしながら検討しました。
検討したプラグイン
Neovimのマークダウンプレビューは大きく3つのアプローチに分かれます。
| アプローチ | 説明 | 代表的なプラグイン |
|---|---|---|
| バッファ内レンダリング | Neovimの画面上で装飾表示 | markview.nvim、render-markdown.nvim |
| ブラウザプレビュー | 外部ブラウザでHTML表示 | markdown-preview.nvim、peek.nvim |
| ターミナルプレビュー | ターミナル内でレンダリング | glow.nvim |
それぞれ見ていきます。
1. markview.nvim(バッファ内レンダリング)
Neovimのバッファ内でマークダウンをレンダリングするプラグイン。 見出しやリスト、コードブロックが装飾されて表示されます。
特徴:
- バッファ内でリアルタイムレンダリング
- 追加のブラウザやツールが不要
- Neovimの画面だけで完結
- ハイブリッドモード(ノーマルモードで装飾、インサートモードで生テキスト)
2. render-markdown.nvim(バッファ内レンダリング)
markview.nvimと同じバッファ内レンダリング系。GitHub Stars 4,000超の人気プラグインです。
特徴:
- モーダルレンダリング — ノーマルモードでは装飾表示、インサートモードでは生テキスト表示に自動切替
- Anti-conceal — カーソル行の仮想テキストを非表示にして編集しやすくする
- ファイルタイプ非依存 — Markdownが注入された任意のファイルタイプで動作
- 大規模ファイル対応 — 表示範囲のみレンダリング、ファイルサイズで無効化可能
- 見出し、コードブロック、テーブル、チェックボックス、リンク、LaTeXブロック、コールアウトなど幅広い要素に対応
{
'MeanderingProgrammer/render-markdown.nvim',
dependencies = { 'nvim-treesitter/nvim-treesitter' },
ft = { 'markdown' },
opts = {
render_modes = { 'n', 'c', 't' },
},
}markview.nvimとの違いは、render-markdown.nvimの方がより「編集の邪魔をしない」設計思想が強い点です。Anti-conceal機能やモーダルレンダリングで、編集中のストレスを軽減してくれます。
3. markdown-preview.nvim(ブラウザプレビュー)
ブラウザでマークダウンをプレビューするプラグイン。 Node.jsベースのローカルサーバーを立ち上げて、ブラウザでリアルタイムに確認できます。
特徴:
- ブラウザでプレビュー(同期スクロール対応)
- リアルタイム同期(WebSocket)
- Mermaid、KaTeX、PlantUML、Chart.js、Flowchart、シーケンス図、dot(Graphviz)に対応
- カスタムCSS / ハイライトCSS でスタイル変更可能
- リモートプレビュー対応(
mkdp_open_to_the_world)
4. peek.nvim(ブラウザプレビュー)
markdown-preview.nvimと同じブラウザプレビュー系ですが、Denoランタイムで動作します。
特徴:
- Deno ベース(Node.js不要、Denoが必要)
- GitHub風のスタイルでレンダリング
- KaTeX(数式)、Mermaid(図)に対応
- webview / ブラウザ / カスタムアプリから表示方法を選択可能
- プレビューウィンドウ内でvimキー操作(j/k スクロール、u/d 半ページ、g/G 先頭/末尾)
{
'toppair/peek.nvim',
event = { 'VeryLazy' },
build = 'deno task --quiet build:fast',
config = function()
require('peek').setup({
theme = 'dark',
app = 'browser',
})
vim.api.nvim_create_user_command('PeekOpen', require('peek').open, {})
vim.api.nvim_create_user_command('PeekClose', require('peek').close, {})
end,
}markdown-preview.nvimとの違いは、peek.nvimの方が軽量で設定がシンプルな反面、対応する記法(PlantUML、Chart.js、Flowchart、dot等)は少なめです。
5. glow.nvim(ターミナルプレビュー) ※アーカイブ済み
Charm社の glow をNeovim内で使うプラグイン。ターミナル上でマークダウンをレンダリングします。
特徴:
- ターミナル内で完結(ブラウザ不要)
- glow CLIのレンダリング品質
- シンタックスハイライト付き
ただし、2025年3月にリポジトリがアーカイブされており、今後のメンテナンスは期待できません。glow CLI自体は健在なので、プラグインなしで :!glow % のようにコマンドとして使う方法はあります。
選んだのは markdown-preview.nvim
いくつか試した結果、markdown-preview.nvim を選びました。
選んだ理由
1. エディタの見た目が変わらない
markview.nvimはバッファ内でレンダリングするため、Neovimの画面自体が装飾されます。
これに違和感がありました。
- ソースコードとして編集しているのに、見た目が変わる
- 「生のマークダウン」を見ながら編集したい
- 装飾が入ると、記法の確認がしづらい
markdown-preview.nvimなら、エディタはそのまま。 「編集画面」と「プレビュー画面」が明確に分離されていて、頭の切り替えがしやすいです。
2. Mermaid などの高度な表示に対応
これが決め手でした。
markdown-preview.nvimは以下に対応しています:
- Mermaid — フローチャート、シーケンス図、ガントチャートなど
- KaTeX — 数式
- PlantUML — UML図
- chart.js — グラフ
技術文書を書くときに、Mermaidでフローチャートを描くことが多いので、これは必須でした。
こういった図がブラウザでそのままレンダリングされます。
markview.nvimでもMermaid対応はあるようですが、ブラウザでの表示に比べると制限があります。
markdown-preview.nvim のインストールと設定
インストール(lazy.nvim)
{
"iamcco/markdown-preview.nvim",
cmd = { "MarkdownPreviewToggle", "MarkdownPreview", "MarkdownPreviewStop" },
ft = { "markdown" },
build = function() vim.fn["mkdp#util#install"]() end,
}Node.jsとyarnがインストール済みの場合は、build を以下に置き換えることもできます:
build = "cd app && npx --yes yarn install",コマンド
:MarkdownPreview " プレビュー開始
:MarkdownPreviewStop " プレビュー停止
:MarkdownPreviewToggle " プレビューのトグル(開始/停止)コマンドを実行すると、ローカルにWebSocketサーバーが起動し、自動的にブラウザが開いてプレビューが表示されます。
キーマップ設定
vim.keymap.set('n', '<Space>mp', ':MarkdownPreviewToggle<CR>', { desc = 'Toggle Markdown Preview' })<Space>mp でプレビューをトグルできるようにしています。<Plug> マッピングも用意されています:
nmap <C-s> <Plug>MarkdownPreview
nmap <M-s> <Plug>MarkdownPreviewStop
nmap <C-p> <Plug>MarkdownPreviewToggle全オプション一覧
markdown-preview.nvim の設定は vim.g.mkdp_* 変数で行います。以下が全オプションです。
起動・終了
| オプション | デフォルト | 説明 |
|---|---|---|
mkdp_auto_start | 0 | Markdownバッファを開いたとき自動でプレビュー開始 |
mkdp_auto_close | 1 | Markdownバッファから離れたとき自動でプレビュー終了 |
mkdp_refresh_slow | 0 | 1 にすると保存時・インサート離脱時のみ更新。0 は編集中リアルタイム更新 |
mkdp_command_for_global | 0 | 1 にするとMarkdown以外のファイルでもコマンドが使える |
mkdp_filetypes | {'markdown'} | プレビュー対象のファイルタイプ |
ブラウザ・表示
| オプション | デフォルト | 説明 |
|---|---|---|
mkdp_browser | '' | プレビューに使うブラウザのパス。空ならシステムデフォルト |
mkdp_browserfunc | '' | URLを受け取ってブラウザを開くカスタム関数名 |
mkdp_theme | システム設定 | プレビューのテーマ。'dark' または 'light' |
mkdp_page_title | '「${name}」' | プレビューページのタイトル。${name} がファイル名に置換される |
mkdp_echo_preview_url | 0 | 1 にするとプレビューURLをコマンドラインに表示 |
ネットワーク・リモート
| オプション | デフォルト | 説明 |
|---|---|---|
mkdp_open_to_the_world | 0 | 1 にするとサーバーをネットワークに公開(リモート開発時に便利) |
mkdp_open_ip | '' | プレビューページを開くカスタムIP |
mkdp_port | '' | サーバーのポート番号。空ならランダム |
カスタムスタイル
| オプション | デフォルト | 説明 |
|---|---|---|
mkdp_markdown_css | '' | カスタムMarkdown CSSファイルの絶対パス |
mkdp_highlight_css | '' | カスタムハイライトCSSファイルの絶対パス |
複数ファイルプレビュー
| オプション | デフォルト | 説明 |
|---|---|---|
mkdp_combine_preview | 0 | 1 にすると複数ファイルで同一プレビューウィンドウを再利用 |
mkdp_combine_preview_auto_refresh | 1 | バッファ切替時に自動でプレビュー内容を更新 |
レンダリングオプション(mkdp_preview_options)
mkdp_preview_options にはレンダリングの詳細設定をテーブルで指定します:
vim.g.mkdp_preview_options = {
mkit = {}, -- markdown-it のオプション
katex = {}, -- KaTeX のオプション
uml = {}, -- PlantUML のオプション
maid = {}, -- Mermaid のオプション
disable_sync_scroll = 0, -- 同期スクロール無効化(1で無効)
sync_scroll_type = 'middle', -- 'middle' | 'top' | 'relative'
hide_yaml_meta = 1, -- YAMLフロントマターを非表示
sequence_diagrams = {}, -- js-sequence-diagrams のオプション
flowchart_diagrams = {}, -- flowchart.js のオプション
content_editable = false, -- プレビューページの編集可否
disable_filename = 0, -- ファイル名ヘッダーの非表示
toc = {}, -- 目次のオプション
}sync_scroll_type の違い:
'middle'— カーソル位置が常にプレビューの中央'top'— Vimの上端がプレビューの上端に一致'relative'— カーソルの相対位置をプレビューに反映
設定例:リモート開発でのプレビュー
SSHでリモートサーバーのNeovimを使っている場合、ローカルブラウザでプレビューできます:
vim.g.mkdp_open_to_the_world = 1
vim.g.mkdp_open_ip = '0.0.0.0'
vim.g.mkdp_port = 8888
vim.g.mkdp_echo_preview_url = 1この設定で http://<サーバーIP>:8888 にアクセスすればプレビューが見られます。
設定例:ブラウザを新規ウィンドウで開く
デフォルトでは既存のブラウザタブで開きますが、新しいウィンドウで開きたい場合:
vim.g.mkdp_browserfunc = 'OpenMarkdownPreview'
vim.cmd([[
function OpenMarkdownPreview(url)
execute "silent ! open -a Firefox -n --args --new-window " . a:url
endfunction
]])Firefox の部分を Google\ Chrome や Brave\ Browser に変えれば、それぞれのブラウザで開けます。
対応記法と具体例
markdown-preview.nvim は多くの記法をサポートしています。
Mermaid(図・チャート)
フローチャート、シーケンス図、ガントチャートなどを記述できます。
```mermaid
graph LR
A[ユーザー] --> B[アプリ]
B --> C[データベース]
C --> B
B --> A
```ガントチャートも書けます:
```mermaid
gantt
dateFormat YYYY-MM-DD
title プロジェクトスケジュール
section 設計
要件定義 :a1, 2025-01-01, 30d
基本設計 :after a1, 20d
section 開発
実装 :2025-02-20, 45d
テスト :2025-04-06, 15d
```KaTeX(数式)
インライン数式と数式ブロックに対応しています。
インライン: $E = mc^2$
ブロック:
$$
\sum_{i=1}^{n} x_i = x_1 + x_2 + \cdots + x_n
$$PlantUML(UML図)
シーケンス図やクラス図を記述できます。
```plantuml
Bob -> Alice : hello
Alice -> Bob : hi
```または @startuml / @enduml 記法も使えます。
Chart.js(グラフ)
JSON形式でグラフを記述できます。
```chart
{
"type": "pie",
"data": {
"labels": ["Red", "Blue", "Yellow"],
"datasets": [{
"data": [300, 50, 100],
"backgroundColor": ["#FF6384", "#36A2EB", "#FFCE56"]
}]
}
}
```シーケンス図(js-sequence-diagrams)
```sequence-diagrams
Andrew->China: Says
Note right of China: China thinks
China-->Andrew: How are you?
Andrew->>China: I am good thanks!
```Flowchart(flowchart.js)
```flowchart
st=>start: 開始
e=>end: 終了
op1=>operation: 処理
cond=>condition: 条件
st->op1->cond
cond(yes)->e
cond(no)->op1
```dot(Graphviz)
```dot
digraph G {
A -> B -> C;
B -> D;
}
```目次
以下のいずれかをファイル内に記述すると、目次が自動生成されます:
${toc}
[[toc]]
[toc]
[[_toc_]]画像サイズ指定
通常のMarkdown画像にサイズを指定できます:
使用感
良い点
- リアルタイム同期 — 編集すると即座にブラウザに反映(WebSocket接続)
- スクロール同期 — エディタのカーソル位置とブラウザが連動(3種類の同期モード)
- 記法の対応幅が広い — Mermaid、KaTeX、PlantUML、Chart.js、Flowchart、dot、シーケンス図
- ダークテーマ — 目に優しい(ヘッダーにテーマ切替ボタンも隠れている)
- カスタムCSS — 自分好みのスタイルに変更可能
気になる点
- ブラウザが必要 — 当たり前だけど、ブラウザが立ち上がる
- リソース消費 — Node.jsサーバーが常駐するので、多少メモリを使う
- 同期スクロールがカクつく場合がある —
updatetimeを小さい値(例:100)に設定すると改善する
とはいえ、常時使うわけではないので問題ありません。 READMEを書くときや、技術文書を整理するときに使っています。
Tips
- 同期スクロールがラグい場合は
set updatetime=100を設定 - WSL 2でブラウザが開かない場合は
sudo apt-get install -y xdg-utilsでインストール - ヘッダーにマウスを合わせると、テーマ切替ボタンが表示される
他のプラグインが向いている人
バッファ内レンダリング系(markview.nvim / render-markdown.nvim)
- バッファ内で完結させたい
- ブラウザを開きたくない
- シンプルなマークダウン(見出し、リスト、コードブロック程度)がメイン
- Neovimの画面が装飾されても気にならない
「ターミナルから出たくない」という人にはこちらの方が合うかもしれません。 render-markdown.nvimはAnti-conceal機能があるので、markview.nvimよりも編集中の違和感が少ないです。
peek.nvim
- markdown-preview.nvimの機能はオーバースペック
- Node.jsよりDenoの方が好み
- GitHub風のプレビューで十分
- 軽量な方がいい
glow.nvim(アーカイブ済み)
- ターミナル内で読み取り確認したい
- 新規プロジェクトでの採用は非推奨(メンテ終了のため)
まとめ
5つのプラグイン比較表
| プラグイン | 表示場所 | Mermaid | KaTeX | PlantUML | Chart.js | カスタムCSS | 依存 |
|---|---|---|---|---|---|---|---|
| markview.nvim | バッファ内 | 限定的 | — | — | — | — | Treesitter |
| render-markdown.nvim | バッファ内 | — | LaTeXブロック | — | — | — | Treesitter |
| markdown-preview.nvim | ブラウザ | 対応 | 対応 | 対応 | 対応 | 対応 | Node.js |
| peek.nvim | ブラウザ | 対応 | 対応 | — | — | — | Deno |
| glow.nvim | ターミナル | — | — | — | — | — | glow CLI |
markdown-preview.nvim を選んだ理由
- エディタの見た目が変わらない — ソースコードとして編集したい
- 対応記法が最も豊富 — Mermaid、KaTeX、PlantUML、Chart.js、Flowchart、dot、シーケンス図
- カスタマイズ性が高い — CSS変更、リモートプレビュー、ポート指定など
対応記法の豊富さが群を抜いています。技術文書でMermaidやKaTeXを多用するなら、現時点ではこれ一択だと思います。
どのプラグインが合うかは好みの問題ですが、私は「編集画面」と「プレビュー画面」を明確に分けたい派でした。