DEV Community

Cover image for Preview images, videos, fonts, PDFs ... in Vifm.
nisidabay
nisidabay

Posted on • Edited on

Preview images, videos, fonts, PDFs ... in Vifm.

Enhanced Image Preview in Vifm with Ueberzug

A Guide to Implementing Robust Image and Media Previews in Vifm with Proper Cache Handling and Preview Cleanup

This enhancement improves the original vifmimg script by adding cache management and fixing preview persistence issues.

Rationale Behind All This

As a Vim enthusiast, I always wanted to replicate my daily workflow based on keymappings and completely avoid using the mouse. I missed the functionality offered by tools like ranger or lf in Vifm, but I didn't want to learn a whole new set of keyboard shortcuts. I watched several YouTube videos trying to recreate this setup, but none quite hit the mark. The project that inspired this work didn't fully meet its intended functionality.

After spending many sleepless nights struggling with it, I have finally achieved something that feels rewarding, at least to me, and I want to share it with you.

I have currently verified these configurations only on Arch Linux"

Prerequisites

Ensure you have these packages installed:

  • vifm
  • ueberzug
  • ffmpegthumbnailer
  • pdftoppm (from poppler-utils)
  • epub-thumbnailer
  • djview (for DJVU documents)
  • ffmpeg
  • fontpreview
  • imagemagick

Packages Installation for Arch Linux

# Install required packages
sudo pacman -S vifm ueberzug ffmpegthumbnailer poppler djvulibre imagemagick

# Install fontpreview using AUR helper
yay -S fontpreview
Enter fullscreen mode Exit fullscreen mode

Follow the instructions in epub-thumbnailer for additional installation steps.

Original Idea and Code

The original scripts can be found in the thimc/vifmimg repository.

Installation Steps

1. Get Original Scripts

Create the scripts directory and download the original scripts:

# Create scripts directory
mkdir -p ~/.config/vifm/scripts

# Download original scripts
wget -P ~/.config/vifm/scripts/ https://raw.githubusercontent.com/thimc/vifmimg/master/vifmimg
wget -P ~/.config/vifm/scripts/ https://raw.githubusercontent.com/thimc/vifmimg/master/vifmrun
Enter fullscreen mode Exit fullscreen mode

2. Implement Enhanced vifmimg Script

Replace the content of ~/.config/vifm/scripts/vifmimg with the improved version below. This version includes proper cache handling and fixes preview persistence issues:

#!/usr/bin/bash

# Cache directory
CACHE_DIR="$HOME/.cache/vifm"
mkdir -p "$CACHE_DIR"

# Get a unique cache filename for the current file
PCACHE="$CACHE_DIR/thumbnail.$(stat --printf '%n\0%i\0%F\0%s\0%W\0%Y' -- "$(readlink -f "$PWD/$6")" | sha256sum)"
export PCACHE="${PCACHE%% *}"

# Clear ueberzug preview and optionally remove cache
pclear() {
    printf '{"action": "remove", "identifier": "vifm-preview"}\n' > "$FIFO_UEBERZUG"
    # Only remove cache if explicitly requested
    if [ "$1" = "cache" ]; then
        rm -f "$PCACHE"*
    fi
}

# Display image using ueberzug
image() {
    # Always clear the previous preview first
    pclear
    # Small delay to ensure previous preview is cleared
    sleep 0.1
    printf '{"action": "add", "identifier": "vifm-preview", "x": "%s", "y": "%s", "width": "%s", "height": "%s", "scaler": "contain", "path": "%s"}\n' \
        "$2" "$3" "$4" "$5" "$6" > "$FIFO_UEBERZUG"
}

main() {
    case "$1" in
        "clear")
            pclear "cache"
            ;;
        "draw")
            FILE="$PWD/$6"
            # For direct image viewing, we don't cache
            image "$1" "$2" "$3" "$4" "$5" "$FILE"
            ;;
        "video")
            FILE="$PWD/$6"
            pclear
            [ ! -f "${PCACHE}.jpg" ] && \
                ffmpegthumbnailer -i "$FILE" -o "${PCACHE}.jpg" -s 0 -q 5
            image "$1" "$2" "$3" "$4" "$5" "${PCACHE}.jpg"
            ;;
        "epub")
            FILE="$PWD/$6"
            pclear
            [ ! -f "$PCACHE" ] && \
                epub-thumbnailer "$FILE" "$PCACHE" 1024
            image "$1" "$2" "$3" "$4" "$5" "$PCACHE"
            ;;
        "pdf")
            FILE="$PWD/$6"
            pclear
            [ ! -f "${PCACHE}.jpg" ] && \
                pdftoppm -jpeg -f 1 -singlefile "$FILE" "$PCACHE"
            image "$1" "$2" "$3" "$4" "$5" "${PCACHE}.jpg"
            ;;
        "djvu")
            FILE="$PWD/$6"
            pclear
            [ ! -f "${PCACHE}.jpg" ] && \
                ddjvu -format=tiff -quality=90 -page=1 "$FILE" "${PCACHE}.jpg"
            image "$1" "$2" "$3" "$4" "$5" "${PCACHE}.jpg"
            ;;
        "audio")
            FILE="$PWD/$6"
            pclear
            [ ! -f "${PCACHE}.jpg" ] && \
                ffmpeg -hide_banner -i "$FILE" "${PCACHE}.jpg" -y >/dev/null
            image "$1" "$2" "$3" "$4" "$5" "${PCACHE}.jpg"
            ;;
        "font")
            FILE="$PWD/$6"
            pclear
            [ ! -f "${PCACHE}.jpg" ] && \
                fontpreview -i "$FILE" -o "${PCACHE}.jpg"
            image "$1" "$2" "$3" "$4" "$5" "${PCACHE}.jpg"
            ;;
        *)
            # Clear preview for any unhandled file types
            pclear "cache"
            ;;
    esac
}

main "$@"

Enter fullscreen mode Exit fullscreen mode

3. Make Scripts Executable and Accessible

Choose one of these methods:

Option A: Link to /usr/local/bin (Recommended)

# Make scripts executable
chmod +x ~/.config/vifm/scripts/vifmrun
chmod +x ~/.config/vifm/scripts/vifmimg

# Create symbolic links
sudo ln -s ~/.config/vifm/scripts/vifmrun /usr/local/bin/
sudo ln -s ~/.config/vifm/scripts/vifmimg /usr/local/bin/
Enter fullscreen mode Exit fullscreen mode

Option B: Add to PATH

Add the following line to your ~/.bashrc or ~/.zshrc:

export PATH=$PATH:$HOME/.config/vifm/scripts

# Reload shell configuration
source ~/.bashrc  # or source ~/.zshrc for zsh users
Enter fullscreen mode Exit fullscreen mode

4. Configure Vifm

Add these lines to your ~/.config/vifm/vifmrc to enable file previews:

" ------------------------------------------------------------------------------
" File preview settings with vifmimg
" ------------------------------------------------------------------------------

" Image, video, pdf, and similar formats
fileviewer *.pdf
        \ vifmimg pdf %px %py %pw %ph %c %pc

fileviewer *.epub
        \ vifmimg epub %px %py %pw %ph %c %pc

fileviewer *.djvu
        \ vifmimg djvu %px %py %pw %ph %c %pc

fileviewer *.avi,*.mp4,*.wmv,*.dat,*.3gp,*.ogv,*.mkv,*.mpg,*.mpeg,*.vob,
        \*.fl[icv],*.m2v,*.mov,*.webm,*.ts,*.mts,*.m4v,*.r[am],*.qt,*.divx,
        \*.as[fx]
        \ vifmimg video %px %py %pw %ph %c %pc

fileviewer *.bmp,*.jpg,*.jpeg,*.png,*.xpm,*.webp,*.gif,*.jfif
        \ vifmimg draw %px %py %pw %ph %c %pc

fileviewer *.otf,*.ttf
        \ vifmimg font %px %py %pw %ph %c %pc

fileviewer *.wav,*.mp3,*.flac,*.m4a,*.wma,*.ape,*.ac3,*.og[agx],*.spx,*.opus,*.aac
        \ vifmimg audio %px %py %pw %ph %c %pc

" ------------------------------------------------------------------------------
" Text-based file previews
" ------------------------------------------------------------------------------
fileviewer *.txt
        \ vifmimg clear %px %py %pw %ph %c && bat --style=numbers --color=always %c

fileviewer *.log
        \ vifmimg clear %px %py %pw %ph %c && bat --style=numbers --color=always %c

fileviewer *.md,*.markdown
        \ vifmimg clear %px %py %pw %ph %c && bat --style=numbers --color=always %c

fileviewer *.json
        \ vifmimg clear %px %py %pw %ph %c && bat --style=numbers --color=always %c

fileviewer *.py,*.js,*.jsx,*.ts,*.tsx,*.css,*.html,*.php,*.c,*.cpp,*.h,*.rb,*.sh
        \ vifmimg clear %px %py %pw %ph %c && bat --style=numbers --color=always %c

" Archive formats
fileviewer *.zip,*.jar,*.war,*.ear,*.oxt
        \ vifmimg clear %px %py %pw %ph %c && unzip -l %c

fileviewer *.tgz,*.tar.gz
        \ vifmimg clear %px %py %pw %ph %c && tar -tzf %c

fileviewer *.tar.bz2,*.tbz2
        \ vifmimg clear %px %py %pw %ph %c && tar -tjf %c

fileviewer *.tar.xz,*.txz
        \ vifmimg clear %px %py %pw %ph %c && tar -tJf %c

" Default file viewer for other formats
fileviewer *
        \ vifmimg clear %px %py %pw %ph %c && bat --style=numbers --color=always %c || echo "No preview available"

"fileviewer *
"        \ vifmimg clear %px %py %pw %ph %c && bat --style=numbers --color=always %c 2>/dev/null || echo "No preview available"

Enter fullscreen mode Exit fullscreen mode

This is only the configuration for previewing images, you also need to add these configurations down below to open them:

" Pdf
filextype {*.pdf},<application/pdf> zathura %c  &, mupdf %c, xpdf %c

"csv
filextype {*.csv},<application/csv> libreoffice %c  &

" Markdown files
filetype {*.md},<text/markdown> vim

" Text files
filetype {*.txt},<text/plain> vim

" PostScript
filextype {*.ps,*.eps,*.ps.gz},<application/postscript>
        \ {View in zathura}
        \ zathura %f &,
        \ {View in gv}
        \ gv %c %i &,

" Djvu
filextype {*.djvu},<image/vnd.djvu>
        \ {View in zathura} \ zathura %f &,
        \ {View in apvlv}
        \ apvlv %f,

" Audio
filetype {*.wav,*.mp3,*.flac,*.m4a,*.wma,*.ape,*.ac3,*.og[agx],*.spx,*.opus},
        \<audio/*>
       \ {Play using ffplay}
       \ ffplay -nodisp -hide_banner -autoexit %c,
       \ {Play using MPlayer}
       \ mplayer %c,
       \ {Play using mpv}
       \ mpv --no-video %c %s,


" Video
filextype {*.avi,*.mp4,*.wmv,*.dat,*.3gp,*.ogv,*.mkv,*.mpg,*.mpeg,*.vob,
          \*.fl[icv],*.m2v,*.mov,*.webm,*.ts,*.mts,*.m4v,*.r[am],*.qt,*.divx,
          \*.as[fx]},
         \<video/*>
        \ mpv --no-terminal --no-osd-bar %f

" Web
filextype {*.xhtml,*.html,*.htm},<text/html>
        \ {Open with qutebrowser}
        \ qutebrowser %f %i &,
        \ {Open with firefox}
        \ firefox %f &,
filetype {*.xhtml,*.html,*.htm},<text/html> links, lynx


" Man page
filetype {*.[1-8]},<text/troff> man ./%c

" Images
filextype {*.bmp,*.jpg,*.jpeg,*.png,*.gif,*.xpm},<image/*>
        \ {View in sxiv}
        \ sxiv %c,

Enter fullscreen mode Exit fullscreen mode

These are examples of my file associations, which you can modify to open files according to your preferences by installing the applications of your liking. There is a subtle difference between filetype and filextype:

  • filetype is used for console-based applications
  • filextype is used for graphical applications

Depending on the file type, you'll need to download the required binaries if they aren't already present.

Features

  • Cached Thumbnails: Faster performance due to cached image thumbnails.
  • Proper Preview Cleanup: Ensures that previews are cleared when switching files.
  • Support for Multiple File Formats:
    • Images: PNG, JPG, BMP, XPM
    • Documents: PDF, EPUB, DJVU
    • Videos: Thumbnails for AVI, MP4, MKV, etc.
    • Audio: Album art previews
    • Fonts: Preview support for OTF, TTF

Screenshots

Image description

Image description

Image description

Image description

Image description

Known Behavior

When toggling preview mode with w:

  1. If a preview persists, navigate to another directory to clear the preview or press h l to refresh the preview.
  2. Then press w again to exit preview mode.

Terminal

The terminal I am currently using is st but I have also tested this "Vifm" enhancement in kitty and alacritty.

Credits

Original vifmimg scripts by thimc, FOSS and GNU community for their incredible job.
How easy everything is when standing on the shoulders of giants.

License

This enhancement is provided under the same license as the original vifmimg project which is GPL-3.0 license.

Disclaimer

Please make a backup copy of your .vifmrc configuration file before applying these changes.
This guide serves as a starting point to configure Vifm to your preferences, and I continue to refine these configurations daily.
I'm a programming enthusiast sharing my experience. Please don't contact me for support, as I am not an expert.

Top comments (0)