TITLE: urlview to easily handle URLs in the terminal
DATE: 2019-10-25
AUTHOR: John L. Godlee
====================================================================


I recently looked at newsboat as a way of reading RSS news feeds on
my laptop. I use [Feeder] to read the feeds on my android phone
and I wanted to keep up to date with the same list of feeds on my
laptop. That’s not very exciting, there were the usual UI
configurations to change colours and so on, but then I found that it
was quite clumsy to act on URLs that I found in posts. Many RSS
entries that I read, particularly those from Multi-reddits have
images attached alongside the description text. I could open the
whole entry in a web browser by pressing o within newsboat, but that
seemed like overkill. What I wanted to do was download and open only
the links I cared about.

  [Feeder]: https://f-droid.org/en/packages/com.nononsenseapps.feeder/

I came across [urlview] as a remedy for this problem. urlview
basically just checks through a text file or STDOUT and finds URLs,
then presents them to you in a selectable list. With no extra
configuration it just prints the selected URL to STDOUT, but with a
fairly simple shell script which defines how different types of URL
should be handled, it turns into a very neat way of handling URLs in
the terminal without having to copy and paste them.

  [urlview]: https://github.com/sigpipe/urlview

I installed urlview with brew install urlview. The configuration
file for urlview lives in ~/.urlview and can contain instructions
for what to do with links, in my case a shell script takes care of
this, called linkhandler and lives in my $PATH. ~/.urlview contains:

    COMMAND linkhandler

The linkhandler looks like this:

    #!/bin/bash

    case "$1" in
        *mkv|*webm|*mp4|*mp3|*flac|*opus|*mp3?source*|*youtube.com/watch*|*youtube.com/playlist*|*youtu.be*)
            youtube-dl -o "~/Downloads/%(title)s.%(ext)s" "$1" ;;
        *png|*jpg|*jpeg|*gif|*svg)
            wget -P ~/Downloads/ "$1"
            open -a preview "Downloads/${1##*/}" ;;
        *pdf)
            wget -P ~/Downloads/ "$1"
            open -a skim "Downloads/${1##*/}" ;;
        *)
            open -a qutebrowser $1 ;;
    esac

It takes the URL as its first and only argument, provided by urlview
then depending on the name of the URL it performs different actions
using a case statement. If the URL ends in common video or audio
extensions (*mkv, *webm ...) it uses youtube-dl to download the file
in the URL. If it is an image it wgets it and then opens it in
Preview.app, and if it’s a .pdf it does the same but opens it in
skim. Finally, if none of the above tests were true, it simply opens
the link in my web browser, qutebrowser.

To use urlview in newsboat I can set some options in
~/.config/newsboat/config:

    external-url-viewer "urlview"
    bind-key U show-urls

This allows me to press U in the article view of newsboat to view
the URLs and use linkhandler to determine how they are opened.

The nice thing about this setup with urlview is I can replicate it
across many programs. In vim I can put this in my ~/.vimrc to use
urlview by pressing <Leader>u:

    nnoremap <Leader>u :w<Home>silent <End> !urlview<CR>

I can also use it in Mutt by adding this to my muttrc:

    macro index,pager U "<enter-command>set pipe_decode = yes<enter><pipe-message>urlview<enter><enter-command>set pipe_decode = no<enter>""view URLs"

and there is a [tmux plugin] as well! Though I haven’t looked at
that properly yet.

  [tmux plugin]: https://github.com/tmux-plugins/tmux-urlview