README.md (16443B)
1 # Elfeed Emacs Web Feed Reader 2 3 Elfeed is an extensible web feed reader for Emacs, supporting both 4 Atom and RSS. It requires Emacs 24.3 and is available for download 5 from [MELPA](http://melpa.milkbox.net/) or 6 [el-get](https://github.com/dimitri/el-get). Elfeed was inspired by 7 [notmuch](http://notmuchmail.org/). 8 9 For a longer overview, 10 11 * [Introducing Elfeed, an Emacs Web Feed Reader](http://nullprogram.com/blog/2013/09/04/). 12 * [Tips and Tricks](http://nullprogram.com/blog/2013/11/26/) 13 * [Read your RSS feeds in Emacs with Elfeed 14 ](http://pragmaticemacs.com/emacs/read-your-rss-feeds-in-emacs-with-elfeed/) 15 * [Scoring Elfeed articles](http://kitchingroup.cheme.cmu.edu/blog/2017/01/05/Scoring-elfeed-articles/) 16 * [Using Emacs 29](https://www.youtube.com/watch?v=pOFqzK1Ymr4), 17 [30](https://www.youtube.com/watch?v=tjnK1rkO7RU), 18 [31](https://www.youtube.com/watch?v=5zuSUbAHH8c) 19 * [Take Elfeed everywhere: Mobile rss reading Emacs-style (for free/cheap)](http://babbagefiles.blogspot.com/2017/03/take-elfeed-everywhere-mobile-rss.html) 20 * [Elfeed Rules!](https://noonker.github.io/posts/2020-04-22-elfeed/) ([reddit](https://old.reddit.com/r/emacs/comments/g6oowz/elfeed_rules/)) 21 * [Elfeed with Tiny Tiny RSS](https://codingquark.com/emacs/2020/04/19/elfeed-protocol-ttrss.html) ([hn](https://news.ycombinator.com/item?id=22915200)) 22 * [Open Emacs elfeed links in the background](http://xenodium.com/open-emacs-elfeed-links-in-background/) 23 * [Using Emacs 72](https://cestlaz.github.io/post/using-emacs-72-customizing-elfeed/) 24 * [Lazy Elfeed](https://karthinks.com/blog/lazy-elfeed/) 25 * [Using Elfeed to View Videos](https://joshrollinswrites.com/help-desk-head-desk/20200611/) 26 * [Manage podcasts in Emacs with Elfeed and Bongo](https://protesilaos.com/codelog/2020-09-11-emacs-elfeed-bongo/) 27 * [... more ...](http://nullprogram.com/tags/elfeed/) 28 * [... and more ...](http://pragmaticemacs.com/category/elfeed/) 29 30 [![](http://i.imgur.com/kxgF5AH.png)](http://i.imgur.com/kxgF5AH.png) 31 32 The database format is stable and is never expected to change. 33 34 ## Prerequisites 35 36 **It is *strongly* recommended you have cURL installed**, either in 37 your PATH or configured via `elfeed-curl-program-name`. Elfeed will 38 prefer it to Emacs' own URL-fetching mechanism, `url-retrieve`. It's 39 also essential for running Elfeed on Windows, where `url-retrieve` is 40 broken. Updates using cURL are significantly faster than the built-in 41 method, both for you and the feed hosts. 42 43 If this is giving you problems, fetching with cURL can be disabled by 44 setting `elfeed-use-curl` to nil. 45 46 ## Extensions 47 48 These projects extend Elfeed with additional features: 49 50 * [elfeed-org](https://github.com/remyhonig/elfeed-org) 51 * [elfeed-goodies](https://github.com/algernon/elfeed-goodies) 52 * [elfeed-protocol](https://github.com/fasheng/elfeed-protocol) 53 * [elfeed-score](https://github.com/sp1ff/elfeed-score) 54 * [Elfeed Android interface](https://github.com/areina/elfeed-cljsrn) 55 ([Google Play](https://play.google.com/store/apps/details?id=com.elfeedcljsrn)) 56 * [elfeed-dashboard](https://github.com/Manoj321/elfeed-dashboard) 57 58 ## Getting Started 59 60 Elfeed is broken into a multiple source files, so if you manually 61 install it you will need to add the Elfeed package directory to your 62 `load-path`. If installed via package.el or el-get, this will be done 63 automatically. 64 65 It is recommended that you make a global binding for `elfeed`. 66 67 ```el 68 (global-set-key (kbd "C-x w") 'elfeed) 69 ``` 70 71 Running the interactive function `elfeed` will pop up the 72 `*elfeed-search*` buffer, which will display feed items. 73 74 * <kbd>g</kbd>: refresh view of the feed listing 75 * <kbd>G</kbd>: fetch feed updates from the servers 76 * <kbd>s</kbd>: update the search filter (see tags) 77 * <kbd>c</kbd>: clear the search filter 78 79 This buffer will be empty until you add your feeds to the 80 `elfeed-feeds` list and initiate an update with `M-x elfeed-update` 81 (or <kbd>G</kbd> in the Elfeed buffer). This will populate the Elfeed 82 database with entries. 83 84 ```el 85 ;; Somewhere in your .emacs file 86 (setq elfeed-feeds 87 '("http://nullprogram.com/feed/" 88 "http://planet.emacsen.org/atom.xml")) 89 ``` 90 91 Another option for providing a feed list is with an OPML file. Running 92 `M-x elfeed-load-opml` will fill `elfeed-feeds` with feeds listed in 93 an OPML file. When `elfeed-load-opml` is called interactively, it will 94 automatically save the feedlist to your customization file, so you 95 will only need to do this once. 96 97 If there are a lot of feeds, the initial update will take noticeably 98 longer than normal operation because of the large amount of 99 information being written the database. Future updates will only need 100 to write new or changed data. If updating feeds slows down Emacs too 101 much for you, reduce the number of concurrent fetches via 102 `elfeed-set-max-connections`. 103 104 If you're getting many "Queue timeout exceeded" errors, increase the 105 fetch timeout via `elfeed-set-timeout`. 106 107 ~~~el 108 (setf url-queue-timeout 30) 109 ~~~ 110 111 From the search buffer there are a number of ways to interact with 112 entries. Entries are selected by placing the point over an entry. 113 Multiple entries are selected at once by using an active region. 114 115 * <kbd>RET</kbd>: view selected entry in a buffer 116 * <kbd>b</kbd>: open selected entries in your browser (`browse-url`) 117 * <kbd>y</kbd>: copy selected entries URL to the clipboard 118 * <kbd>r</kbd>: mark selected entries as read 119 * <kbd>u</kbd>: mark selected entries as unread 120 * <kbd>+</kbd>: add a specific tag to selected entries 121 * <kbd>-</kbd>: remove a specific tag from selected entries 122 123 ## Tags 124 125 Elfeed maintains a list of arbitrary tags -- symbols attached to an 126 entry. The tag `unread` is treated specially by default, with unread 127 entries appearing in bold. 128 129 ### Autotagging 130 131 Tags can automatically be applied to entries discovered in specific 132 feeds through extra syntax in `elfeed-feeds`. Normally this is a list 133 of strings, but an item can also be a list, providing set of 134 "autotags" for a feed's entries. 135 136 ```el 137 (setq elfeed-feeds 138 '(("http://nullprogram.com/feed/" blog emacs) 139 "http://www.50ply.com/atom.xml" ; no autotagging 140 ("http://nedroid.com/feed/" webcomic))) 141 ``` 142 143 ### Filter Syntax 144 145 To make tags useful, the Elfeed entry listing buffer can be filtered 146 by tags. Use `elfeed-search-set-filter` (or <kbd>s</kbd>) to update 147 the filter. Use `elfeed-search-clear-filter` to restore the default. 148 149 Any component of the search string beginning with a `+` or 150 a `-` is treated like a tag. `+` means the tag is required, `-` means 151 the tag must not be present. 152 153 A component beginning with a `@` indicates an age or a date range. An 154 age is a relative time expression or an absolute date expression. 155 Entries older than this age are filtered out. The age description 156 accepts plain English, but cannot have spaces, so use dashes. For 157 example, `"@2-years-old"`, `"@3-days-ago"` or `"@2019-06-24"`. A date 158 range are two ages seperated by a `--`, e.g. 159 `"@2019-06-20--2019-06-24"` or `"@5-days-ago--1-day-ago"`. The entry 160 must be newer than the first expression but older than the second. The 161 database is date-oriented, so **filters that include an age 162 restriction are significantly more efficient.** 163 164 A component beginning with a `!` is treated as an "inverse" regular 165 expression. This means that any entry matching this regular expression 166 will be filtered out. The regular expression begins *after* the `!` 167 character. You can read this as "entry not matching `foo`". 168 169 A component beginning with a `#` limits the total number of entries 170 displayed to the number immediately following the symbol. For example, 171 to limit the display to 20 entries: `#20`. 172 173 A component beginning with a `=` is a regular expression matching the 174 entry's feed (title or URL). Only entries belonging to a feed that 175 matches at least one of the `=` expressions will be shown. 176 177 A component beginning with a `~` is a regular expression matching the 178 entry's feed (title or URL). Only entries belonging to a feed that 179 matches none of the `~` expressions will be shown. 180 181 All other components are treated as a regular expression, and only 182 entries matching it (title or URL) will be shown. 183 184 Here are some example filters. 185 186 * `@6-months-ago +unread` 187 188 Only show unread entries of the last six months. This is the default filter. 189 190 * `linu[xs] @1-year-old` 191 192 Only show entries about Linux or Linus from the last year. 193 194 * `-unread +youtube #10` 195 196 Only show the most recent 10 previously-read entries tagged as 197 `youtube`. 198 199 * `+unread !x?emacs` 200 201 Only show unread entries not having `emacs` or `xemacs` in the title 202 or link. 203 204 * `+emacs =http://example.org/feed/` 205 206 Only show entries tagged as `emacs` from a specific feed. 207 208 #### Default Search Filter 209 210 You can set your default search filter by changing the default value 211 of `elfeed-search-filter`. It only changes buffer-locally when you're 212 adjusting the filter within Elfeed. For example, some users prefer to 213 have a space on the end for easier quick searching. 214 215 (setq-default elfeed-search-filter "@1-week-ago +unread ") 216 217 ### Tag Hooks 218 219 The last example assumes you've tagged posts with `youtube`. You 220 probably want to do this sort of thing automatically, either through 221 the "autotags" feature mentioned above, or with the 222 `elfeed-new-entry-hook`. Functions in this hook are called with new 223 entries, allowing them to be manipulated, such as adding tags. 224 225 ```el 226 ;; Mark all YouTube entries 227 (add-hook 'elfeed-new-entry-hook 228 (elfeed-make-tagger :feed-url "youtube\\.com" 229 :add '(video youtube))) 230 ``` 231 232 Avoiding tagging old entries as `unread`: 233 234 ```el 235 ;; Entries older than 2 weeks are marked as read 236 (add-hook 'elfeed-new-entry-hook 237 (elfeed-make-tagger :before "2 weeks ago" 238 :remove 'unread)) 239 ``` 240 241 Or building your own subset feeds: 242 243 ```el 244 (add-hook 'elfeed-new-entry-hook 245 (elfeed-make-tagger :feed-url "example\\.com" 246 :entry-title '(not "something interesting") 247 :add 'junk 248 :remove 'unread)) 249 ``` 250 251 Use `M-x elfeed-apply-hooks-now` to apply `elfeed-new-entry-hook` to 252 all existing entries. Otherwise hooks will only apply to new entries 253 on discovery. 254 255 ### Custom Tag Faces 256 257 By default, entries marked `unread` will have bolded titles in the 258 `*elfeed-search*` listing. You can customize how tags affect an 259 entry's appearance by customizing `elfeed-search-face-alist`. For 260 example, this configuration makes entries tagged `important` stand out 261 in red. 262 263 ~~~el 264 (defface important-elfeed-entry 265 '((t :foreground "#f77")) 266 "Marks an important Elfeed entry.") 267 268 (push '(important important-elfeed-entry) 269 elfeed-search-face-alist) 270 ~~~ 271 272 All faces from all tags will be applied to the entry title. The faces 273 will be ordered as they appear in `elfeed-search-face-alist`. 274 275 ## Bookmarks 276 277 Filters can be saved and restored using Emacs' built-in [bookmarks 278 feature][bm]. While in the search buffer, use `M-x bookmark-set` to 279 save the current filter, and `M-x bookmark-jump` to restore a saved 280 filter. Emacs automatically persists bookmarks across sessions. 281 282 [bm]: https://www.gnu.org/software/emacs/manual/html_node/emacs/Bookmarks.html 283 284 ## Metadata Plist 285 286 All feed and entry objects have plist where you can store your own 287 arbitrary, [readable values][rd]. These values are automatically 288 persisted in the database. This metadata is accessed using the 289 polymorphic `elfeed-meta` function. It's setf-able. 290 291 ~~~el 292 (setf (elfeed-meta entry :rating) 4) 293 (elfeed-meta entry :rating) 294 ;; => 4 295 296 (setf (elfeed-meta feed :title) "My Better Title") 297 ~~~ 298 299 Elfeed itself adds some entries to this plist, some for your use, some 300 for its own use. Here are the properties that Elfeed uses: 301 302 * `:authors` : A list of author plists (`:name`, `:uri`, `:email`). 303 * `:canonical-url` : The final URL for the feed after all redirects. 304 * `:categories` : The feed-supplied categories for this entry. 305 * `:etag` : HTTP Etag header, for conditional GETs. 306 * `:failures` : Number of times this feed has failed to update. 307 * `:last-modified` : HTTP Last-Modified header, for conditional GETs. 308 * `:title` : Overrides the feed-supplied title for display purposes, 309 both for feeds and entries. See also `elfeed-search-set-feed-title` 310 and `elfeed-search-set-entry-title`. 311 312 This list will grow in time, so you might consider namespacing your 313 own properties to avoid collisions (e.g. `:xyz/rating`), or simply not 314 using keywords as keys. Elfeed will always use keywords without a 315 slash. 316 317 [rd]: http://nullprogram.com/blog/2013/12/30/ 318 319 ## Hooks 320 321 A number of hooks are available to customize the behavior of Elfeed at 322 key points without resorting to advice. 323 324 * `elfeed-new-entry-hook` : Called each time a new entry it added to 325 the database, allowing for automating tagging and such. 326 * `elfeed-new-entry-parse-hook` : Called with each new entry and the 327 full XML structure from which it was parsed, allowing for additional 328 information to be drawn from the original feed XML. 329 * `elfeed-http-error-hooks` : Allows for special behavior when HTTP 330 errors occur, beyond simply logging the error to `*elfeed-log*` . 331 * `elfeed-parse-error-hooks` : Allows for special behavior when feed 332 parsing fails, beyond logging. 333 * `elfeed-db-update-hook` : Called any time the database has had a 334 major modification. 335 336 ## Viewing Entries 337 338 Entries are viewed locally in Emacs by typing `RET` while over an 339 entry in the search listing. The content will be displayed in a 340 separate buffer using `elfeed-show-mode`, rendered using Emacs' 341 built-in shr package. This requires an Emacs compiled with `libxml2` 342 bindings, which provides the necessary HTML parser. 343 344 Sometimes displaying images can slow down or even crash Emacs. Set 345 `shr-inhibit-images` to disable images if this is a problem. 346 347 ## Web Interface 348 349 Elfeed includes a demonstration/toy web interface for remote network 350 access. It's a single-page web application that follows the database 351 live as new entries arrive. It's packaged separately as `elfeed-web`. 352 To fire it up, run `M-x elfeed-web-start` and visit 353 http://localhost:8080/elfeed/ (check your `httpd-port`) with a 354 browser. See the `elfeed-web.el` header for endpoint documentation if 355 you'd like to access the Elfeed database through the web API. 356 357 It's rough and unfinished -- no keyboard shortcuts, read-only, no 358 authentication, and a narrow entry viewer. This is basically Elfeed's 359 "mobile" interface. Patches welcome. 360 361 ## Platform Support 362 363 Summary: Install cURL and most problems disappear for all platforms. 364 365 I personally only use Elfeed on Linux, but it's occasionally tested on 366 Windows. Unfortunately the Windows port of Emacs is a bit too unstable 367 for parallel feed downloads with `url-retrieve`, not to mention the 368 [tiny, hard-coded, 512 open descriptor limitation][files], so it 369 limits itself to one feed at a time on this platform. 370 371 [files]: http://msdn.microsoft.com/en-us/library/kdfaxaay%28vs.71%29.aspx 372 373 If you fetch HTTPS feeds without cURL on *any* platform, it's 374 essential that Emacs is built with the `--with-gnutls` option. 375 Otherwise Emacs runs gnutls in an inferior process, which rarely works 376 well. 377 378 ## Database Management 379 380 The database should keep itself under control without any manual 381 intervention, but steps can be taken to minimize the database size if 382 desired. The simplest option is to run the `elfeed-db-compact` 383 command, which will pack the loose-file content database into a single 384 compressed file. This function works well in `kill-emacs-hook`. 385 386 Going further, a function could be added to `elfeed-new-entry-hook` to 387 strip unwanted/unneeded content from select entries before being 388 stored in the database. For example, for YouTube videos only the entry 389 link is of interest and the regularly-changing entry content could be 390 tossed to save time and storage. 391 392 ## Status and Roadmap 393 394 Elfeed is to the point where it can serve 100% of my own web feed 395 needs. My personal selection of about 150 feeds has been acting as my 396 test case as I optimize and add features. 397 398 Some things I still might want to add: 399 400 * Database synchronization between computers 401 * Parallel feed fetching via separate Emacs subprocesses 402 403 ## Motivation 404 405 As far as I know, outside of Elfeed there does not exist an 406 extensible, text-file configured, power-user web feed client that can 407 handle a reasonable number of feeds. The existing clients I've tried 408 are missing some important capability that limits its usefulness to 409 me.