I recently got the question- "What is the use case for elfeed?". When I get a chance to talk about my favorite software I will NEVER pass up that opportunity.

Elfeed is a RSS feed reader for Emacs that I use daily and it solves a lot of problems for me. To understand how this works let's start by looking at a snippet of my feeds config. Elfeed feeds is just a list of lists where each feed is represented by (url tag1 tag2 tagN) . This combination is the start of a lot of very powerful workflows.

(setq elfeed-feeds
      '(("http://asert.arbornetworks.com/feed/" security second)
        ("http://feeds.feedburner.com/feedburner/Talos?format=xml" security second)
        ("http://feeds.trendmicro.com/Anti-MalwareBlog/" security second)
        ("http://researchcenter.paloaltonetworks.com/unit42/feed/" security second)
        ("https://www.proofpoint.com/rss.xml" security second)
        ("https://www.bellingcat.com/feed/" security second)
        ("https://nomasters.io/index.xml" blog tech)
        ("http://www.reddit.com/r/ReverseEngineering/.rss" security second reddit)
        ("https://www.reddit.com/r/listentothis/.rss" music reddit)
        ("https://www.youtube.com/feeds/videos.xml?channel_id=UCWZ3HFiJkxG1K8C4HVnyBvQ" youtube) ;; Vic Berger
        ("https://www.youtube.com/feeds/videos.xml?channel_id=UC--DwaiMV-jtO-6EvmKOnqg" youtube) ;; OA Labs
        ("https://www.youtube.com/feeds/videos.xml?channel_id=UCbpMy0Fg74eXXkvxJrtEn3w" youtube) ;; Bon Apetit
        ("https://www.youtube.com/feeds/videos.xml?channel_id=UC5fdssPqmmGhkhsJi4VcckA" youtube) ;; Innuendo Studios
        ("https://usesthis.com/feed.atom")
        ("https://greenbay.craigslist.org/search/sss?format=rss&query=accordion&sort=rel" hunt)
        ("http://rss.acast.com/nature" podcast) ;; Nature
        ("http://feeds.feedburner.com/birdnote/OYfP" podcast) ;; Bird Note
        ("https://www.kcrw.com/culture/shows/nocturne/rss.xml" podcast) ;; Nocturne
        ("http://feeds.wnyc.org/onthemedia" podcast) ;; On The Media
        ("https://www.npr.org/rss/podcast.php?id=510289" podcast) ;; Planet Money
        ("http://rss.nytimes.com/services/xml/rss/nyt/HomePage.xml" news first)
        ("https://www.ftc.gov/feeds/press-release-consumer-protection.xml" gov first ftc)
        ("https://api2.fcc.gov/edocs/public/api/v1/rss/" gov first fcc)
        ("https://api2.fcc.gov/edocs/public/api/v1/rss/docTypes/Cit" gov first fcc)
        ("http://licensing.fcc.gov/myibfs/yesterdaysFilingsFeed.do" gov first fcc)
        ("http://licensing.fcc.gov/myibfs/yesterdaysActionsFeed.do" gov first fcc)
))

This is only a small snippet of all the feeds I subscribe to. RSS is used to make sure that you can stay on top of all of your feeds but also importantly for me it's a way to efficiently manage all of the 100+ feeds I subscribe to. So let's dive in to a couple of the use cases!

Tagging for level of attention required

There's a few tags I use to help me orient the stories I'm looking at to see which I want to read. first, second, and local.

  • First is the tag I use for anything that I'm not REALLY interested in but like to fetch for potential search later. For this tag I will briefly skim the list and mark the whole thing as read.
  • Second is the tag I use for security related news. These are the feeds I'm reading for work and filtering on that allows me to reorient how I look at the stories. I can quickly mark things as read if they do not pertain to any topics I'm currently tasked on or strike my interest.
  • Local is my tag for local headlines. Filtering on this allows me to read headlines within the context of my local community. Headlines that may not jump out in a global feed may suddenly be more interesting when they're happening down the street.

Focusing my attention based on the stories displayed is made possible by all sorts of tagging and sorting that you can do within elfeed.

  • +/- before a search term to add or remove a tag
  • = before a search term to filter by name of source
  • You can start typing to search the title or any of the body of the feed
  • @ operator to specify a time range

/images/attention.gif

NoSurf

I also use elfeed to aid my NoSurf efforts. Two of my three biggest time wasters are Reddit and Youtube. Both of these services have RSS feeds to subscribe to channels and subreddits.

/images/nosurf.gif

Music

After a friend showed me the subreddit ListenToThis I've found it a pretty valuable resource for finding new music. I can add the tags +music removing the +unread tag and just searching for genres I'm feeling at the moment. It's made even better by extending elfeed just a little:

(require 'elfeed)

(defun yt-dl-it (url)
  "Downloads the URL in an async shell"
  (let ((default-directory "~/Videos"))
    (async-shell-command (format "youtube-dl %s" url))))

(defun elfeed-youtube-dl (&optional use-generic-p)
  "Youtube-DL link"
  (interactive "P")
  (let ((entries (elfeed-search-selected)))
    (cl-loop for entry in entries
             do (elfeed-untag entry 'unread)
             when (elfeed-entry-link entry)
             do (yt-dl-it it))
    (mapc #'elfeed-search-update-entry entries)
    (unless (use-region-p) (forward-line))))

(define-key elfeed-search-mode-map (kbd "d") 'elfeed-youtube-dl)

This allows me to download the feed item at point by pressing d. I also do this for Youtubes in my feed since I've been burned by having my favorite videos removed in the past.

/images/newmusic.gif

Podcasts

On the go I normally just use the Apple podcasts app to listen to my podcasts on my phone but when I'm at my desk it's nice to be able to use elfeed to just grab the newest podcast.

/images/podcast.gif

Multiple Browsers

I've extended elfeed in a couple of ways to make reading of feeds easier. Sometimes I want to read feeds in my default browser but often I would just rather read them in w3m. This often gets around ad blockers and stops a lot of privacy invading javascript. I can also then use Spray to effectively read a lot of news articles.

Here's what I've added to my config for alternate browsers:

(defun elfeed-eww-open (&optional use-generic-p)
  "open with eww"
  (interactive "P")
  (let ((entries (elfeed-search-selected)))
    (cl-loop for entry in entries
             do (elfeed-untag entry 'unread)
             when (elfeed-entry-link entry)
             do (eww-browse-url it))
    (mapc #'elfeed-search-update-entry entries)
    (unless (use-region-p) (forward-line))))

(defun elfeed-firefox-open (&optional use-generic-p)
  "open with firefox"
  (interactive "P")
  (let ((entries (elfeed-search-selected)))
    (cl-loop for entry in entries
             do (elfeed-untag entry 'unread)
             when (elfeed-entry-link entry)
             do (browse-url-firefox it))
    (mapc #'elfeed-search-update-entry entries)
    (unless (use-region-p) (forward-line))))

(defun elfeed-w3m-open (&optional use-generic-p)
  "open with w3m"
  (interactive "P")
  (let ((entries (elfeed-search-selected)))
    (cl-loop for entry in entries
             do (elfeed-untag entry 'unread)
             when (elfeed-entry-link entry)
             do (ffap-w3m-other-window it))
    (mapc #'elfeed-search-update-entry entries)
    (unless (use-region-p) (forward-line))))

(define-key elfeed-search-mode-map (kbd "t") 'elfeed-w3m-open)
(define-key elfeed-search-mode-map (kbd "w") 'elfeed-eww-open)
(define-key elfeed-search-mode-map (kbd "f") 'elfeed-firefox-open)

/images/w3m.gif

Note to Self

Sometimes when I see a story it's not one I want to read now but I know it's one I want to check out later I'll often email the link to myself so I can check it out when I'm on the bus, laying in bed, or some other time I have a spare couple of minutes.

(defun todo (text &optional body)
  (interactive "sTodo: ")
  (compose-mail-other-window "mailroom@legitimate.company" text)
  (mail-text)
  (if body
      (insert body))
  (message-send-and-exit))

(defun elfeed-mail-todo (&optional use-generic-p)
  "Mail this to myself for later reading"
  (interactive "P")
  (let ((entries (elfeed-search-selected)))
    (cl-loop for entry in entries
             do (elfeed-untag entry 'unread)
             when (elfeed-entry-title entry)
             do (todo it (elfeed-entry-link entry)))
    (mapc #'elfeed-search-update-entry entries)
    (unless (use-region-p) (forward-line))))

(define-key elfeed-search-mode-map (kbd "m") 'elfeed-mail-todo)

Hunting

I also use Elfeed to keep up on some things I'm searching for. This includes VirusTotal hunting hits, Craigslist search terms in my area, and Google custom search terms.

/images/hunt.gif

I hope this inspired you to give elfeed a shot. I haven't been this happy with an RSS reader since Google Reader 🪦