font preview in vifm

This setup is heavily inspired by Siddharth Dushantha’s bash script fontpreview.

I have been looking for a lightweight replacement for FontBase for a long time. It turns out it is quite easy to build my own command line font previewer using vifm, ImageMagick, and Überzug.

1 the preview script

The entire setup is based on the following bash script, which is adapted from fontpreview. It will generate a preview image for the input font file.

#!/usr/bin/env bash

PREVIEW_TEXT="ABCDEFGHIJKLM\n"\
"NOPQRSTUVWXYZ\n"\
"abcdefghijklm\n"\
"nopqrstuvwxyz\n"\
"1234567890\n"\
"!@$\%(){}[]"

convert -size "532x365" xc:"#ffffff" \
        -gravity center \
        -pointsize 38 \
        -font "$1" \
        -fill "#000000" \
        -annotate +0+0 "$PREVIEW_TEXT" \
        -flatten "$2"

The convert command is provided by ImageMagick. It must be installed before we can execute the script.

Save the script as fntprevw and add it to PATH. It can be executed by

$ fntprevw font.otf out.png

where font.otf is the font to be previewed and out.png is the filename of the output image.

I have also sent a pull request to fontpreview. If you are using it, you can generate the preview image using the -i and -o options.

$ fontpreview -i font.otf -o out.png

2 überzug wrapper

Once we can generate a preview image for a font file, it is easy to incorporate it into vifm using the fileviewer setting.

The configuration for vifm is based on the scripts provided by Überzug’s author seebye. It will use Überzug to display images inside vifm’s preview window.

First, we need to create a wrapper for vifm named vifmrun and add it to the system PATH.

#!/usr/bin/env bash

export FIFO_UEBERZUG="/tmp/vifm-ueberzug-${PPID}"

function cleanup() {
    rm "$FIFO_UEBERZUG" 2>/dev/null
    pkill -P $$ 2>/dev/null
}

rm "$FIFO_UEBERZUG" 2>/dev/null
mkfifo "$FIFO_UEBERZUG"
trap cleanup EXIT
tail --follow "$FIFO_UEBERZUG" | ueberzug layer --silent --parser bash &

vifm "$@"
cleanup

It will create a FIFO so that vifm can communicate with Überzug. In order to use Überzug for image preview inside vifm, you have to run vifm using the wrapper vifmrun.

You can rename the wrapper script to your preference. I have set up an alias in my .zshrc to run the script.

3 vifm config

Next, create a script named vifmimg inside the scripts directory of vifm’s config directory. You can alternatively add the script to system PATH.

#!/usr/bin/env bash

readonly ID_PREVIEW="preview"

# preview an image file directly
function draw() {
  declare -p -A cmd=([action]=add [identifier]="$ID_PREVIEW"
                     [x]="$2" [y]="$3" [width]="$4" [height]="$5" \
                     [path]="${PWD}/$6") \
    > "$FIFO_UEBERZUG"
}

# preview a font file (e.g. *.otf)
function font_prevw() {
  # if no preview found, generate one
  if [[ ! -f "/tmp${PWD}/$6.png" ]]; then
    fntprevw "$6" "/tmp${PWD}/$6.png"
    # if you are using fontpreview
    # fontpreview -i "$6" -o "/tmp${PWD}/$6.png"
  fi
  declare -p -A cmd=([action]=add [identifier]="$ID_PREVIEW"
                     [x]="$2" [y]="$3" [width]="$4" [height]="$5" \
                     [path]="/tmp${PWD}/$6.png") \
    > "$FIFO_UEBERZUG"
}

# ... other preview functions

# clear preview image
function clear_prevw() {
  declare -p -A cmd=([action]=remove [identifier]="$ID_PREVIEW") \
    > "$FIFO_UEBERZUG"
}

# make sure ueberzug's fifo exists
if [ -e "$FIFO_UEBERZUG" ]; then
  # make a temp dir for rendering if not exists
  if [[ ! -d "/tmp${PWD}/" ]]; then
    mkdir -p "/tmp${PWD}/"
  fi
  case "$1" in
    draw) draw "$@" ;;
    font) font_prevw "$@" ;;
    # ... other preview options
    clear) clear_prevw ;;
  esac
fi

After we have created the script to display the font preview, we need to set up a fileviewer for font files (e.g. .otf, .ttf, and .woff). Append the following to your vifmrc,

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

and if you want image previews as well,

fileviewer *.jpg,*.jpeg,*.png,*.bmp
        \ vifmimg draw %px %py %pw %ph %c
        \ %pc
        \ vifmimg clear

Now you should be able to preview font files by pressing W inside vifm. If you can’t see the preview, you might want to switch to another terminal emulator.