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*|*y
outube.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