✏️

[小ネタ] Neovimでのインライン画像表示付きのマークダウン執筆環境を整えてみた

に公開

こんにちは。ダイの大冒険エンジョイ勢のbun913と申します。

みなさんは Neovim でマークダウンを書いていて「画像のプレビューどうしよう」「mermaid のダイアグラムが確認できない」と困ったことはありませんか?私はあります。

私はテスト技術者として、コードを書く時間ももちろんありますが、マークダウンや yaml を扱う時間もかなりあります。以前は VSCode をメインにしていたのですが、統合ターミナルで作業するよりもエディタとターミナルを独立させた方がメモリ効率が良いという記事を読んだこともあり、もともとサブで使っていた Neovim に寄せていくことにしました。

ターミナル上で Claude Code と Neovim を並べて作業するワークフローにしたかったのですが、課題になったのがマークダウンのプレビュー周りです。特に画像のインライン表示が厄介でした。

今回はその課題をプラグイン4つとターミナルの選択で解決した話を書きます。主に Neovim への移行を検討されている方に向けた内容ですが、既に Neovim を使っていてマークダウン周りの環境を改善したい方にも参考になればと思います。

早速デモ

以下は Neovim のバッファ内で画像がインライン表示されている様子です。ブラウザを開かずに、バッファ上で画像を確認できます。

image.nvimによるバッファ内画像表示

また、mermaid のコードブロックもターミナル内でダイアグラムとしてレンダリングされます。

snacks.nvimによるmermaidレンダリング

これらの環境をどのように整えたかを以下で説明していきます。

WezTerm から Kitty への移行

なぜ乗り換えたのか

きっかけは image.nvim というプラグインの存在を知ったことです。マークダウン内の ![alt](path) をバッファにインライン表示してくれるプラグインで、VSCode のプレビューのように画像を俯瞰して確認できるのが魅力でした。

https://github.com/3rd/image.nvim

この image.nvim の推奨環境について、README では以下のように記載されています。

  1. Kitty (recommended) >= 28.0 for the kitty backend
    • Has the best performance, native clipping, caching, etc.
  • WezTerm implements it, but the performance is bad and it's not fully compliant. Most things work, but due to these issues it's not officially supported.
  • Ghostty not that much information about this yet! SUBJECT TO CHANGE

もともと使っていた WezTerm でも Kitty Graphics Protocol 自体はサポートしており、hover で画像を表示するような使い方はできていました。ただ、今回やりたかったのはバッファ内にインラインで画像を並べて俯瞰する使い方です。WezTerm では完全準拠ではなく officially supported でもないため、推奨されている Kitty への乗り換えを決めました。

ちなみに Ghostty でもインライン画像のレンダリングはうまく動作しました。tmux 越しでも問題なかったです。

ただ、私の場合は Kitty のように設定ファイルで管理できれば十分ですし、Ghostty のような機能が現段階では必要なかったので利用をしておりません。

ターミナルの選択肢は他にもありますので、ご自身のニーズに合うものを選択されると良いと思います。

プラグイン構成

マークダウン関連で使っているプラグインは以下の4つです。

render-markdown.nvim: マークダウンのリッチ表示

バッファ内でマークダウンのリスト、コードブロックなどをリッチに装飾表示してくれるプラグインです。普段の執筆はこれがメインになっています。

https://github.com/MeanderingProgrammer/render-markdown.nvim

{
  'MeanderingProgrammer/render-markdown.nvim',
  ft = { 'markdown' },
  dependencies = { 'nvim-treesitter/nvim-treesitter', 'nvim-tree/nvim-web-devicons' },
  opts = {
    render_modes = { 'n', 'c' },
    heading = { enabled = false },
    link = { enabled = false },
    pipe_table = { enabled = false },
  },
}

いくつかの機能を無効にしています。

  • heading : 見出しは ## のまま表示したいので無効化
  • link : image.nvim の画像表示で十分なので無効化
  • pipe_table : 折り返し時の挙動など、私は通常のテーブル表示で十分だと考えたためです

render_modes = { 'n', 'c' } を設定しているので、挿入モードに入ると自動的に生テキストに戻ります。ノーマルモードではリッチ表示、挿入モードでは生テキストという切り替えが自然にできて気に入っています。

image.nvim: 画像インライン表示

![alt](path) の画像を Neovim のバッファ内にインライン表示してくれるプラグインです。これが Kitty Graphics Protocol の unicode placeholders を必要とする部分になります。

https://github.com/3rd/image.nvim

{
  '3rd/image.nvim',
  ft = { 'markdown' },
  cond = function()
    if vim.fn.executable('magick') == 0 and vim.fn.executable('convert') == 0 then
      vim.notify('image.nvim requires ImageMagick. Run: brew install imagemagick', vim.log.levels.WARN)
      return false
    end
    return true
  end,
  opts = {
    backend = 'kitty',
    processor = 'magick_cli',
    integrations = {
      markdown = {
        enabled = true,
        clear_in_insert_mode = true,
        only_render_image_at_cursor = false,
        floating_windows = false,
      },
    },
    max_height_window_percentage = 50,
  },
}
  • clear_in_insert_mode = true で挿入モードに入ると画像が消え、生テキストに戻ります
  • only_render_image_at_cursor = false で全画像を常時表示
  • 依存として brew install imagemagick が必要ですので、一応利用できない場合の注意を表示するようにしています

冒頭のデモでお見せしたとおり、ブラウザを開かずにバッファ内で画像を確認できるのはなかなか快適です。

snacks.nvim: mermaid レンダリング

snacks.nvimimage モジュールは Kitty Graphics Protocol を使った画像表示の基盤を提供してくれます。mermaid コードブロックにカーソルを合わせると、自動的にダイアグラムがレンダリングされて表示されます。

https://github.com/folke/snacks.nvim

{
  'folke/snacks.nvim',
  lazy = false,
  opts = {
    image = {},
  },
}

mermaid などの表示には外部ツールへの依存があります。:checkhealth snacks で確認したところ、mermaid のレンダリングには mmdc が必要でした。

- ⚠ `mmdc` is required to render Mermaid diagrams
npm install -g @mermaid-js/mermaid-cli

冒頭のデモでお見せしたとおり、コードブロックの上にフローチャートが表示されます。簡単な確認であればこれで十分ですし、ブラウザを開かなくて済むのが地味にありがたいです。

live-preview.nvim: ブラウザプレビュー

Mermaid や KaTeX など表示を本格的に確認したいときに使っています。:LivePreview start でブラウザが開き、ライブリロードでプレビューできます。

https://github.com/brianhuster/live-preview.nvim

{
  'brianhuster/live-preview.nvim',
  cmd = { 'LivePreview' },
  ft = { 'markdown' },
  opts = {},
}
  • 以前は iamcco/markdown-preview.nvim を使っていましたが、2023年10月以降メンテナンスされていないようだったので乗り換えることにしました

まとめ

  • Neovim でマークダウンを書く際に、画像のインライン表示や mermaid のレンダリングが課題でした
  • ターミナルを WezTerm から Kitty に乗り換えることで、unicode placeholders に対応し画像のインライン表示ができるようになりました
    • Ghostty や tmux 越しでもレンダリング自体は動作しました
  • render-markdown.nvim + image.nvim の組み合わせで、普段の執筆は Neovim 内で完結できるようになりました
  • 本格的なプレビューが必要な場合は live-preview.nvim:LivePreview start で対応しています
  • ただ、色々と依存が入っているので VSCode でいい人はそっちの方が楽だと思います
    • 若干意地になっている気持ちも正直あります
    • また、snacks.nvim の hover 画像表示だけで十分なケースも多くあると思います

以上、最後までお読みいただきありがとうございました。

GitHubで編集を提案
Money Forward Developers

Discussion