summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDLFW <daniel@llin.info>2023-07-10 00:39:26 +0200
committerGitHub <noreply@github.com>2023-07-09 18:39:26 -0400
commitb044a7cf1bf18e2c61bef277815f6a0e795995c6 (patch)
treeca01ecefa7297a2d5c28653c9323c727d624b36f
parentb57184e4ea72d4a97b83f6a9c3c5a0b9e5295cf8 (diff)
Add docs for Überzug++ as image previewer (#359)
* Add docs for Überzug++ as image previewer Adding instructions how Überzug++ can be used to preview image files in Joshuto. Additionally: * Restructure image preview documentation into multiple files in a sub-directory. * Add deprecation note and remove dead link to installation instructions for the Überzug recipe. * Some text enhancements here and there. * rename readme.md to README.md
-rw-r--r--docs/README.md2
-rw-r--r--docs/image_previews.md319
-rw-r--r--docs/image_previews/README.md58
-rw-r--r--docs/image_previews/combined_with_text.md72
-rw-r--r--docs/image_previews/kitty.md63
-rw-r--r--docs/image_previews/preview_text_image_combined.png (renamed from docs/preview_text_image_combined.png)bin784865 -> 784865 bytes
-rw-r--r--docs/image_previews/ueberzug.md154
-rw-r--r--docs/image_previews/ueberzugpp.md159
8 files changed, 507 insertions, 320 deletions
diff --git a/docs/README.md b/docs/README.md
index 90ee823..a97036c 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -4,6 +4,6 @@ These docs should help you get set up and understand how Joshuto works.
- [command line arguments](/docs/command_arguments.md)
- [configuration](/docs/configuration/)
-- [image previews](/docs/image_previews.md)
+- [image previews](/docs/image_previews/README.md)
- [misc](/docs/misc.md)
- [contributing](/docs/contributing.md)
diff --git a/docs/image_previews.md b/docs/image_previews.md
deleted file mode 100644
index e9c2d73..0000000
--- a/docs/image_previews.md
+++ /dev/null
@@ -1,319 +0,0 @@
-# Image Thumbnails in File Previews
-
-Joshuto does not support image previews directly.
-One reason is to keep Joshuto independent of specific display protocols and terminal emulators.
-
-However, Joshuto offers two preview-related hooks which allow to easily implement an
-image preview with some simple scripts.
-This page explains the integration with [Überzug](https://github.com/seebye/ueberzug),
-a Python tool to display images as overlays on a terminal emulator, and integration with [Kitty's Icat](https://sw.kovidgoyal.net/kitty/kittens/icat/).
-This exemplary solution shows previews for JPEG and PNG files.
-It has not been tested with MacOS and tmux.
-
-# Image Previews with Überzug
-
-Überzug must be [installed](https://github.com/seebye/ueberzug#installation) for the solution explained here.
-
-## Joshuto Wrapper
-
-First, we need a wrapper script for Joshuto.
-Joshuto is not started directly anymore but through that wrapper script.
-Place this script in a directory which is in your `$PATH`.
-You may name the script `j` or `jo` or whatever you like to type to start Joshuto.
-You may also name it `joshuto`, just take care that it
-must come before the actual `joshuto` binary in you `$PATH` in that case.
-
-```bash
-#!/usr/bin/env bash
-
-if [ -n "$DISPLAY" ] && command -v ueberzug > /dev/null; then
- export joshuto_wrap_id="$$"
- export joshuto_wrap_tmp="$(mktemp -d -t joshuto-wrap-$joshuto_wrap_id-XXXXXX)"
- export joshuto_wrap_ueber_fifo="$joshuto_wrap_tmp/fifo"
- export joshuto_wrap_pid_file="$joshuto_wrap_tmp/pid"
- export joshuto_wrap_preview_meta="$joshuto_wrap_tmp/preview-meta"
- export joshuto_wrap_ueber_identifier="preview"
-
- function start_ueberzug {
- mkfifo "${joshuto_wrap_ueber_fifo}"
- tail --follow "$joshuto_wrap_ueber_fifo" | ueberzug layer --parser bash &
- echo "$!" > "$joshuto_wrap_pid_file"
- mkdir -p "$joshuto_wrap_preview_meta"
- }
-
- function stop_ueberzug {
- ueberzug_pid=`cat "$joshuto_wrap_pid_file"`
- kill "$ueberzug_pid"
- rm -rf "$joshuto_wrap_tmp"
- }
-
- function show_image {
- >"${joshuto_wrap_ueber_fifo}" declare -A -p cmd=( \
- [action]=add [identifier]="${joshuto_wrap_ueber_identifier}" \
- [x]="${2}" [y]="${3}" \
- [width]="${4}" [height]="${5}" \
- [path]="${1}")
- }
-
- function remove_image {
- >"${joshuto_wrap_ueber_fifo}" declare -A -p cmd=( \
- [action]=remove [identifier]="${joshuto_wrap_ueber_identifier}")
- }
-
- function get_preview_meta_file {
- echo "$joshuto_wrap_preview_meta/$(echo "$1" | md5sum | sed 's/ //g')"
- }
-
- export -f get_preview_meta_file
- export -f show_image
- export -f remove_image
-
- trap stop_ueberzug EXIT QUIT INT TERM
- start_ueberzug
- echo "ueberzug started"
-fi
-
-joshuto "$@"
-exit $?
-```
-
-The script must be _executable_!
-
-This script starts an “ueberzug server” and then Joshuto itself.
-It takes care that ueberzug is stopped when
-`joshuto` terminates.
-Each Joshuto instance will have its own instance of an “ueberzug server”.
-The script also provides some functions
-and variables which can be used in sub-processes.
-
-## Configuring Hook Scripts
-
-When started with the wrapper script, Joshuto's sub-processes can show and remove a
-preview image with Überzug now. Joshuto offers two hooks which will be used for that.
-
-In your `~/.config/joshuto/joshuto.toml`, configure a script for each of these hooks:
-
-```toml
-[preview]
-...
-preview_shown_hook_script = "~/.config/joshuto/on_preview_shown"
-preview_removed_hook_script = "~/.config/joshuto/on_preview_removed"
-```
-
-The “shown” script will be called each time a file preview is shown by Joshuto.
-The “removed” script will be called each time the file preview disappears in Joshuto.
-That is the case if the user selects a file for which no file preview is shown
-(either due to missing output of the preview script or due to file size),
-if the preview is not cached already and the preview pane is temporarily removed,
-or if the selection jumps from a file to a directory.
-
-The “shown” script gets the path of the file being previwed
-as first argument and then the x and y coordinate and the width an
-height of the preview area as second to fifth parameters.
-
-The “removed” script does not get any arguments.
-
-Keep in mind that the result of the `preview` script you use for textual previews
-is cached by Joshuto and not called every time a file is focused, but the “shown” hook is.
-
-## The Hook Scripts
-
-Now we need to create the two hook scripts which have been configured before.
-
-Create these two scripts and make them _executable_!
-
-`~/.config/joshuto/on_preview_shown`:
-
-```bash
-#!/usr/bin/env bash
-
-test -z "$joshuto_wrap_id" && exit 1;
-
-path="$1" # Full path of the previewed file
-x="$2" # x coordinate of upper left cell of preview area
-y="$3" # y coordinate of upper left cell of preview area
-width="$4" # Width of the preview pane (number of fitting characters)
-height="$5" # Height of the preview pane (number of fitting characters)
-
-
-# Find out mimetype and extension
-mimetype=$(file --mime-type -Lb "$path")
-extension=$(/bin/echo "${path##*.}" | awk '{print tolower($0)}')
-
-case "$mimetype" in
- image/png | image/jpeg)
- show_image "$path" $x $y $width $height
- ;;
- *)
- remove_image
-
-esac
-```
-
-`~/.config/joshuto/on_preview_removed`:
-
-```bash
-#!/usr/bin/env bash
-test -z "$joshuto_wrap_id" && exit 1;
-remove_image
-```
-
-The first script shows a preview in case we have a JPEG or PNG file.
-If there is already a preview image shown, it will just be replaced.
-If we have a file other than JPEG or PNG, any preview which might be
-visible is removed.
-
-The second script just removes a preview image in case one is currently shown.
-
-The removal of a preview in the first script is important when the user changes
-the selection from one file with a preview to another.
-The removal in the second script is important when the user changes the selection
-from a file with a preview to a file without a preview or a directory.
-
-That's it. Previewing JPEG and PNG files should work now when the wrapper
-script is started.
-
-# Combining Text Preview and Thumbnails
-
-It's possible to combine a textual preview and an image preview.
-The wrapper script shown above exports one more function,
-`get_preview_meta_file`,
-which returns a unique, temporary file location for any path that can be used
-to hand over information from the preview script to the hooks script.
-
-In this example, we use that file to store the information on which y-offset
-the preview image shall be drawn to place the preview image beneath the textual preview.
-
-![Combined Text and Image Preview](preview_text_image_combined.png)
-
-Let's say we have this handling for JPEG and PNG files in the **`preview`** script:
-
-```bash
-case "$mimetype" in
-
- ...
-
- image/png | image/jpeg)
- dimension="Size `exiftool "$path" | grep '^Image Size' | awk '{print $4}'`"
- tags=$(tmsu_tag_list)
- echo "$dimension"
- echo "$tags"
- meta_file="$(get_preview_meta_file $path)"
- let y_offset=`printf "${tags}" | sed -n '=' | wc -l`+2
- echo "y-offset $y_offset" > "$meta_file"
- exit 4
- ;;
-```
-
-Here, we fetch some data we want as text (dimensions of the image and some tags) and just print it out for
-Joshuto to show.
-Additionally, we calculate the height of our output and write it to a temporary file, specific for the
-current `$path`, which has been provided by the wrapper script via the `get_preview_meta_file` function.
-
-Then we adapt the “preview shown” hook script as follows:
-
-```bash
-...
-
-case "$mimetype" in
- image/png | image/jpeg)
- meta_file="$(get_preview_meta_file $path)"
- y_offset=`cat "$meta_file" | grep "y-offset" | awk '{print $2}'`
- y=$(( $y + $y_offset ))
- show_image "$path" $x $y $width $height
- ;;
- *)
- remove_image
-
-esac
-```
-
-Here, we again get the path of our temporary file and use that offset information to
-display the image preview just below the textual output.
-
-Joshuto will have cached the textual output but all the temporary files will remain until
-Joshuto (and the wrapper script) are exited, so they will remain available for the hook scripts.
-
-# Image Previews with Kitty's Icat
-
-The Kitty terminal must be [installed](https://sw.kovidgoyal.net/kitty/binary/#) for the solution explained here.
-
-## Hook Scripts
-
-To preview images in Kitty, you need to create these two scripts and make them executable.
-
-`~/.config/joshuto/on_preview_shown`:
-
-```shell
-#!/usr/bin/env bash
-
-FILE_PATH="$1" # Full path of the previewed file
-PREVIEW_X_COORD="$2" # x coordinate of upper left cell of preview area
-PREVIEW_Y_COORD="$3" # y coordinate of upper left cell of preview area
-PREVIEW_WIDTH="$4" # Width of the preview pane (number of fitting characters)
-PREVIEW_HEIGHT="$5" # Height of the preview pane (number of fitting characters)
-
-TMP_FILE="$HOME/.cache/joshuto/thumbcache.png"
-
-mimetype=$(file --mime-type -Lb "$FILE_PATH")
-
-function image {
- kitty +kitten icat \
- --transfer-mode=file \
- --clear 2>/dev/null
- kitty +kitten icat \
- --transfer-mode=file \
- --place "${PREVIEW_WIDTH}x${PREVIEW_HEIGHT}@${PREVIEW_X_COORD}x${PREVIEW_Y_COORD}" \
- "$1" 2>/dev/null
-}
-
-case "$mimetype" in
- image/*)
- image "${FILE_PATH}"
- ;;
- *)
- kitty +kitten icat \
- --transfer-mode=file \
- --clear 2>/dev/null
- ;;
-esac
-```
-
-`~/.config/joshuto/on_preview_removed.sh`:
-
-```shell
-#!/usr/bin/env bash
-
-kitty +kitten icat \
- --transfer-mode=file \
- --clear 2>/dev/null
-```
-
-The first script will use icat to place an image on top of joshuto's preview window.
-If any images already exist, they will be cleared before showing the image.
-
-The second script simply clears any existing images on the screen.
-
-Thats it. Previewing images should now work whenever you select a file.
-
-NOTE: make sure the `preview_file.sh` script returns 5 exit code when previewing images in order for this to work:
-
-```sh
-...
-handle_mime() {
- ...
- exit 5
-}
-```
-
-## Kitty Demo:
-
-![Demo](https://user-images.githubusercontent.com/57725322/150659504-203c7175-4bee-4e46-b5c5-16cc16a51a12.png)
-
-# Further Options
-
-By extending the scripts, image previews can also be provided for other formats, including
-videos, SVGs and whatever else. The wrapper script can be extended to provide a 2nd temporary
-file to cache a thumbnail for those file types which cannot be displayed by Überzug directly.
-
-Feel free to provide recipes to include in this documentation.
diff --git a/docs/image_previews/README.md b/docs/image_previews/README.md
new file mode 100644
index 0000000..e52d0d3
--- /dev/null
+++ b/docs/image_previews/README.md
@@ -0,0 +1,58 @@
+# Image Thumbnails in File Previews
+
+Joshuto does not support image previews directly.
+One reason is that Joshuto wants to stay independent of specific display protocols and terminal emulators.
+
+However, Joshuto offers two preview-related hooks which allow to easily implement an
+image preview with some simple scripts.
+The hooks can be configured in the `joshuto.toml` file.
+```toml
+[preview]
+...
+preview_shown_hook_script = "~/path/to/some/executable_script_1"
+preview_removed_hook_script = "~/path/to/some/executable_script_2"
+```
+The shown-hook is called whenever a new file-preview (in the 3rd pane) is activated.
+
+The removed-hook will be called each time the file preview panel
+completely disappears in Joshuto.
+That is the case if the user selects a file for which no file preview is shown
+(either due to missing output of the preview script or due to file size),
+if the preview is not cached already and the preview pane is temporarily removed,
+or if the selection jumps from a file to a directory.
+
+The “shown” script gets the path of the file being previewed
+as first argument and then the x and y coordinate and the width an
+height of the preview area as second to fifth parameters.
+
+The “removed” script does not get any arguments.
+
+Using these hook, one can trigger various actions when moving the cursor along files in Joshuto,
+and they can also be used to show image previews by the help of other 3rd party tools.
+
+Keep in mind that the result of the “normal” `preview` script you use for textual previews
+is cached by Joshuto and is not called every time a file is focused, but the “shown” hook is.
+
+# Wrapper Script
+For some of the 3rd party tools, it's necessary
+to run them as a separate process, in parallel to Joshuto.
+
+One famous example is “Überzug”. To be able to use such a solution,
+one need to have a “wrapper-script” which must be started instead of Joshuto.
+The wrapper-script will then start both, first the program for showing images
+in the terminal and then Joshuto.
+
+
+# Recipes
+## Image Thumbnail Solution Recipes
+We have recipes for a few famous solutions.
+* [Überzug](ueberzug.md) (only for X11)
+* [Überzug++](ueberzugpp.md) (for X11, some Wayland compositors, and some specific terminal emulators)
+* [Kitty](kitty.md) (for the Kitty terminal)
+
+## Other Recipes and Tricks
+* [Combining text preview and image preview](combined_with_text.md)
+
+# Recipe Contributions welcome 🤗
+
+Feel free to provide recipes to include in this documentation.
diff --git a/docs/image_previews/combined_with_text.md b/docs/image_previews/combined_with_text.md
new file mode 100644
index 0000000..39dd8b3
--- /dev/null
+++ b/docs/image_previews/combined_with_text.md
@@ -0,0 +1,72 @@
+# Combining Text Preview and Thumbnails
+When using a wrapper script like used for the Überzug and Überzug++ recipes,
+it is possible to hand over information from the textual preview script to
+the hook scripts.
+
+With this, it's possible to combine a textual preview and an image preview
+by giving a y-offset for the image to the hook script.
+
+The wrapper scripts used in the Überzug and Überzug++ recipes
+exports another function,
+`get_preview_meta_file`,
+which returns a unique, temporary file location for
+each file that may be previewed in Joshuto.
+
+In this example, we use these file locations to store information on which y-offset
+the preview image shall be drawn to be placed beneath the textual preview.
+
+![Combined Text and Image Preview](preview_text_image_combined.png)
+
+## Adapt the Text Preview Script to calculate an Y-Offset
+
+Let's say we have this handling for JPEG and PNG files in the **`preview`** script (the “normal” preview script for textual preview):
+
+```bash
+case "$mimetype" in
+
+ ...
+
+ image/png | image/jpeg)
+ dimension="Size `exiftool "$path" | grep '^Image Size' | awk '{print $4}'`"
+ tags=$(tmsu_tag_list)
+ echo "$dimension"
+ echo "$tags"
+ meta_file="$(get_preview_meta_file $path)"
+ let y_offset=`printf "${tags}" | sed -n '=' | wc -l`+2
+ echo "y-offset $y_offset" > "$meta_file"
+ exit 4
+ ;;
+```
+
+Here, we fetch some data we want as text (dimensions of the image and some tags) and just print it out for
+Joshuto to show like for just a textual preview.
+Additionally, we calculate the height of our output and write it to a temporary file, specific for the
+current `$path`, which has been provided by the wrapper script via the `get_preview_meta_file` function.
+
+## Adapt the "preview-shown" Script to put the Image at the right Y-Offset
+
+After we have the y-offset available, we adapt the “preview shown” hook script as follows:
+
+```bash
+...
+
+case "$mimetype" in
+ image/png | image/jpeg)
+ meta_file="$(get_preview_meta_file $path)"
+ y_offset=`cat "$meta_file" | grep "y-offset" | awk '{print $2}'`
+ y=$(( $y + $y_offset ))
+ show_image "$path" $x $y $width $height
+ ;;
+ *)
+ remove_image
+
+esac
+```
+
+Here, we again get the path of our temporary file and then
+use that offset information to
+display the image preview just below the textual output.
+
+Joshuto will have cached the textual output but all the temporary files will remain until
+Joshuto (and the wrapper script) are exited, so they will remain available for the hook scripts.
+
diff --git a/docs/image_previews/kitty.md b/docs/image_previews/kitty.md
new file mode 100644
index 0000000..84c142d
--- /dev/null
+++ b/docs/image_previews/kitty.md
@@ -0,0 +1,63 @@
+# Image Previews with Kitty's `icat`
+
+The [Kitty](https://sw.kovidgoyal.net/kitty/) terminal must be [installed](https://sw.kovidgoyal.net/kitty/binary/#)
+and used for the solution explained here.
+
+To preview images in Kitty, you need to create these two scripts and make them executable.
+
+`~/.config/joshuto/on_preview_shown`:
+
+```shell
+#!/usr/bin/env bash
+
+FILE_PATH="$1" # Full path of the previewed file
+PREVIEW_X_COORD="$2" # x coordinate of upper left cell of preview area
+PREVIEW_Y_COORD="$3" # y coordinate of upper left cell of preview area
+PREVIEW_WIDTH="$4" # Width of the preview pane (number of fitting characters)
+PREVIEW_HEIGHT="$5" # Height of the preview pane (number of fitting characters)
+
+TMP_FILE="$HOME/.cache/joshuto/thumbcache.png"
+
+mimetype=$(file --mime-type -Lb "$FILE_PATH")
+
+function image {
+ kitty +kitten icat \
+ --transfer-mode=file \
+ --clear 2>/dev/null
+ kitty +kitten icat \
+ --transfer-mode=file \
+ --place "${PREVIEW_WIDTH}x${PREVIEW_HEIGHT}@${PREVIEW_X_COORD}x${PREVIEW_Y_COORD}" \
+ "$1" 2>/dev/null
+}
+
+case "$mimetype" in
+ image/*)
+ image "${FILE_PATH}"
+ ;;
+ *)
+ kitty +kitten icat \
+ --transfer-mode=file \
+ --clear 2>/dev/null
+ ;;
+esac
+```
+
+`~/.config/joshuto/on_preview_removed.sh`:
+
+```shell
+#!/usr/bin/env bash
+
+kitty +kitten icat \
+ --transfer-mode=file \
+ --clear 2>/dev/null
+```
+
+The first script will use `icat` to place an image on top of joshuto's preview window.
+If any images already exist, they will be cleared before showing the image.
+
+The second script simply clears any existing images on the screen.
+
+That's it. Previewing images should now work whenever you select a file.
+
+![Demo](https://user-images.githubusercontent.com/57725322/150659504-203c7175-4bee-4e46-b5c5-16cc16a51a12.png)
+
diff --git a/docs/preview_text_image_combined.png b/docs/image_previews/preview_text_image_combined.png
index 04c9753..04c9753 100644
--- a/docs/preview_text_image_combined.png
+++ b/docs/image_previews/preview_text_image_combined.png
Binary files differ
diff --git a/docs/image_previews/ueberzug.md b/docs/image_previews/ueberzug.md
new file mode 100644
index 0000000..824f239
--- /dev/null
+++ b/docs/image_previews/ueberzug.md
@@ -0,0 +1,154 @@
+# Image Previews with Überzug
+This recipe shows how to use [Überzug](https://github.com/seebye/ueberzug) to display image previews.
+Be aware that the Überzug project is archived and not maintained anymore.
+
+Überzug must be installed for the solution explained here.
+
+## Joshuto Wrapper
+
+First, we need a wrapper script for Joshuto.
+Joshuto is not started directly anymore but by that wrapper script
+after Überzug has been started.
+Place this script in a directory which is in your `$PATH`.
+You may name the script `j` or `jo` or whatever you like to type to start Joshuto.
+You may also name it `joshuto`, just take care that it
+must come before the actual `joshuto` binary in you `$PATH` in that case and
+that the `joshuto` call down in the script calls the actual `joshuto` binary.
+
+```bash
+#!/usr/bin/env bash
+
+if [ -n "$DISPLAY" ] && command -v ueberzug > /dev/null; then
+ export joshuto_wrap_id="$$"
+ export joshuto_wrap_tmp="$(mktemp -d -t joshuto-wrap-$joshuto_wrap_id-XXXXXX)"
+ export joshuto_wrap_ueber_fifo="$joshuto_wrap_tmp/fifo"
+ export joshuto_wrap_pid_file="$joshuto_wrap_tmp/pid"
+ export joshuto_wrap_preview_meta="$joshuto_wrap_tmp/preview-meta"
+ export joshuto_wrap_ueber_identifier="preview"
+
+ function start_ueberzug {
+ mkfifo "${joshuto_wrap_ueber_fifo}"
+ tail --follow "$joshuto_wrap_ueber_fifo" | ueberzug layer --parser bash &
+ echo "$!" > "$joshuto_wrap_pid_file"
+ mkdir -p "$joshuto_wrap_preview_meta"
+ }
+
+ function stop_ueberzug {
+ ueberzug_pid=`cat "$joshuto_wrap_pid_file"`
+ kill "$ueberzug_pid"
+ rm -rf "$joshuto_wrap_tmp"
+ }
+
+ function show_image {
+ >"${joshuto_wrap_ueber_fifo}" declare -A -p cmd=( \
+ [action]=add [identifier]="${joshuto_wrap_ueber_identifier}" \
+ [x]="${2}" [y]="${3}" \
+ [width]="${4}" [height]="${5}" \
+ [path]="${1}")
+ }
+
+ function remove_image {
+ >"${joshuto_wrap_ueber_fifo}" declare -A -p cmd=( \
+ [action]=remove [identifier]="${joshuto_wrap_ueber_identifier}")
+ }
+
+ function get_preview_meta_file {
+ echo "$joshuto_wrap_preview_meta/$(echo "$1" | md5sum | sed 's/ //g')"
+ }
+
+ export -f get_preview_meta_file
+ export -f show_image
+ export -f remove_image
+
+ trap stop_ueberzug EXIT QUIT INT TERM
+ start_ueberzug
+ echo "ueberzug started"
+fi
+
+joshuto "$@"
+exit $?
+```
+
+The script must be _executable_!
+
+This script starts an “ueberzug server” and then Joshuto itself.
+It takes care that ueberzug is stopped when
+`joshuto` terminates.
+Each Joshuto instance will have its own instance of an “ueberzug server”.
+The script also provides some functions
+and variables which can be used in sub-processes.
+
+## Configuring Hook Scripts
+
+When started with the wrapper script, Joshuto's sub-processes can show and remove a
+preview image with Überzug now. Joshuto offers two hooks which will be used for that.
+
+In your `~/.config/joshuto/joshuto.toml`, configure a script for each of these hooks:
+
+```toml
+[preview]
+...
+preview_shown_hook_script = "~/.config/joshuto/on_preview_shown"
+preview_removed_hook_script = "~/.config/joshuto/on_preview_removed"
+```
+
+## The Hook Scripts
+
+Now we need to create the two hook scripts which have been configured before.
+
+Create these two scripts and make them _executable_!
+
+`~/.config/joshuto/on_preview_shown`:
+
+```bash
+#!/usr/bin/env bash
+
+test -z "$joshuto_wrap_id" && exit 1;
+
+path="$1" # Full path of the previewed file
+x="$2" # x coordinate of upper left cell of preview area
+y="$3" # y coordinate of upper left cell of preview area
+width="$4" # Width of the preview pane (number of fitting characters)
+height="$5" # Height of the preview pane (number of fitting characters)
+
+
+# Find out mimetype and extension
+mimetype=$(file --mime-type -Lb "$path")
+extension=$(/bin/echo "${path##*.}" | awk '{print tolower($0)}')
+
+case "$mimetype" in
+ image/png | image/jpeg)
+ show_image "$path" $x $y $width $height
+ ;;
+ *)
+ remove_image
+
+esac
+```
+
+`~/.config/joshuto/on_preview_removed`:
+
+```bash
+#!/usr/bin/env bash
+test -z "$joshuto_wrap_id" && exit 1;
+remove_image
+```
+
+The first script shows a preview in case we have a JPEG or PNG file.
+If there is already a preview image shown, it will just be replaced.
+If we have a file other than JPEG or PNG, any preview which might be
+visible is removed.
+
+The second script just removes a preview image in case one is currently shown.
+
+The removal of a preview in the first script is important when the user changes
+the selection from an image file to a non-image file with text preview.
+
+The removal in the second script is important when the user changes the selection
+from an image file to a file without even a text-preview or a directory.
+
+That's it. Previewing JPEG and PNG files should work now when the wrapper
+script is started.
+
+The `on_preview_shown` script may be extended for further mime-types.
+
diff --git a/docs/image_previews/ueberzugpp.md b/docs/image_previews/ueberzugpp.md
new file mode 100644
index 0000000..43b0311
--- /dev/null
+++ b/docs/image_previews/ueberzugpp.md
@@ -0,0 +1,159 @@
+# Image Previews with Überzug++
+This recipe shows how to use [Überzug++](https://github.com/jstkdng/ueberzugpp)to display image previews.
+Überzug++ is _not_ the famous Überzug, but a completely new project that tries to be compatible to
+“the old”, now unmaintained Überzug.
+
+Überzug++ must be [installed](https://github.com/jstkdng/ueberzugpp#install) for the solution explained here.
+In case of trouble, try first to get Überzug++ running standalone and check for parameters that
+work for you.
+
+This recipe is mostly the same as the Überzug recipe.
+Only the wrapper script is different.
+
+## Joshuto Wrapper
+
+First, we need a wrapper script for Joshuto.
+Joshuto is not started directly anymore but by that wrapper script
+after Überzug has been started.
+Place this script in a directory which is in your `$PATH`.
+You may name the script `j` or `jo` or whatever you like to type to start Joshuto.
+You may also name it `joshuto`, just take care that it
+must come before the actual `joshuto` binary in you `$PATH` in that case and
+that the `joshuto` call down in the script calls the actual `joshuto` binary.
+
+The first line in the `start_ueberzugpp` function may need to be adapted to your
+needs. It starts the actual `ueberzugpp` process that will show the images.
+You may want to remove the `--no-opencv` switch and maybe add an output specifier
+(like `-o kitty` to use the Kitty terminal backend).
+Consult the Überzug++ documentation.
+
+```bash
+#!/usr/bin/env bash
+#
+## Example wrapper for using Überzug++
+
+export joshuto_wrap_id="$$"
+export joshuto_wrap_tmp="$(mktemp -d -t joshuto-wrap-$joshuto_wrap_id-XXXXXX)"
+export joshuto_wrap_preview_meta="$joshuto_wrap_tmp/preview-meta"
+export ueberzug_pid_file="$joshuto_wrap_tmp/pid"
+export ueberzug_img_identifier="preview"
+export ueberzug_socket=""
+export ueberzug_pid=""
+
+
+function start_ueberzugpp {
+ ## Adapt Überzug++ options here. For example, remove the '--no-opencv' or set another output method.
+ ueberzugpp layer --no-stdin --pid-file "$ueberzug_pid_file" --no-opencv &>/dev/null
+ export ueberzug_pid="$(cat "$ueberzug_pid_file")"
+ export ueberzug_socket=/tmp/ueberzugpp-"$ueberzug_pid".socket
+ mkdir -p "$joshuto_wrap_preview_meta"
+}
+
+function stop_ueberzugpp {
+ remove_image
+ ueberzugpp cmd -s "$ueberzug_socket" -a exit
+ kill "$ueberzug_pid"
+ rm -rf "$joshuto_wrap_tmp"
+}
+
+function show_image {
+ ueberzugpp cmd -s "$ueberzug_socket" -a add -i "$ueberzug_img_identifier" -x "$2" -y "$3" --max-width "$4" --max-height "$5" -f "$1" &>/dev/null
+}
+
+function remove_image {
+ ueberzugpp cmd -s "$ueberzug_socket" -a remove -i "$ueberzug_img_identifier" &>/dev/null
+}
+
+function get_preview_meta_file {
+ echo "$joshuto_wrap_preview_meta/$(echo "$1" | md5sum | sed 's/ //g')"
+}
+
+export -f get_preview_meta_file
+export -f show_image
+export -f remove_image
+
+if [ -n "$DISPLAY" ] && command -v ueberzugpp > /dev/null; then
+ trap stop_ueberzugpp EXIT QUIT INT TERM
+ start_ueberzugpp
+fi
+
+joshuto "$@"
+exit $?
+```
+
+The script must be _executable_!
+
+## Configuring Hook Scripts
+
+When started with the wrapper script, Joshuto's sub-processes can show and remove a
+preview image with Überzug now. Joshuto offers two hooks which will be used for that.
+
+In your `~/.config/joshuto/joshuto.toml`, configure a script for each of these hooks:
+
+```toml
+[preview]
+...
+preview_shown_hook_script = "~/.config/joshuto/on_preview_shown"
+preview_removed_hook_script = "~/.config/joshuto/on_preview_removed"
+```
+
+## The Hook Scripts
+
+Now we need to create the two hook scripts which have been configured before.
+
+Create these two scripts and make them _executable_!
+
+`~/.config/joshuto/on_preview_shown`:
+
+```bash
+#!/usr/bin/env bash
+
+test -z "$joshuto_wrap_id" && exit 1;
+
+path="$1" # Full path of the previewed file
+x="$2" # x coordinate of upper left cell of preview area
+y="$3" # y coordinate of upper left cell of preview area
+width="$4" # Width of the preview pane (number of fitting characters)
+height="$5" # Height of the preview pane (number of fitting characters)
+
+
+# Find out mimetype and extension
+mimetype=$(file --mime-type -Lb "$path")
+extension=$(/bin/echo "${path##*.}" | awk '{print tolower($0)}')
+
+case "$mimetype" in
+ image/png | image/jpeg)
+ show_image "$path" $x $y $width $height
+ ;;
+ *)
+ remove_image
+
+esac
+```
+
+`~/.config/joshuto/on_preview_removed`:
+
+```bash
+#!/usr/bin/env bash
+test -z "$joshuto_wrap_id" && exit 1;
+remove_image
+```
+
+The first script shows a preview in case we have a JPEG or PNG file.
+If there is already a preview image shown, it will just be replaced.
+If we have a file other than JPEG or PNG, any preview which might be
+visible is removed.
+
+The second script just removes a preview image in case one is currently shown.
+
+The removal of a preview in the first script is important when the user changes
+the selection from an image file to a non-image file with text preview.
+
+The removal in the second script is important when the user changes the selection
+from an image file to a file without even a text-preview or a directory.
+
+That's it. Previewing JPEG and PNG files should work now when the wrapper
+script is started.
+
+The `on_preview_shown` script may be extended for further mime-types.
+