Last active
April 20, 2026 15:13
-
-
Save delphinus/634ac506ecdda58ca9e00a402816fe14 to your computer and use it in GitHub Desktop.
md-render.nvim: Kitty Graphics Protocol で画像を表示する最小デモ
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| -- demo_kitty.lua | |
| -- Kitty Graphics Protocol で画像を表示する最小デモ | |
| -- md-render.nvim の image モジュールを使用 | |
| -- | |
| -- 使い方: Kitty / WezTerm / Ghostty 上で | |
| -- nvim -u NONE -l demo_kitty.lua /path/to/image.png | |
| -- | |
| -- md-render.nvim が runtimepath に無い場合はパスを指定: | |
| -- nvim -u NONE --cmd 'set rtp+=~/.local/share/nvim/lazy/md-render.nvim' -l demo_kitty.lua /path/to/image.png | |
| local image = require("md-render.image") | |
| local path = arg[1] | |
| if not path then | |
| print("Usage: nvim -u NONE -l demo_kitty.lua <image.png>") | |
| print(" md-render.nvim が rtp に無い場合:") | |
| print(" nvim -u NONE --cmd 'set rtp+=~/.local/share/nvim/lazy/md-render.nvim' -l demo_kitty.lua <image.png>") | |
| os.exit(1) | |
| end | |
| -- 1. Kitty Graphics Protocol に対応しているか確認 | |
| if not image.supports_kitty() then | |
| print("この端末は Kitty Graphics Protocol に対応していません") | |
| os.exit(1) | |
| end | |
| -- 2. 画像を端末に転送(表示はまだしない) | |
| -- 内部では以下のエスケープシーケンスを送っている: | |
| -- ESC_Ga=t,f=100,t=f,i=<id>,q=2;<base64エンコードしたファイルパス>ESC\ | |
| -- a=t : transmit(転送して保存、表示しない) | |
| -- f=100: フォーマットは PNG | |
| -- t=f : ペイロードはファイルパス(base64) | |
| -- i=id : 画像 ID(後で配置に使う) | |
| -- q=2 : 端末からの応答を抑制 | |
| local id = image.transmit_image(path) | |
| if not id then | |
| print("画像の転送に失敗しました") | |
| os.exit(1) | |
| end | |
| print("転送完了: image_id = " .. id) | |
| -- 3. 画像のピクセルサイズを取得 | |
| local img_w, img_h = image.image_dimensions(path) | |
| print(string.format("画像サイズ: %dx%d px", img_w or 0, img_h or 0)) | |
| -- 4. 端末のセルサイズ(1文字あたりのピクセル数)を取得 | |
| local cell = image.get_cell_size() | |
| print(string.format("セルサイズ: %dx%d px", cell.cell_w, cell.cell_h)) | |
| -- 5. 表示サイズ(セル数)を計算(最大 40 列 x 20 行に収める) | |
| local cols, rows = image.calc_display_size(img_w, img_h, 40, 20) | |
| print(string.format("表示サイズ: %d cols x %d rows", cols, rows)) | |
| -- 6. カーソルを移動して画像を配置 | |
| -- 内部では以下のエスケープシーケンスを送っている: | |
| -- ESC_Ga=p,i=<id>,c=<cols>,r=<rows>,C=1,q=2 ESC\ | |
| -- a=p : put(保存済み画像を配置) | |
| -- c,r : 表示サイズ(セル単位) | |
| -- C=1 : カーソルを動かさない | |
| local tty = io.open("/dev/tty", "w") | |
| tty:write(string.rep("\n", rows)) -- 画像の高さ分の空行を確保 | |
| tty:write(string.format( | |
| "\x1b[%dA" -- カーソルを rows 行上に戻す | |
| .. "\x1b_Ga=p,i=%d,c=%d,r=%d,C=1,q=2\x1b\\" -- 画像を配置(空行を覆う) | |
| .. "\x1b[%dB", -- カーソルを空行の下に戻す | |
| rows, id, cols, rows, rows | |
| )) | |
| tty:close() | |
| -- 表示を維持してからクリーンアップ | |
| print(string.format("(%d 行分の画像を表示中… 3 秒後に削除します)", rows)) | |
| vim.uv.sleep(3000) | |
| -- 7. 画像を削除 | |
| -- ESC_Ga=d,d=i,i=<id>,q=2 ESC\ | |
| -- a=d : delete | |
| -- d=i : 指定 ID の画像を削除 | |
| image.delete_image(id) | |
| print("削除完了") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment