Note
この記事はVim 駅伝の 4/24 の記事です。
TLDR
oil.nvimで画像を選択し、Weztermで画像を表示。 画像はこちらから
- Neovimで画像と向き合う方法を紹介
- Quicklookを呼び出す方法は簡単
- 今回はWeztermとoil.nvimをフル活用して、Terminal上で画像を表示する方法を紹介をメインに紹介
はじめに
Vimmerたるもの、普段はTerminalに引きこもっているものです。 特にVim(Neovim)上で作業をすることが多いはず。
しかし、Terminalが苦手なファイルも存在します。 ご存じ、画像ファイルです。
これまで、自分は画像ファイルを見たいときは
openコマンドで画像を開く(MacならPreviewで開く)open .でFinderを開いて画像を見る
としてきましたが、やはり画像を見たいためだけにFinderを立ち上げたりアプリを起動、終了するのは面倒です。
そこで、これらを改善することにしました。
Note
参考までに、筆者の環境は以下のとおりです。
│ neofetch
'c. ryoppippi@ryoppippi.local
,xNMM. -------------------------
.OMMMMo OS: macOS 14.4.1 23E224 arm64
OMMM0, Host: Mac15,6
.;loddo:' loolloddol;. Kernel: 23.4.0
cKMMMMMMMMMMNWMMMMMMMMMM0: Uptime: 7 days, 2 hours, 15 mins
.KMMMMMMMMMMMMMMMMMMMMMMMWd. Packages: 1 (brew)
XMMMMMMMMMMMMMMMMMMMMMMMX. Shell: fish 3.7.1
;MMMMMMMMMMMMMMMMMMMMMMMM: Resolution: 2560x1080, 1512x982, 1080x1920
:MMMMMMMMMMMMMMMMMMMMMMMM: DE: Aqua
.MMMMMMMMMMMMMMMMMMMMMMMMX. WM: Rectangle
kMMMMMMMMMMMMMMMMMMMMMMMMWd. Terminal: WezTerm
.XMMMMMMMMMMMMMMMMMMMMMMMMMMk CPU: Apple M3 Pro
.XMMMMMMMMMMMMMMMMMMMMMMMMK. GPU: Apple M3 Pro
kMMMMMMMMMMMMMMMMMMMMMMd Memory: 5014MiB / 36864MiB
;KMMMMMMMWXXWMMMMMMMk.
.cooc,. .,coo:.
本記事では、ファイラとしてoil.nvimを使った例を紹介しますが、他のファイラでも同様のことができるはずです。 https://github.com/stevearc/oil.nvim
また、設定はluaで書かれています。
Step 1: Quicklookを使う
macOS には標準でQuicklookという機能があります。 みなさん、一度はお世話になったことのある、Finderでファイルを選択してスペースキーを押すと、ファイルの中身をプレビューできるあれです。
実は、TerminalからもQuicklookを使うことができます。
qlmanage -p hoge.png
つまり、これをVim(Neovim)から呼び出せば、画像をプレビューできるはずです。
https://github.com/ryoppippi/dotfiles/blob/359609ea44ddbc7b4b621aaea4ea5d4a9a06e88e/nvim/lua/core/utils.lua#L52-L55 https://github.com/ryoppippi/dotfiles/blob/359609ea44ddbc7b4b621aaea4ea5d4a9a06e88e/nvim/lua/plugin/oil/actions.lua#L24-L31 https://github.com/ryoppippi/dotfiles/blob/359609ea44ddbc7b4b621aaea4ea5d4a9a06e88e/nvim/lua/plugin/oil/init.lua#L41
これで、oil.nvimで画像を選択し、Quicklookを呼び出すことができますね。
oil.nvimで画像を選択し、Quicklookを呼び出す
Step 2: Weztermを分割&画像表示
さて、Quicklookの方法にもまだ改善点があります。
- いちいちEscキーを押してQuicklookを閉じるのは面倒
- QuicklookにFocusが当たってしまうので、他のファイルを選択できない
というわけで、本命択はTerminal上で画像を表示したいわけです。
これまで、Vim/Neovimで画像を表示する試みはいくつかありました。
https://github.com/kjuq/sixelview.nvim/ https://zenn.dev/vim_jp/articles/358848a5144b63
しかし、先の記事にも触れられているように、いくつか課題があります。
- 画像のサイズをいい感じに調整するのが難しい。
- gifをポンと渡しても再生されない。
そのため、今回はTerminalの機能を使って画像を表示することにしました。
自分の使用しているWeztermには、画像を表示する機能があります。 https://wezfurlong.org/wezterm/imgcat.html https://wezfurlong.org/wezterm/cli/imgcat.html
これにより、任意の画像をTerminal上で表示することができます。
またWeztermには wezterm cliコマンドがあり、Weztermの動作をコマンドで制御することができます。
https://wezfurlong.org/wezterm/cli/cli/index.html
これらをフル活用して、次のような設定を行いました。
(以下、この機能のことをWezterm Previewと呼びます)
oil.nvimでgpを押すとWezterm Previewを起動
現在のNeovimが開かれているPane IDを取得
現在のPane IDを取得するには、環境変数 WEZTERM_PANE を使います。
https://wezfurlong.org/wezterm/cli/cli/spawn.html#synopsis https://github.com/ryoppippi/dotfiles/blob/6c587dfbc3773a5adfff661f0943e0edf9288a7f/nvim/lua/plugin/oil/actions.lua#L34-L41
Weztermの画面を分割して、分割されたpaneのidを取得
Weztermで画面を分割するには、wezterm cli split-paneコマンドを使います。
このコマンドの戻り値には、分割されたpaneのidが含まれています。 https://wezfurlong.org/wezterm/cli/cli/split-pane.html https://github.com/ryoppippi/dotfiles/blob/6c587dfbc3773a5adfff661f0943e0edf9288a7f/nvim/lua/plugin/oil/actions.lua#L48-L66 https://github.com/ryoppippi/dotfiles/blob/6c587dfbc3773a5adfff661f0943e0edf9288a7f/nvim/lua/plugin/oil/actions.lua#L140
もしすでにpaneが分割されている場合は、そのpaneのidを取得します。
この時は wezterm cli list --format=json コマンドを使います。
Neovimが開かれているPaneにFocusを戻す
https://github.com/ryoppippi/dotfiles/blob/6c587dfbc3773a5adfff661f0943e0edf9288a7f/nvim/lua/plugin/oil/actions.lua#L43-L45 https://github.com/ryoppippi/dotfiles/blob/6c587dfbc3773a5adfff661f0943e0edf9288a7f/nvim/lua/plugin/oil/actions.lua#L153
oil.nvimでカーソルが動くたびに、Wezterm Previewを更新
まず、カーソルが選択しているファイルの情報を取得します。 https://github.com/ryoppippi/dotfiles/blob/6c587dfbc3773a5adfff661f0943e0edf9288a7f/nvim/lua/plugin/oil/actions.lua#L148-L151
そしてその情報を元に、もし新しいファイルであれば、WeztermのPreview用のPaneにコマンドを送って実行します。 この時
- ディレクトリであれば、
lsコマンド - 画像ファイルであれば、
wezterm imgcatコマンド - そのほかは
batコマンド
を実行するようにします。
Weztermでpaneにコマンドを送るには、 wezterm cli send-text コマンドを使います。 https://wezfurlong.org/wezterm/cli/cli/send-text.html https://github.com/ryoppippi/dotfiles/blob/6c587dfbc3773a5adfff661f0943e0edf9288a7f/nvim/lua/plugin/oil/actions.lua#L77-L89
oil.nvimが終了したら、Wezterm Previewを閉じる
oil.nvimの現在のバッファが閉じられたら、WeztermのPreview用のPaneも閉じるようにします。
https://wezfurlong.org/wezterm/cli/cli/kill-pane.html https://github.com/ryoppippi/dotfiles/blob/6c587dfbc3773a5adfff661f0943e0edf9288a7f/nvim/lua/plugin/oil/actions.lua#L201-L211 https://github.com/ryoppippi/dotfiles/blob/6c587dfbc3773a5adfff661f0943e0edf9288a7f/nvim/lua/plugin/oil/actions.lua#L68-L75
コードの全体像
動作は冒頭のGIFをご覧ください。
まとめ
今回は、oil.nvimとWeztermを使って、Terminal上で画像を表示する方法を紹介しました。 まだプラグインとして公開してないのですが、要望があれば公開するかもしれません。
今回はWeztermの機能をフル活用しましたが、他のTerminal Emulatorでも同様のことができるはずです。 ぜひみなさんも、自分の環境に合わせて設定してみてください。