Post

Images in Neovim | Setting up Snacks Image and Comparing it to Image.nvim

I have been using the image.nvim plugin for some time to view images in neovim, this is specially useful when I'm working on a new blogpost, I use the plugin to view the images I'm uploading. Also, in very rare occassions, I add images to my markdown notes, so it becomes useful in that case too

Images in Neovim | Setting up Snacks Image and Comparing it to Image.nvim

Contents

Table of contents

YouTube video

Pre-requisites


  • If you don’t want to watch the video above, and you already have your own neovim config, and want to quickly get started and follow along in this tutorial
  • Run the git clone commands below to clone my dotfiles in your .config directory and we will run my config below
1
2
mkdir -p ~/.config
git clone git@github.com:linkarzu/dotfiles-latest ~/.config/linkarzu/dotfiles-latest
  • Open the newly downloaded neobean config with:
1
NVIM_APPNAME=linkarzu/dotfiles-latest/neovim/neobean nvim
  • You can create an alias in your .bashrc or .zshrc file to run my config
1
alias neobean='NVIM_APPNAME=linkarzu/dotfiles-latest/neovim/neobean nvim'
  • Then to run this config, just run neobean

  • If you don’t even have neovim yet, of course you will need to install it first, so if you’re just getting started, I have a video for you:

If you like my content, and want to support me

  • I create and edit my videos in an M1 mac mini, and it’s starting to stay behind in the editing side of things, tends to slow me down a bit, I’d like to upgrade the machine I use for all my videos to a mac mini with these specs:
    • Apple M4 Pro chip with 14‑core CPU, 20‑core GPU, 16-core Neural Engine
    • 24GB unified memory
    • 1TB SSD storage
    • 10 Gigabit Ethernet
  • If you want to help me reach my goal, you can donate here

Image

Discord server

Image

Follow me on social media

  • The following links will be in the YouTube video description:
    • Each one of the videos shown
    • A link to this blogpost

How do you manage your passwords?

Image

How do the images look?

  • Below you’ll find a few screenshots, notice that I’ll be showing images in different formats
  • There’s also an image that is going to be loaded from a URL
  • Notice that you can view images in the snacks picker
  • Also notice that the last image is preview of an .mp4 file

Image Image under the cursor displayed in a floating window

Image Image loaded from a URL

Image Image loaded on the top right corner

Image HTML image loaded

Image Image loaded in Snacks Picker

Image Image loaded in Snacks Picker

Image Image loaded in Snacks Picker

Image Preview of an mp4 file loaded as an image

Image Preview of a PDF file shown as an image

Why do I care about images in Neovim?

  • Notice that the article you’re reading right now has some images
  • I usually take a screenshot, and I have a Neovim keymap Alt+1 that allows me to paste that screenshot, or image into a file in Neovim, but what happens in the background?:
    • When I paste the image, the HakonHarnes/img-clip.nvim plugin is called and it converts the image I’m pasting into the format I specify, usually avif because they’re really small, quality is great and nowadays they’re compatible with most of the browsers
    • That avif converted image is stored to a location that I specify, if I’m on my blogpost, that’s usually the /assets/img/imgs directory
    • And then that image is added to my neovim file, and to make sure I have the right image, I need to preview it, and that’s where the snacks image plugin comes in handy

Does this replace the 3rd/image.nvim plugin

  • 3rd/image.nvim
  • I have been using the image.nvim plugin for a long time, it’s the only way you could see images in Neovim in the past
  • Yes, the snacks plugin replaces the image.nvim plugin, more on how below.

How does it compare to image.nvim then?

  • 3rd/image.nvim
  • image.nvim is an awesome plugin, I loved it and used it for a long time, there’s 2 things I like more about the snacks image plugin:
    • You get the preview of the image in a floating window, that’s optional, you don’t need to do it that way. I personally feel this integrates with my neovim workflow a little bit better. When not using the floating window, the entire screen moves around when you pass over an image. You’ll understand this a bit better by watching the video
    • The caching mechanism makes the images load way faster, the first time you load it it will take a few seconds because ImageMagick is converting them to the png format, but once they’re cached, they’ll load way faster

Who is the creator of Snacks Image?

  • If you’re new to Neovim, his name is Folke
  • He’s the creator of the LazyVim neovim distribution, also the lazy.nvim plugin manager, and a lot of great plugins, including flash.nvim and way more
  • He recently created the Snacks which is a collection of plugins, one of them being picker which for me, replaced my beloved telescope
  • github.com/folke

How did I find out about this plugin?

  • I was recording a video in which I go over how I basically re-created my Obsidian workflow but in Neovim
  • While recording I opened the file picker snacks and I noticed that I could preview images on the right hand side
  • So I figured out it was because folke had released this snacks image plugin a few days before


Configure Snacks Image

  • The most up to date version of my snacks image plugin config can be found in my dotfiles
  • Here’s a snippet as of today, but remember to go to my dotfiles for the latest updates
  • To enable the plugin, make sure that the enabled = true, line is added under the image section
    • In the video I had not added the styles.snacks_image section yet, but this is what allows you to display the image on the top right corner
  • My latest config can be found here: plugins/snacks.lua
  • ⭐⭐⭐⭐ Remember to star my dotfiles ⭐⭐⭐⭐
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
      -- This keeps the image on the top right corner, basically leaving your
      -- text area free, suggestion found in reddit by user `Redox_ahmii`
      -- https://www.reddit.com/r/neovim/comments/1irk9mg/comment/mdfvk8b/?utm_source=share&utm_medium=web3x&utm_name=web3xcss&utm_term=1&utm_content=share_button
      styles = {
        snacks_image = {
          relative = "editor",
          col = -1,
        },
      },
      image = {
        enabled = true,
        doc = {
          -- Personally I set this to false, I don't want to render all the
          -- images in the file, only when I hover over them
          -- render the image inline in the buffer
          -- if your env doesn't support unicode placeholders, this will be disabled
          -- takes precedence over `opts.float` on supported terminals
          inline = vim.g.neovim_mode == "skitty" and true or false,
          -- render the image in a floating window
          -- only used if `opts.inline` is disabled
          float = true,
          -- Sets the size of the image
          max_width = vim.g.neovim_mode == "skitty" and 20 or 60,
          max_height = vim.g.neovim_mode == "skitty" and 10 or 30,
          -- max_width = 60,
          -- max_height = 30,
          -- Apparently, all the images that you preview in neovim are converted
          -- to .png and they're cached, original image remains the same, but
          -- the preview you see is a png converted version of that image
          --
          -- Where are the cached images stored?
          -- This path is found in the docs
          -- :lua print(vim.fn.stdpath("cache") .. "/snacks/image")
          -- For me returns `~/.cache/neobean/snacks/image`
          -- Go 1 dir above and check `sudo du -sh ./* | sort -hr | head -n 5`
        },
      },
  • Notice above there’s this line inline = vim.g.neovim_mode == "skitty" and true or false,, you don’t have to add that or you’ll get an error, unless you’re using my skitty-notes app, if you don’t just replace that with inline = false

  • skitty-notes is the small app you see on the right hand side, it’s something custom I came up with that allows me to keep track of the stuff I need to do during the day, or other days, video ideas, etc

Image skitty-notes

Disable image.nvim

  • If you’re using the image.nvim plugin, make sure to disable it to avoid any conflicts
  • In my case, notice that I disabled luarocks.nvim and also the image.nvim plugin itself
  • The config to my image.nvim plugin can be found here: plugins/image-nvim.lua
  • ⭐⭐⭐⭐ MF, did you star the dotfiles already? ⭐⭐⭐⭐
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
  {
    -- luarocks.nvim is a Neovim plugin designed to streamline the installation
    -- of luarocks packages directly within Neovim. It simplifies the process
    -- of managing Lua dependencies, ensuring a hassle-free experience for
    -- Neovim users.
    -- https://github.com/vhyrro/luarocks.nvim
    "vhyrro/luarocks.nvim",
    enabled = false,
    -- this plugin needs to run before anything else
    priority = 1001,
    opts = {
      rocks = { "magick" },
    },
  },
  {
    "3rd/image.nvim",
    enabled = false,
    dependencies = { "luarocks.nvim" },

Caveats (tmux, wezterm, ImageMagick, Zellij)

  • If you go through the documentation, which can be found here: docs/image.md
  • You’re going to notice that if you’re using tmux, you need to make sure you add a config to your tmux.conf file, and reload the config
1
set -gq allow-passthrough on
  • WezTerm has some issues displaying images, folke explained what’s going on in this reddit post
  • You need to install ImageMagick because as Folke explained:
    • The kitty graphics protocol works with only png images, so all other formats are converted using ImageMagick. And those are indeed cached.
  • Zellij is no supported

How do you install ImageMagick?

  • I cover this in another video, but here’s the relevant section
  • ImageMagick
  • ImageMagick is an open source set of tools used to create, edit, compose, or convert bitmap images
  • Since we’ll be working with images, we need to install it with brew
1
brew install imagemagick
  • To confirm that ImageMagick is installed
1
identify -version
1
2
3
4
5
6
7
8
9
10
linkarzu.@.mini~/github
[24/06/02 13:38:40]
❯ identify -version

Version: ImageMagick 7.1.1-32 Q16-HDRI aarch64 22207 https://imagemagick.org
Copyright: (C) 1999 ImageMagick Studio LLC
License: https://imagemagick.org/script/license.php
Features: Cipher DPC HDRI Modules OpenMP(5.0)
Delegates (built-in): bzlib fontconfig freetype gslib heic jng jp2 jpeg jxl lcms lqr ltdl lzma openexr png ps raw tiff webp xml zlib zstd
Compiler: gcc (4.2)
  • >>>>>>>>>> REALLY IMPORTANT <<<<<<<<<<
  • Review the imagemagick package information, pay close attention to the Dependencies section
    • Notice that I’m not missing the pkg-config one
    • Otherwise you would see an x next to the name
  • Images were not working for me, and figuring out it was related to one of these dependencies took me a day, so pay close attention to this part
  • If you have any missing dependencies, install them using brew (see example below)
1
brew info imagemagick
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
linkarzu.@.mini~/github
[24/06/02 13:38:42]
❯ brew info imagemagick

==> imagemagick: stable 7.1.1-33 (bottled), HEAD
Tools and libraries to manipulate images in many formats
https://imagemagick.org/index.php
Installed
/opt/homebrew/Cellar/imagemagick/7.1.1-32 (809 files, 32.3MB) *
  Poured from bottle using the formulae.brew.sh API on 2024-05-22 at 16:22:20
From: https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/i/imagemagick.rb
License: ImageMagick
==> Dependencies
Build: pkg-config ✔
Required: fontconfig ✔, freetype ✔, ghostscript ✔, jpeg-turbo ✔, jpeg-xl ✔, libheif ✔, liblqr ✔, libpng ✔, libraw ✔, libtiff ✔, libtool ✔, little-cms2 ✔, openexr ✔, openjpeg ✔, webp ✔, xz ✔, gettext ✔, glib ✔, imath ✔, libomp ✔
==> Options
--HEAD
        Install HEAD version
==> Analytics
install: 76,865 (30 days), 217,784 (90 days), 894,695 (365 days)
install-on-request: 70,276 (30 days), 201,905 (90 days), 824,794 (365 days)
build-error: 19 (30 days)
  • Just as an example, let’s say you’re missing the pkg-config dependency, install it through brew with
1
brew install pkg-config

What if I want to use the image.nvim plugin?

What terminal emulator can I use?

  • I’m currently using Ghostty, that’s the one I demo in the video
  • But in the video I also demo how images work just fine in kitty (skitty-notes app on the right side)
  • I haven’t tested any other terminal emulators, but those are the ones I’ve always viewed images with in the past

Where are the cached images?

  • If you run this command
1
:lua print(vim.fn.stdpath("cache") .. "/snacks/image")
  • It shows me this directory
1
/Users/linkarzu/.cache/neobean/snacks/image
  • If I go to that directory I’ll be able to see all the png cached images, not sure if they’ll be eventually flushed by the plugin or something, but just keep this directory in mind, as it may grow over time
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
linkarzu.@.[25/02/18]
~/.cache/neobean/snacks/image
kubernetes
❯❯❯❯ ll
Permissions Size User     Group Date Modified Name
.rw-r--r--  984k linkarzu staff 18 Feb 08:54  04f080cf-dark.png
.rw-r--r--  1.1M linkarzu staff 18 Feb 08:41  1bd78e4d-250201-select.png
.rw-r--r--  1.4M linkarzu staff 18 Feb 08:34  1e94419d-theaudacity.png
.rw-r--r--  1.3M linkarzu staff 18 Feb 08:41  2bb0ef4e-250201-ivy.png
.rw-r--r--  3.1M linkarzu staff 18 Feb 08:31  2bdfde10-linkarzu-youtube.png
.rw-r--r--  1.7M linkarzu staff 18 Feb 08:41  2bf7db85-250201-default.png
.rw-r--r--  1.3M linkarzu staff 18 Feb 08:42  2c38a70d-250201-vertical.png
.rw-r--r--   61k linkarzu staff 18 Feb 09:15  3acc4e7d-250124-1password-banner.png
.rw-r--r--  1.8M linkarzu staff 18 Feb 08:53  4e232857-250218-snacks-image-url.png
.rw-r--r--  460k linkarzu staff 18 Feb 08:43  5e8c9456-250103-glove80-rgb.png
.rw-r--r--  1.1M linkarzu staff 18 Feb 08:41  7a60a93c-250201-vscode.png
.rw-r--r--  583k linkarzu staff 18 Feb 08:41  255bddd4-250126-whyugae.png
.rw-r--r--  1.7M linkarzu staff 18 Feb 09:03  393a8dd8-250218-snacks-image-picker-mp4.png
.rw-r--r--  1.2M linkarzu staff 18 Feb 08:53  435d3993-250218-snacks-image-html.png
.rw-r--r--  1.2M linkarzu staff 18 Feb 09:01  511fb8d0-yoink-issues.png
.rw-r--r--  1.7M linkarzu staff 18 Feb 08:31  4209f640-i.redd.it-leyzxn31efj21.jpg.png
.rw-r--r--  3.3M linkarzu staff 18 Feb 08:31  6089c5cc-terminal-transparent.png
.rw-r--r--  478k linkarzu staff 18 Feb 08:54  9089a301-250208-085214.png

Checkhealth command

  • In case you’re experiencing issues, images are not loading, etc, etc, run this command
1
:checkhealth snacks
  • And pay attention to the output, and make sure to go through each one of the ERROR and WARNING messages
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
Snacks.image ~
- OK setup {enabled}
- OK 'kitty' `kitty 0.39.1 created by Kovid Goyal`
- OK 'wezterm' `wezterm 20240203-110809-5046fc22`
- OK 'ghostty' `Ghostty 1.1.2`
- OK 'magick' `Version: ImageMagick 7.1.1-43 Q16-HDRI aarch64 22550 https://imagemagick.org`
- OK 'convert' `WARNING: The convert command is deprecated in IMv7, use "magick" instead of "convert" or "magick convert"`
- OK `ghostty` detected and supported
- OK `ghostty` supports unicode placeholders
- OK Inline images are available
- OK `tmux` detected and supported
- OK Terminal Dimensions:
  - {size}: `2718` x `1640` pixels
  - {scale}: `2.25`
  - {cell}: `18` x `40` pixels
- OK Image rendering for `css` is available
- OK Image rendering for `html` is available
- OK Image rendering for `javascript` is available
- WARNING Image rendering for `latex` is not available
- OK Image rendering for `markdown` is available
- OK Image rendering for `markdown_inline` is available
- WARNING Image rendering for `norg` is not available
- WARNING Image rendering for `scss` is not available
- OK Image rendering for `tsx` is available
- WARNING Image rendering for `typst` is not available
- WARNING Image rendering for `vue` is not available
- OK 'gs' `10.04.0`
- OK PDF files are supported
- ERROR None of the tools found: 'tectonic', 'pdflatex'
- WARNING `tectonic` or `pdflatex` is required to render LaTeX math equations
- ERROR Tool not found: 'mmdc'
- WARNING `mmdc` is required to render Mermaid diagrams
- OK your terminal supports the kitty graphics protocol

Start your 14 day FREE trial

Start your 14 day FREE trial

Image

This post is licensed under CC BY 4.0 by the author.