• Stars
    star
    1,371
  • Rank 34,304 (Top 0.7 %)
  • Language
    Emacs Lisp
  • License
    The Unlicense
  • Created about 11 years ago
  • Updated over 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

An Emacs web feeds client

Elfeed Emacs Web Feed Reader

Elfeed is an extensible web feed reader for Emacs, supporting both Atom and RSS. It requires Emacs 24.3 and is available for download from MELPA or el-get. Elfeed was inspired by notmuch.

For a longer overview,

The database format is stable and is never expected to change.

Prerequisites

It is strongly recommended you have cURL installed, either in your PATH or configured via elfeed-curl-program-name. Elfeed will prefer it to Emacs' own URL-fetching mechanism, url-retrieve. It's also essential for running Elfeed on Windows, where url-retrieve is broken. Updates using cURL are significantly faster than the built-in method, both for you and the feed hosts.

If this is giving you problems, fetching with cURL can be disabled by setting elfeed-use-curl to nil.

Extensions

These projects extend Elfeed with additional features:

Getting Started

Elfeed is broken into a multiple source files, so if you manually install it you will need to add the Elfeed package directory to your load-path. If installed via package.el or el-get, this will be done automatically.

It is recommended that you make a global binding for elfeed.

(global-set-key (kbd "C-x w") 'elfeed)

Running the interactive function elfeed will pop up the *elfeed-search* buffer, which will display feed items.

  • g: refresh view of the feed listing
  • G: fetch feed updates from the servers
  • s: update the search filter (see tags)
  • c: clear the search filter

This buffer will be empty until you add your feeds to the elfeed-feeds list and initiate an update with M-x elfeed-update (or G in the Elfeed buffer). This will populate the Elfeed database with entries.

;; Somewhere in your .emacs file
(setq elfeed-feeds
      '("http://nullprogram.com/feed/"
        "https://planet.emacslife.com/atom.xml"))

Another option for providing a feed list is with an OPML file. Running M-x elfeed-load-opml will fill elfeed-feeds with feeds listed in an OPML file. When elfeed-load-opml is called interactively, it will automatically save the feedlist to your customization file, so you will only need to do this once.

If there are a lot of feeds, the initial update will take noticeably longer than normal operation because of the large amount of information being written the database. Future updates will only need to write new or changed data. If updating feeds slows down Emacs too much for you, reduce the number of concurrent fetches via elfeed-set-max-connections.

If you're getting many "Queue timeout exceeded" errors, increase the fetch timeout via elfeed-set-timeout.

(setf url-queue-timeout 30)

From the search buffer there are a number of ways to interact with entries. Entries are selected by placing the point over an entry. Multiple entries are selected at once by using an active region.

  • RET: view selected entry in a buffer
  • b: open selected entries in your browser (browse-url)
  • y: copy selected entries URL to the clipboard
  • r: mark selected entries as read
  • u: mark selected entries as unread
  • +: add a specific tag to selected entries
  • -: remove a specific tag from selected entries

Tags

Elfeed maintains a list of arbitrary tags -- symbols attached to an entry. The tag unread is treated specially by default, with unread entries appearing in bold.

Autotagging

Tags can automatically be applied to entries discovered in specific feeds through extra syntax in elfeed-feeds. Normally this is a list of strings, but an item can also be a list, providing set of "autotags" for a feed's entries.

(setq elfeed-feeds
      '(("http://nullprogram.com/feed/" blog emacs)
        "http://www.50ply.com/atom.xml"  ; no autotagging
        ("http://nedroid.com/feed/" webcomic)))

Filter Syntax

To make tags useful, the Elfeed entry listing buffer can be filtered by tags. Use elfeed-search-set-filter (or s) to update the filter. Use elfeed-search-clear-filter to restore the default.

Any component of the search string beginning with a + or a - is treated like a tag. + means the tag is required, - means the tag must not be present.

A component beginning with a @ indicates an age or a date range. An age is a relative time expression or an absolute date expression. Entries older than this age are filtered out. The age description accepts plain English, but cannot have spaces, so use dashes. For example, "@2-years-old", "@3-days-ago" or "@2019-06-24". A date range are two ages seperated by a --, e.g. "@2019-06-20--2019-06-24" or "@5-days-ago--1-day-ago". The entry must be newer than the first expression but older than the second. The database is date-oriented, so filters that include an age restriction are significantly more efficient.

A component beginning with a ! is treated as an "inverse" regular expression. This means that any entry matching this regular expression will be filtered out. The regular expression begins after the ! character. You can read this as "entry not matching foo".

A component beginning with a # limits the total number of entries displayed to the number immediately following the symbol. For example, to limit the display to 20 entries: #20.

A component beginning with a = is a regular expression matching the entry's feed (title or URL). Only entries belonging to a feed that matches at least one of the = expressions will be shown.

A component beginning with a ~ is a regular expression matching the entry's feed (title or URL). Only entries belonging to a feed that matches none of the ~ expressions will be shown.

All other components are treated as a regular expression, and only entries matching it (title or URL) will be shown.

Here are some example filters.

  • @6-months-ago +unread

Only show unread entries of the last six months. This is the default filter.

  • linu[xs] @1-year-old

Only show entries about Linux or Linus from the last year.

  • -unread +youtube #10

Only show the most recent 10 previously-read entries tagged as youtube.

  • +unread !x?emacs

Only show unread entries not having emacs or xemacs in the title or link.

  • +emacs =http://example.org/feed/

Only show entries tagged as emacs from a specific feed.

Default Search Filter

You can set your default search filter by changing the default value of elfeed-search-filter. It only changes buffer-locally when you're adjusting the filter within Elfeed. For example, some users prefer to have a space on the end for easier quick searching.

(setq-default elfeed-search-filter "@1-week-ago +unread ")

Tag Hooks

The last example assumes you've tagged posts with youtube. You probably want to do this sort of thing automatically, either through the "autotags" feature mentioned above, or with the elfeed-new-entry-hook. Functions in this hook are called with new entries, allowing them to be manipulated, such as adding tags.

;; Mark all YouTube entries
(add-hook 'elfeed-new-entry-hook
          (elfeed-make-tagger :feed-url "youtube\\.com"
                              :add '(video youtube)))

Avoiding tagging old entries as unread:

;; Entries older than 2 weeks are marked as read
(add-hook 'elfeed-new-entry-hook
          (elfeed-make-tagger :before "2 weeks ago"
                              :remove 'unread))

Or building your own subset feeds:

(add-hook 'elfeed-new-entry-hook
          (elfeed-make-tagger :feed-url "example\\.com"
                              :entry-title '(not "something interesting")
                              :add 'junk
                              :remove 'unread))

Use M-x elfeed-apply-hooks-now to apply elfeed-new-entry-hook to all existing entries. Otherwise hooks will only apply to new entries on discovery.

Custom Tag Faces

By default, entries marked unread will have bolded titles in the *elfeed-search* listing. You can customize how tags affect an entry's appearance by customizing elfeed-search-face-alist. For example, this configuration makes entries tagged important stand out in red.

(defface important-elfeed-entry
  '((t :foreground "#f77"))
  "Marks an important Elfeed entry.")

(push '(important important-elfeed-entry)
      elfeed-search-face-alist)

All faces from all tags will be applied to the entry title. The faces will be ordered as they appear in elfeed-search-face-alist.

Bookmarks

Filters can be saved and restored using Emacs' built-in bookmarks feature. While in the search buffer, use M-x bookmark-set to save the current filter, and M-x bookmark-jump to restore a saved filter. Emacs automatically persists bookmarks across sessions.

Metadata Plist

All feed and entry objects have plist where you can store your own arbitrary, readable values. These values are automatically persisted in the database. This metadata is accessed using the polymorphic elfeed-meta function. It's setf-able.

(setf (elfeed-meta entry :rating) 4)
(elfeed-meta entry :rating)
;; => 4

(setf (elfeed-meta feed :title) "My Better Title")

Elfeed itself adds some entries to this plist, some for your use, some for its own use. Here are the properties that Elfeed uses:

  • :authors : A list of author plists (:name, :uri, :email).
  • :canonical-url : The final URL for the feed after all redirects.
  • :categories : The feed-supplied categories for this entry.
  • :etag : HTTP Etag header, for conditional GETs.
  • :failures : Number of times this feed has failed to update.
  • :last-modified : HTTP Last-Modified header, for conditional GETs.
  • :title : Overrides the feed-supplied title for display purposes, both for feeds and entries. See also elfeed-search-set-feed-title and elfeed-search-set-entry-title.

This list will grow in time, so you might consider namespacing your own properties to avoid collisions (e.g. :xyz/rating), or simply not using keywords as keys. Elfeed will always use keywords without a slash.

Hooks

A number of hooks are available to customize the behavior of Elfeed at key points without resorting to advice.

  • elfeed-new-entry-hook : Called each time a new entry it added to the database, allowing for automating tagging and such.
  • elfeed-new-entry-parse-hook : Called with each new entry and the full XML structure from which it was parsed, allowing for additional information to be drawn from the original feed XML.
  • elfeed-http-error-hooks : Allows for special behavior when HTTP errors occur, beyond simply logging the error to *elfeed-log* .
  • elfeed-parse-error-hooks : Allows for special behavior when feed parsing fails, beyond logging.
  • elfeed-db-update-hook : Called any time the database has had a major modification.

Viewing Entries

Entries are viewed locally in Emacs by typing RET while over an entry in the search listing. The content will be displayed in a separate buffer using elfeed-show-mode, rendered using Emacs' built-in shr package. This requires an Emacs compiled with libxml2 bindings, which provides the necessary HTML parser.

Sometimes displaying images can slow down or even crash Emacs. Set shr-inhibit-images to disable images if this is a problem.

Web Interface

Elfeed includes a demonstration/toy web interface for remote network access. It's a single-page web application that follows the database live as new entries arrive. It's packaged separately as elfeed-web. To fire it up, run M-x elfeed-web-start and visit http://localhost:8080/elfeed/ (check your httpd-port) with a browser. See the elfeed-web.el header for endpoint documentation if you'd like to access the Elfeed database through the web API.

It's rough and unfinished -- no keyboard shortcuts, read-only, no authentication, and a narrow entry viewer. This is basically Elfeed's "mobile" interface. Patches welcome.

Platform Support

Summary: Install cURL and most problems disappear for all platforms.

I personally only use Elfeed on Linux, but it's occasionally tested on Windows. Unfortunately the Windows port of Emacs is a bit too unstable for parallel feed downloads with url-retrieve, not to mention the tiny, hard-coded, 512 open descriptor limitation, so it limits itself to one feed at a time on this platform.

If you fetch HTTPS feeds without cURL on any platform, it's essential that Emacs is built with the --with-gnutls option. Otherwise Emacs runs gnutls in an inferior process, which rarely works well.

Database Management

The database should keep itself under control without any manual intervention, but steps can be taken to minimize the database size if desired. The simplest option is to run the elfeed-db-compact command, which will pack the loose-file content database into a single compressed file. This function works well in kill-emacs-hook.

Going further, a function could be added to elfeed-new-entry-hook to strip unwanted/unneeded content from select entries before being stored in the database. For example, for YouTube videos only the entry link is of interest and the regularly-changing entry content could be tossed to save time and storage.

Status and Roadmap

Elfeed is to the point where it can serve 100% of my own web feed needs. My personal selection of about 150 feeds has been acting as my test case as I optimize and add features.

Some things I still might want to add:

  • Database synchronization between computers
  • Parallel feed fetching via separate Emacs subprocesses

Motivation

As far as I know, outside of Elfeed there does not exist an extensible, text-file configured, power-user web feed client that can handle a reasonable number of feeds. The existing clients I've tried are missing some important capability that limits its usefulness to me.

More Repositories

1

endlessh

SSH tarpit that slowly sends an endless banner
C
7,113
star
2

w64devkit

Portable C and C++ Development Kit for x64 (and x86) Windows
C
2,871
star
3

skewer-mode

Live web development in Emacs
Emacs Lisp
1,066
star
4

hash-prospector

Automated integer hash function discovery
C
672
star
5

enchive

Encrypted personal archives
C
630
star
6

branchless-utf8

Branchless UTF-8 decoder
C
589
star
7

scratch

Personal scratch code
C
366
star
8

pixelcity

Shamus Young's procedural city project
C++
359
star
9

optparse

Portable, reentrant, getopt-like option parser
C
326
star
10

pdjson

C JSON parser library that doesn't suck
C
279
star
11

interactive-c-demo

Demonstration of interactive C programming
C
249
star
12

emacs-aio

async/await for Emacs Lisp
Emacs Lisp
215
star
13

webgl-particles

WebGL particle system demo
JavaScript
203
star
14

fantasyname

Fantasy name generator
C
180
star
15

lstack

C11 Lock-free Stack
C
172
star
16

resurrect-js

JavaScript serialization that preserves behavior and reference circularity.
JavaScript
169
star
17

passphrase2pgp

Generate a PGP key from a passphrase
Go
168
star
18

pure-linux-threads-demo

Pthreads-free Linux threading demo
Assembly
147
star
19

ptrace-examples

Examples for Linux ptrace(2)
C
134
star
20

memdig

Memory cheat tool for Windows and Linux games
C
131
star
21

dosdefender-ld31

DOS Defender (Ludum Dare #31)
C
130
star
22

dotfiles

My personal dotfiles
Shell
124
star
23

Prelude-of-the-Chambered

Notch's Prelude of the Chambered 48-hour game
Java
124
star
24

sort-circle

Colorful sorting animations
C
124
star
25

.emacs.d

My personal .emacs.d
Emacs Lisp
119
star
26

growable-buf

Growable Memory Buffer for C99
C
116
star
27

youtube-dl-emacs

Emacs youtube-dl download manager
Emacs Lisp
104
star
28

getopt

POSIX getopt() as a portable header library
C
102
star
29

trie

C99 trie library
C
98
star
30

opengl-demo

Minimal OpenGL 3.3 core profile demo
C
97
star
31

Minicraft

Notch's Ludum Dare 22 entry.
Java
95
star
32

igloojs

Low-level, fluent, OOP WebGL wrapper
JavaScript
89
star
33

hastyhex

A blazing fast hex dumper
C
88
star
34

webgl-game-of-life

WebGL Game of Life
JavaScript
88
star
35

u-config

a smaller, simpler, portable pkg-config clone
C
84
star
36

bmp

24-bit BMP (Bitmap) ANSI C header library
C
84
star
37

elisp-ffi

Emacs Lisp Foreign Function Interface
C++
83
star
38

rng-js

JavaScript seedable random number generation tools.
JavaScript
82
star
39

mandel-simd

Mandelbrot set in SIMD (SSE, AVX)
C
81
star
40

sample-java-project

Example Ant-based Java project
Java
78
star
41

nasm-mode

Major mode for editing NASM assembly programs
Emacs Lisp
78
star
42

vulkan-test

Test if your system supports Vulkan
C
77
star
43

gap-buffer-animator

Gap buffer animation creator
C
72
star
44

at-el

Prototype-based Emacs Lisp object system
Emacs Lisp
71
star
45

skeeto.github.com

Personal website/blog
HTML
64
star
46

ulid-c

ULID Library for C
C
62
star
47

xf8

8-bit Xor Filter in C99
C
61
star
48

race64

World's fastest Base64 encoder / decoder
C
58
star
49

devdocs-lookup

Quick Emacs API lookup on devdocs.io
Emacs Lisp
58
star
50

webgl-path-solver

WebGL shortest path solver
JavaScript
57
star
51

x86-lookup

Quickly jump to x86 documentation from Emacs
Emacs Lisp
57
star
52

javadoc-lookup

Quickly lookup Javadoc pages from Emacs
Emacs Lisp
55
star
53

am-i-shadowbanned

Online reddit shadowban test
JavaScript
53
star
54

fun-liquid

Physics engine liquid in Java.
Java
53
star
55

minimail

Embeddable POP3 + SMTP server.
C
50
star
56

emacs-memoize

Elisp memoization functions
Emacs Lisp
48
star
57

webgl-fire

WebGL fire effect
JavaScript
47
star
58

simplegpg

Simplified, signify-like interface to GnuPG signatures
Shell
47
star
59

autotetris-mode

Automatically play Emacs Tetris
Emacs Lisp
45
star
60

fiber-await

Win32 Fiber async/await demo
C
45
star
61

lorenz-webgl

Lorenz System WebGL
JavaScript
42
star
62

asteroids-demo

Asteroids Clone for Windows
C
40
star
63

elisp-json-rpc

JSON-RPC library for Emacs Lisp
Emacs Lisp
39
star
64

hashtab

Simple C hash table
C
37
star
65

pgp-poisoner

PGP key poisoner
Go
36
star
66

bf-x86

x86_64 brainfuck compiler
C
36
star
67

wisp

Wisp, a lisp programming language
C
33
star
68

binitools

Bini file translator for the game Freelancer
C
32
star
69

double-pendulum

JavaScript double pendulum simulation with RK4 integration
JavaScript
30
star
70

predd

Multimethods for Emacs Lisp
Emacs Lisp
29
star
71

atomkv

In-memory, JSON, key-value service with compare-and-swap updates and event streams
Go
29
star
72

purgeable

Purgeable memory allocations for Linux
C
28
star
73

lqueue

C11 + Pthreads Atomic Bounded Work Queue
C
28
star
74

uuid

UUID generator for Go
Go
27
star
75

goblin-com

Goblin-COM roguelike game for 7DRL 2015
C
27
star
76

jekyll-deck

Template for Jekyll / deck.js presentations
27
star
77

rlhk

Roguelike Header Kit
C
26
star
78

voronoi-toy

WebGL interactive Voronoi diagram
JavaScript
26
star
79

transcription-mode

Emacs mode for editing transcripts.
Emacs Lisp
25
star
80

october-chess-engine

Java Chess Engine
Java
25
star
81

boids-js

HTML5 boids (skewer-mode demo)
JavaScript
25
star
82

optparse-go

GNU style long options for Go
Go
24
star
83

geohash

Fast, lean, efficient geohash C library
C
24
star
84

bitpack

Emacs Lisp structure packing
Emacs Lisp
23
star
85

lean-static-gpg

Lean, static GnuPG build for Linux
Shell
23
star
86

connect4

Connect Four AI and Engine
C
22
star
87

blowpipe

Authenticated Blowfish-encrypted pipe
C
22
star
88

markov-text

Markov chain text generation in Emacs Lisp
Emacs Lisp
22
star
89

joymacs

Joystick support for Emacs
C
21
star
90

emacs-rsa

RSA cryptography in Emacs Lisp
Emacs Lisp
21
star
91

live-dev-env

A live CD of my personal development environment
Shell
20
star
92

dynamic-function-benchmark

Benchmark for three different kinds of dynamic function calls
C
20
star
93

utf-7

UTF-7 encoder and decoder in ANSI C
C
19
star
94

elisp-fakespace

Emacs Lisp namespaces (defpackage)
Emacs Lisp
18
star
95

siphash

Incremental SipHash in C
C
18
star
96

bencode-c

Bencode decoder in ANSI C
C
17
star
97

british-square

British Square Engine (Analysis and Perfect AI Player)
C
17
star
98

pokerware

Pokerware Secure Passphrase Generation
Makefile
17
star
99

xxtea

100% XXTEA authenticated, chunked file encryption
C
17
star
100

gnupg-windows-build

Cross-compile GnuPG for Windows using Docker
Dockerfile
17
star