🏃

VHS で楽に Neovim のデモ動画を録る

2024/07/15に公開

はじめに

1ヶ月ほど前に Vim のマイナーなテクニックを紹介する記事を公開し、ありがたいことに非常に多くの方に読んでいただきました。

https://zenn.dev/vim_jp/articles/2024-06-05-vim-middle-class-features

この記事では特にデモ動画を多く載せることを意識していました。数えてみると8つもの GIF 動画が例に用いられています。Vim を用いた編集のスピート感を視覚的に示すことで、紹介したテクニックの魅力がより効果的に伝わったのではないでしょうか。

元記事の末尾に書いた通り、「中級 Vim 操作」では VHS というコマンドラインツール (CLI) と Neovim、そして nvim-keycastr というプラグインを用いてデモ動画を作成しました。 この体験が非常に良かったため、本記事ではより詳しく作り方を紹介します。 特に OSS 貢献を行っている方であれば、デモ動画はたとえば以下のような場所で役立つでしょう。

  • Vim/Neovim に関する記事やスライドに

  • Vim/Neovim プラグインの README に

  • Vim/Neovim 本体またはプラグインへ Issue/PR を作るときの説明に

ぜひご活用ください。

本記事の前半で VHS という CLI の紹介を行い、後半で Neovim との連携方法を説明します。VHS は簡単な扱い方および良かった点を紹介するだけにとどめました。詳しくは公式の README を確認してください。

VHS とは

https://github.com/charmbracelet/vhs

VHS とは、Tape という形式のコマンド列を与えることでターミナルのデモ動画を作成できる CLI コマンドです。 Tape フォーマットはたとえばこんな内容です(README より抜粋)。

demo.tape
# Where should we write the GIF?
Output demo.gif

# Set up a 1200x600 terminal with 46px font.
Set FontSize 46
Set Width 1200
Set Height 600

# Type a command in the terminal.
Type "echo 'Welcome to VHS!'"

# Pause for dramatic effect...
Sleep 500ms

# Run the command by pressing enter.
Enter

# Admire the output for a bit.
Sleep 5s

Tape 形式に初めて触れる方でもすぐ理解できるのではないでしょうか。ざっと読み方を説明すると以下のような意味になっています。

  • # から始まる行はコメント行を表し、後の処理では無視されます。
  • Output は、作成する動画の出力先を指定するコマンドです。
  • Set <Setting> Value は、ターミナルのレイアウトなどの設定値を指定するコマンドです。
  • Type "<character>" は、与えられた文字列を端末に入力することを表すコマンドです。
    • ただし一気にすべての文字を打ち込むのではなく、手で打ち込むように順番に(デフォルトでは 100ms のスリープをはさみつつ)タイピングが行われます。
    • タイピングのスピードは Type@500ms "500ms delay per character" といった書き方により調整可能です。
  • Sleep <time> は、 <time> で与えた時間だけ何もせず待機するコマンドです。
  • Enter はエンターキーを入力するコマンドです。他にも Space Ctrl+q など、特殊文字を端末に入力するためのコマンドが別途用意されています。

このようなコマンド列が記された demo.tapevhs コマンドの標準入力に与えます。

vhs < demo.tape

すると、以下のようなデモ動画が作成されます。


demo.tape から得られたデモ動画

  1. 指定されたフォントサイズ、幅、高さのターミナルを開く
  2. ターミナル上で echo 'Welcome to VHS!' と叩ち、0.5秒待つ
  3. ターミナル上でエンターキーを押し、5秒待つ

という、Tape ファイルにて指示した通りの処理がターミナル上で実行されていることが分かります。

このように VHS 自体は Character User Interface (CUI) や Text User Interface (TUI) を持つ CLI の実行をエミュレートし、結果をデモ動画にするツールです。Vim や Neovim も TUI ベースのテキストエディタですから、VHS を使って簡単にデモ動画が作れるというわけです。

VHS でデモ動画を作成するメリット

VHS でのデモ動画作成は、手動での収録に比べ多くの利点があります。

  • プレッシャーのかかる収録作業から解放される

    • 人手での画面収録では、ノイズとなるタイプミスやモタつきを極力避けなければなりません。これは収録においてプレッシャーとなり、「そう何度も録りたくないな」という心理的な抵抗につながります。テープから動画を作成するのであれば、このようなプレッシャーは発生しません。

    • ちなみに vhs record コマンドを使えば、(script コマンドで作業ログを残すように)実際に手打ちしたコマンドを Tape 形式に書き起こすこともできます。この収録にプレッシャーはかかりません。いくらモタついたとしても、後で Tape を修正できるからです。

  • ターミナルのレイアウト設定が楽

    • 普段使っている端末のレイアウトは必ずしもデモに適していません。フォントサイズはなるべく大きく、画面サイズはデモが収まる最低限の範囲にすべきです。

    • デモのためにいちいち端末のレイアウトを変えるのは手間ですが、VHS なら Tape 中にレイアウト情報を記述でき、手軽にレイアウトを調整できます。

  • 動画にメリハリをつけやすい

    • 人の手でデモを作るとタイピングのスピードなどに必ずブレが生じますが、VHS ならキー押下後の待ち時間を厳密に設定できます。

    • その結果、注目してほしいキー入力を終えた直後は待ち時間を長めにする、逆に長文を挿入するときは待ち時間を短くするなど、メリハリある構成にしやすくなります。

  • 作成した後の編集・微調整がしやすい

    • Tape からの動画生成が自動でできるため、動画を後から修正したり、微調整したりするハードルがグンと下がります。

    • プラグインのデモ動画など、定期的にアップデートしたい動画にとってかなりのメリットではないでしょうか。

VHS でデモ動画を作成するデメリット

  • 動画の作成には、テープに記載したコマンド実行以上の実行時間がかかる

    • たとえば Sleep 5s と書かれたテープを読み込む場合、動画の作成には最低でも5秒かかります。長い動画を作成すればその分時間が必ずかかるということです。

    • とはいえ手動で作成するときも結局実時間は消費するため、手動作成と比べればデメリットになりません。

VHS + Neovim の連携方法

VHS と Neovim の連携自体は非常に単純です。普段自分が使っているシェルを指定し、 レイアウトをよしなに設定して nvim と Type するだけ。たとえばこんな感じです。

demo.tape
Set Shell "fish"
Set FontSize 20
Set Width 800
Set Height 400
Set Padding 0

Hide

# ここで時間かけて type してもしょうがないので 0ms を指定
Type@0ms "nvim" Enter

Show

Hide / Show コマンドを使うことで、Neovim が起動した状態からデモ動画を開始することができます。 もちろんコマンドを打つところから動画を開始することもできます。どちらが望ましいかは場合によるでしょう。

デモ用の Neovim 設定ファイルを作る

端末のレイアウトと同様、普段使っている Neovim の設定と、デモに適した Neovim の設定は必ずしも一致しません。 どうせならデモに適した Neovim を立ち上げたいものです。

Neovim にはそれを実現するぴったりの機能があります。 $NVIM_APPNAME という環境変数を設定すれば、起動時に用いる Neovim の設定を切り替えられるのです。 たとえば通常の設定を置いている場所 (~/.config など) を以下のようなディレクトリ構成にします。

nvim/                     # 普段の Neovim 設定
├── after/
├── lua/
└── init.lua
nvim-demo/                # デモ用の Neovim 設定
└── init.lua

このとき、$NVIM_APPNAMEnvim-demo に設定して nvim コマンドを実行すると、 nvim-demo/init.lua のほうの設定が読まれた状態で Neovim が起動されます。 デモ用の Neovim の設定(設定が最小限であることが多い)を普段の設定(使いやすい Neovim)でいじれるのも嬉しい点ですね。

nvim-keycastr の導入

VHS では今のところ、押下しているキーを表示することができません。 通常の CLI のデモであればそこまで困りませんが、入力キーが見えない Neovim のデモとしてはかなり辛いです。 実際 VHS 側にも issue が立っているものの、2024/06/09 時点でオープンとなっています。

ここは Neovim 側のレイヤで解決してみましょう。以下のプラグインを導入します。

https://github.com/4513ECHO/nvim-keycastr

  1. 上記のリポジトリを適当なディレクトリにクローン (ここでは /your/path/to/nvim-keycastr にクローンしたものとする)

  2. 上の節で導入した nvim-demo/init.lua に以下を記述

    vim.opt.runtimepath:append("/your/path/to/nvim-keycastr")
    
    local keycastr = require("keycastr")
    
    keycastr.config.set {
        ignore_mouse = true,
        position = "SE",
        win_config = {
            border = "rounded",
        },
    }
    
    keycastr.enable()
    

これでデモ用 Neovim の中で nvim-keycastr を使うことができます。

デモテープの作成

上で設定したことをデモテープに反映します。たとえば fish shell を使うなら以下のようになります。

demo.tape
Output "demo.gif"

Set Shell "fish"
Set FontSize 20
Set Width 800
Set Height 400
Set Padding 0

Hide

Type@0ms "env NVIM_APPNAME='nvim-demo' nvim" Enter
Show

これで雛形は完成! Show コマンドの後に好きなコマンドを書き並べ、望み通りのデモを作ってください。場合によっては vhs record などでキーストロークを収録し、雛形の後ろに流し込んでもよいでしょう [1]

おわりに

VHS + nvim-keycastr を用いて Neovim のデモ動画を録る方法を紹介しました。紹介した素晴らしい OSS を作ってくださった方々に感謝いたします。 VHS 自体かなり便利なので、Neovim ユーザでない方もぜひ一度使ってみてください。

脚注
  1. なお筆者の環境では一部の修飾キーがうまく収録されなかったので、結局手動で打ち込んだほうが早いケースもあるかもしれません。 ↩︎

Discussion