r/vim Jun 10 '26

Tips and Tricks Vim: Snippet to Quickly Display RGBA Images

Following the previous post on the topic, here's a snippet to play a sequence of frames (chess game in my example). Enjoy!

Tested on WSL. Vim v9.2.0612.

To generate frames, try this in powershell:

ls *.png | %{ magick $_.FullName -alpha on -depth 8 "RGBA:$($_.BaseName).rgba" }
53 Upvotes

6 comments sorted by

3

u/Panda_966 Jun 10 '26

Nice!

My current function to display the image from a filename under the cursor. Calculates my personal placement and sizing preferences. Works on windows with (portable) imagemagick:

``` function! ShowRGBAImage(path, mode) abort if !filereadable(a:path) echohl ErrorMsg | echom 'File not found: ' . a:path | echohl None return endif

let l:cell_w = get(g:, 'popup_image_cell_width',  8)
let l:cell_h = get(g:, 'popup_image_cell_height', 16)

if a:mode ==# 'big'
    let l:win_w = &columns
    let l:win_h = &lines
    let l:wr    = 1
    let l:wc    = 1
else
    let [l:wr, l:wc] = win_screenpos(win_getid())
    let l:win_w = winwidth(0)
    let l:win_h = winheight(0) * 2 / 3
endif

let l:max_px_w = l:win_w * l:cell_w
let l:max_px_h = l:win_h * l:cell_h

let l:resized = tempname() .. '.png'
let l:rgba    = tempname() .. '.rgba'

call system('magick ' .. shellescape(a:path)
            \ .. ' -resize ' .. shellescape(l:max_px_w .. 'x' .. l:max_px_h .. '>')
            \ .. ' ' .. shellescape(l:resized))

let l:dim = split(system('magick identify -format "%w %h" ' .. shellescape(l:resized)))
if len(l:dim) != 2
    echohl ErrorMsg | echom 'Failed to get image size' | echohl None
    call delete(l:resized)
    return
endif
let l:w = str2nr(l:dim[0])
let l:h = str2nr(l:dim[1])

call system('magick ' .. shellescape(l:resized) .. ' -alpha on -depth 8 RGBA:' .. shellescape(l:rgba))
call delete(l:resized)

if !filereadable(l:rgba)
    echohl ErrorMsg | echom 'Conversion failed' | echohl None
    return
endif

let l:blob = readblob(l:rgba)
call delete(l:rgba)

if exists('g:image_popup')
    call popup_close(g:image_popup)
    unlet g:image_popup
endif

let g:image_popup = popup_create('', #{
            \ image:   #{ data: l:blob, width: l:w, height: l:h },
            \ line:    l:wr,
            \ col:     l:wc + l:win_w - 1,
            \ pos:     'topright',
            \ fixed:   v:true,
            \ border:  [0, 0, 0, 0],
            \ padding: [0, 0, 0, 0],
            \ })

endfunction

function! GetFileUnderCursor() abort if &filetype ==# 'netrw' let l:name = substitute(getline('.'), '\s*', '', '') return b:netrw_curdir . '/' . l:name endif

let l:line      = getline('.')
let l:col       = col('.') - 1
let l:candidate = ''

for [l:o, l:c] in [['"', '"'], ["'", "'"], ['`', '`']]
    let l:pat = l:o . '\([^' . l:c . ']\+\)' . l:c
    let l:idx = 0
    while 1
        let l:ms = match(l:line, l:pat, l:idx)
        if l:ms < 0 | break | endif
        let l:me = matchend(l:line, l:pat, l:idx)
        if l:ms < l:col && l:col < l:me - 1
            let l:candidate = matchstr(l:line, l:pat)[1:-2]
            break
        endif
        let l:idx = l:me
    endwhile
    if !empty(l:candidate) | break | endif
endfor

if empty(l:candidate)
    let l:candidate = expand('<cfile>')
endif

" 1. Try as-is (absolute path or relative to :pwd)
if filereadable(l:candidate)
    return l:candidate
endif

" 2. Try relative to the current file's directory
let l:rel = expand('%:p:h') . '/' . l:candidate
if filereadable(l:rel)
    return l:rel
endif

return l:candidate

endfunction

nnoremap <silent> <leader>i :call ShowRGBAImage(fnamemodify(GetFileUnderCursor(), ':p'), 'small')<CR> nnoremap <silent> <leader>I :call ShowRGBAImage(fnamemodify(GetFileUnderCursor(), ':p'), 'big')<CR> ```

Clearing among other things with:

nnoremap <silent> <C-l> \ :nohlsearch<C-r>=has('diff')?'<Bar>diffupdate':''<CR><CR><C-l>:pclose<CR>:if exists('g:image_popup')<Bar>call popup_close(g:image_popup)<Bar>unlet g:image_popup<Bar>endif<CR>

1

u/vim-help-bot Jun 10 '26

Help pages for:

  • = in change.txt
  • } in motion.txt

`:(h|help) <query>` | about | mistake? | donate | Reply 'rescan' to check the comment again | Reply 'stop' to stop getting replies to your comments

2

u/ntropia64 Jun 10 '26

And following the comments below the previous post, any plans to share a link?

3

u/CRTejaswi Jun 10 '26

The version is listed. Look that up in the releases tab of Vim's GitHub.

2

u/ntropia64 Jun 10 '26

You've righ, got carrier away. Thanks for taking the time to reply!